У меня на хост-компьютере, где развернута моя серверная служба, есть несколько файлов PDF, которые я хочу предоставлять публично. Требование состоит в том, чтобы сделать обновление файлов динамическим, чтобы клиент мог заменять устаревшие файлы новыми через модуль, который я для них создал. Конечно, я мог бы передавать файлы через конечную точку, но это менее эффективно, поскольку запросы маршрутизируются через весь стек приложения, что увеличивает затраты на обработку по сравнению с прямым обслуживанием статических файлов веб-сервером.
В папке application.properties я добавил следующее:
spring.web.resources.static-locations=file:/home/spidey/sopon3/rda-aof/
Это работает при доступе к my-devdomain.com/public-data.pdf, однако из-за безопасности Spring для доступа к нему требуется аутентификация. Я попробовал разрешить /rda-aof/** в своей конфигурации безопасности, но это не сработало, и я не могу просто разрешить /**, потому что это разрешит все конечные точки. Так каков обходной путь для этого? Кроме того, не стесняйтесь предлагать другие методы, если это не сработает.
Я добавляю код конфигурации безопасности для справки:
package ca.p6son.spring.config.security;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import java.util.Arrays;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
Environment env;
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Autowired
private UserDetailsService jwtUserDetailsService;
@Autowired
private JwtRequestFilter jwtRequestFilter;
/*
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// configure AuthenticationManager so that it knows from where to load
// user for matching credentials
// Use BCryptPasswordEncoder
auth.userDetailsService(jwtUserDetailsService).passwordEncoder(passwordEncoder());
}
*/
@Bean
public BCryptPasswordEncoder passwordEncoder() {
//return new BCryptPasswordEncoder(11, new SecureRandom());
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
logger.info("AuthManager init: " + super.authenticationManagerBean().toString());
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
boolean isProd = (Arrays.stream(env.getActiveProfiles()).findFirst().orElse(null)).equals("prod");
http
.authorizeRequests()
.antMatchers("/api/v1/geojson/atm",
isProd ? "/api/v1/invalid/path1" : "/swagger-ui/**",
isProd ? "/api/v1/invalid/path2" : "/v3/api-docs/**",
"/api/v1/account/resend_otp",
"/api/v1/resource/**",
"/api/v1/geojson/branches",
"/api/v1/guides",
"/api/v1/faq",
"/actuator/**",
"/api/v1/products",
"/api/v1/version_validate",
"/api/v1/security_guides",
"/api/v1/biometric_challenge", // To enable
"/api/v1/bio-override",
"/api/v1/dao/bio-override",
"/api/v1/push-notification",
"/api/v1/deals_and_offers",
"/api/v1/city_list",
"/api/v1/users",
"/api/v1/cleanup/*",
"/api/v1/account/forgot_username/*",
"/api/v1/account/forgot_password/*",
"/api/v1/auth/**",
"/api/v1/validate/pin",
"/api/v1/test",
"/api/v1/cleanup",
// "/api-docs/**",
// "/swagger-ui.html",
// "/swagger-ui/**",
// "/v3/api-docs/**",
"/inter-module/**",
"/rda-aof/**",
"/api/v1/verify-email-link",
"/api/v1/robo/**",
"/api/v1/terms_and_conditions").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.headers(headers -> {
headers.addHeaderWriter((request, response) -> {
String requestURI = request.getRequestURI();
if (!(requestURI.startsWith("/api/v1/resource/alerts") || requestURI.startsWith("/api/v1/verify-email-link"))) {
// Apply headers to all requests except the excluded endpoint
response.addHeader("Referrer-Policy", "strict-origin-when-cross-origin");
// response.addHeader("X-XSS-Protection", "1; mode=block");
response.addHeader("Content-Security-Policy", "default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; base-uri 'self'; form-action 'self'");
response.addHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
response.addHeader("Permissions-Policy", "geolocation=(self), microphone=(), camera=()");
}
});
})
.cors().and().csrf().disable(); // TODO: Security issue?
// Add a filter to validate the tokens with every request
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}
Подробнее здесь: https://stackoverflow.com/questions/793 ... pring-boot
Подавать файлы с хост-машины через Spring Boot ⇐ JAVA
Программисты JAVA общаются здесь
-
Anonymous
1735149605
Anonymous
У меня на хост-компьютере, где развернута моя серверная служба, есть несколько файлов PDF, которые я хочу предоставлять публично. Требование состоит в том, чтобы сделать обновление файлов динамическим, чтобы клиент мог заменять устаревшие файлы новыми через модуль, который я для них создал. Конечно, я мог бы передавать файлы через конечную точку, но это менее эффективно, поскольку запросы маршрутизируются через весь стек приложения, что увеличивает затраты на обработку по сравнению с прямым обслуживанием статических файлов веб-сервером.
В папке application.properties я добавил следующее:
spring.web.resources.static-locations=file:/home/spidey/sopon3/rda-aof/
Это работает при доступе к my-devdomain.com/public-data.pdf, однако из-за безопасности Spring для доступа к нему требуется аутентификация. Я попробовал разрешить [b]/rda-aof/[/b]** в своей конфигурации безопасности, но это не сработало, и я не могу просто разрешить [b]/[/b]**, потому что это разрешит все конечные точки. Так каков обходной путь для этого? Кроме того, не стесняйтесь предлагать другие методы, если это не сработает.
Я добавляю код конфигурации безопасности для справки:
package ca.p6son.spring.config.security;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import java.util.Arrays;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
Environment env;
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Autowired
private UserDetailsService jwtUserDetailsService;
@Autowired
private JwtRequestFilter jwtRequestFilter;
/*
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// configure AuthenticationManager so that it knows from where to load
// user for matching credentials
// Use BCryptPasswordEncoder
auth.userDetailsService(jwtUserDetailsService).passwordEncoder(passwordEncoder());
}
*/
@Bean
public BCryptPasswordEncoder passwordEncoder() {
//return new BCryptPasswordEncoder(11, new SecureRandom());
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
logger.info("AuthManager init: " + super.authenticationManagerBean().toString());
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
boolean isProd = (Arrays.stream(env.getActiveProfiles()).findFirst().orElse(null)).equals("prod");
http
.authorizeRequests()
.antMatchers("/api/v1/geojson/atm",
isProd ? "/api/v1/invalid/path1" : "/swagger-ui/**",
isProd ? "/api/v1/invalid/path2" : "/v3/api-docs/**",
"/api/v1/account/resend_otp",
"/api/v1/resource/**",
"/api/v1/geojson/branches",
"/api/v1/guides",
"/api/v1/faq",
"/actuator/**",
"/api/v1/products",
"/api/v1/version_validate",
"/api/v1/security_guides",
"/api/v1/biometric_challenge", // To enable
"/api/v1/bio-override",
"/api/v1/dao/bio-override",
"/api/v1/push-notification",
"/api/v1/deals_and_offers",
"/api/v1/city_list",
"/api/v1/users",
"/api/v1/cleanup/*",
"/api/v1/account/forgot_username/*",
"/api/v1/account/forgot_password/*",
"/api/v1/auth/**",
"/api/v1/validate/pin",
"/api/v1/test",
"/api/v1/cleanup",
// "/api-docs/**",
// "/swagger-ui.html",
// "/swagger-ui/**",
// "/v3/api-docs/**",
"/inter-module/**",
"/rda-aof/**",
"/api/v1/verify-email-link",
"/api/v1/robo/**",
"/api/v1/terms_and_conditions").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.headers(headers -> {
headers.addHeaderWriter((request, response) -> {
String requestURI = request.getRequestURI();
if (!(requestURI.startsWith("/api/v1/resource/alerts") || requestURI.startsWith("/api/v1/verify-email-link"))) {
// Apply headers to all requests except the excluded endpoint
response.addHeader("Referrer-Policy", "strict-origin-when-cross-origin");
// response.addHeader("X-XSS-Protection", "1; mode=block");
response.addHeader("Content-Security-Policy", "default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; base-uri 'self'; form-action 'self'");
response.addHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
response.addHeader("Permissions-Policy", "geolocation=(self), microphone=(), camera=()");
}
});
})
.cors().and().csrf().disable(); // TODO: Security issue?
// Add a filter to validate the tokens with every request
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79307901/serve-files-from-host-machine-through-spring-boot[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия