我对Springboot非常陌生,目前正处于学习阶段。所以 springboot 充当资源服务器来保护我的 API 免受未经授权的用户的攻击。同时,每次调用 API 时,我的前端都会将访问令牌 (jwt) 传递到我的 Springboot。 (是的,我已经确认了)。
然而,我的 springboot 应用程序收到了 jwt,但无法验证它,并且每次在通过 MSAL 登录并生成访问令牌并传入我的标头后从前端应用程序调用 API 时都会传递 401 错误。
这是我的 SB 的 securityconfig:
@Bean
public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
.oauth2ResourceServer(OAuth -> OAuth.jwt(Customizer.withDefaults()));
return http.build();
}
应用程序属性
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://login.microsoftonline.com/<my-tenant-id>/v2.0
我想我已经具备了成为资源服务器所需的一切。
我已经在这里停留了几个星期,没有任何指示。我还需要解码 JWT 吗?但我一直使用 Azure 作为客户端,他们应该按照应用程序属性中所述为我解码和验证它。
是的,您需要解码令牌。 尝试创建两个像这样的自定义处理程序以进行身份验证和授权。 在使用基于 JWT 的身份验证时,您还需要禁用其他安全技术,例如 csrf、登录、注销,因为它们默认启用。还要确保您的配置类使用 @Configuration 进行注释 @EnableWebSecurity
身份验证处理程序
@Component
公共类 AuthenticationExceptionHandler 实现 AuthenticationEntryPoint { 私有最终 HandlerExceptionResolver 解析器;
@Autowired
public AuthenticationExceptionHandler(HandlerExceptionResolver handlerExceptionResolver) {
this.resolver = handlerExceptionResolver;
}
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) {
resolver.resolveException(request, response, null, authException);
}
}
private final AuthenticationExceptionHandler authenticationExceptionHandler;
private final AccessDeniedExceptionHandler accessDeniedExceptionHandler;
@Autowired
public WebSecurityConfig(AuthenticationExceptionHandler authenticationExceptionHandler, AccessDeniedExceptionHandler accessDeniedExceptionHandler) {
this.accessDeniedExceptionHandler = accessDeniedExceptionHandler;
this.authenticationExceptionHandler = authenticationExceptionHandler;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.httpBasic(AbstractHttpConfigurer::disable)
.csrf(AbstractHttpConfigurer::disable)
.formLogin(AbstractHttpConfigurer::disable)
.logout(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(authorize ->
authorize
.anyRequest().authenticated()
)
.oauth2ResourceServer(httpSecurityOAuth2ResourceServerConfigurer ->
httpSecurityOAuth2ResourceServerConfigurer.jwt(jwt -> jwt.decoder(jwtDecoder()))
.authenticationEntryPoint(authenticationExceptionHandler)
.accessDeniedHandler(accessDeniedExceptionHandler)
)
.sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.build();
}
@Bean
public JwtDecoder jwtDecoder() {
RestOperations rest = new RestTemplateBuilder()
.setConnectTimeout(Duration.ofMillis(connectionTimeout))
.setReadTimeout(Duration.ofMillis(connectionTimeout))
.build();
return NimbusJwtDecoder.withJwkSetUri(jwkSetUri).restOperations(rest).build();
}