Spring boot Security自定义过滤器不调用

问题描述 投票:0回答:2

我正在使用 Spring Boot 3.2.0 和 Java 17 开发一个遵循微服务架构的应用程序。我有一个服务 -

AuthService
用于身份验证目的。用户的登录请求将通过 API 网关路由到
AuthService
,并在提供有效的用户凭据后获得 JWT 令牌。

现在,用户拥有有效的 JWT 令牌。通过将此令牌以

Bearer token
格式放入请求标头中,用户可以向任何其他服务(即,employeeService、hospitalService...;我将这些服务称为
OtherService
)发出 http 请求。我不想给令牌验证代码带来负担。相反,在
OtherService
->
AuthService
处有一个 API 端点。此端点将验证 jwt 令牌并返回 cusotm
/auth/validate
对象。
简而言之,工作流程是这样的 - 如果用户想查看员工列表,第一个用户将提供用户名、密码。这将由 

UserDetails

验证并返回

JWT
令牌。然后,用户将使用此令牌向employeeService 发出请求。 AuthService 中将有一个过滤器,它将检查请求标头中是否有任何授权令牌,并对
EmployeeService
进行其余调用以从中获取
UserDetail
对象。 [P.S.我是 Spring Security 的新手;我不确定这种方法是否理想]

下面,我提供了

AuthService

的代码部分。


    应用程序安全
  1. EmployeeService
注意:我在这里没有定义任何 
@RefreshScope @Configuration @EnableWebSecurity @RequiredArgsConstructor public class ApplicationSecurity { private final AppSecurityFilter appSecurityFilter; @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http .csrf(AbstractHttpConfigurer::disable) .cors(AbstractHttpConfigurer::disable) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .addFilterBefore(appSecurityFilter, UsernamePasswordAuthenticationFilter.class) .authorizeHttpRequests(auth -> auth .requestMatchers("/health") .permitAll() .anyRequest() .authenticated()) .build(); } }

AuthenticationManager
AuthenticationProvider
,因为我没有在
bean
中从数据库验证或获取用户对象,而是调用
EmployeeService
AuthService
执行此操作。

2。应用程序安全过滤器

AppSecurityFilter

所以,我面临的问题是;即使我在请求标头中设置了授权令牌; 
@AllArgsConstructor @Component public class AppSecurityFilter extends OncePerRequestFilter { private static String AUTH_SERVER_VALIDATE_TOKEN_URL = "http://AUTH-SERVICE/auth/api/v1/validate"; private RestTemplate restTemplate; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { final String header = request.getHeader(AUTHORIZATION); if (isEmpty(header) || !header.startsWith("Bearer ")) { filterChain.doFilter(request, response); return; } ResponseEntity<AuthResponseDto> authResponse = // get userDetails form authService via restTeamplate post call UserResponseDto user = authResponse.getBody().getUserResponseDto(); SecurityContextHolder.getContext().setAuthentication( new UsernamePasswordAuthenticationToken( user, null, user.getAuthorities() ) ); filterChain.doFilter(request, response); } }

应用程序将请求重定向到Spring的默认登录页面。此外,

EmployeeService
永远不会调用。
我在这里缺少什么,完成这项工作需要哪些必要步骤?

spring-boot spring-security jwt microservices spring-cloud-config
2个回答
1
投票
官方 Spring Security 文档

上有关如何使用不记名令牌授权资源的说明。 此外,Spring Security 文档建议我们向安全过滤器链添加过滤器的方式有一个

小警告

,您应该遵循。 乍一看我也看不出你缺少什么,但是如果你提供更多的上下文,例如 spring boot 版本以及配置文件,也许可以提供更多有用的见解。


0
投票
AppSecurityFilter

类中添加了

@RefreshScope
注释而发生的。
(p.s.我一开始以为这与问题无关,所以没有在问题中添加这个注释)
. 如果将来有人偶然发现此类问题,请在此处添加我的发现。

投入日志后,我发现如果添加了

ApplicationSecurity

那么在应用程序启动时会有两个独立的

@RefreshScope
日志 -
DefaultSecurityFilterChain

如您所见,日志的第二行没有我配置的自定义过滤器。

如果我从类中删除了

line1: o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [ DisableEncodeUrlFilter, WebAsyncManagerIntegrationFilter, SecurityContextHolderFilter, HeaderWriterFilter, LogoutFilter, AppSecurityFilter, <------------------- my custom filter added RequestCacheAwareFilter, SecurityContextHolderAwareRequestFilter, AnonymousAuthenticationFilter, SessionManagementFilter, ExceptionTranslationFilter, AuthorizationFilter ] line2: o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [ DisableEncodeUrlFilter, WebAsyncManagerIntegrationFilter, SecurityContextHolderFilter, HeaderWriterFilter, CorsFilter, CsrfFilter, LogoutFilter, UsernamePasswordAuthenticationFilter, DefaultLoginPageGeneratingFilter, DefaultLogoutPageGeneratingFilter, BasicAuthenticationFilter, RequestCacheAwareFilter, SecurityContextHolderAwareRequestFilter, AnonymousAuthenticationFilter, ExceptionTranslationFilter, AuthorizationFilter ]

注释,则仅打印一行

@RefreshScope
-
 日志
DefaultSecurityFilterChain

通过从 
DefaultSecurityFilterChain : Will secure any request with [ DisableEncodeUrlFilter, WebAsyncManagerIntegrationFilter, SecurityContextHolderFilter, HeaderWriterFilter, LogoutFilter, AppSecurityFilter, <------------------ my custom filter RequestCacheAwareFilter, SecurityContextHolderAwareRequestFilter, AnonymousAuthenticationFilter, SessionManagementFilter, ExceptionTranslationFilter, AuthorizationFilter ]

类中删除

@RefreshScope
,一切都会按预期进行。
为什么我首先添加

ApplicationSecurity

我正在从 ConfigServer 读取一些属性。
为什么添加

@RefreshScope

会使 Spring Security 回退到默认配置?

我还没想明白。

© www.soinside.com 2019 - 2024. All rights reserved.