这是我的 SecurityConfig 类,即使我的自定义过滤器:SettingsAPIAuthFilter 成功验证了请求,它也会返回 403,因为:
.authorizeHttpRequests(auth -> auth.anyRequest()
.authenticated())
我只是在 SettingsAPIAuthFilter 类中扩展 OncePerRequestFiler 。这是我的 SecurityConfig 类。
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Autowired
private SettingsAPIAuthFilter settingsAPIAuthFilter;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity
.formLogin(AbstractHttpConfigurer::disable)
.httpBasic(AbstractHttpConfigurer::disable)
.addFilterBefore(settingsAPIAuthFilter, UsernamePasswordAuthenticationFilter.class)
.cors(corsConfigurer -> corsConfigurer.configurationSource(request -> {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedOrigins(List.of("*"));
corsConfiguration.setAllowedMethods(List.of(HttpMethod.GET.name(), "POST", "PUT", "DELETE"));
corsConfiguration.setAllowedHeaders(List.of("*"));
return corsConfiguration;
}))
.authorizeHttpRequests(auth -> auth.anyRequest()
.authenticated())
.build();
}
}
我想知道我应该扩展什么过滤器,以便它得到正确的身份验证,并且 spring security 通过 anyRequest().authenticated() 正确地获取身份验证?
编辑:这是我的 SettingsAPIAuthFilter :
@Component
public class SettingsAPIAuthFilter extends OncePerRequestFilter {
private static final String API_AUTHORISE_REQ_ACTION_ID_QUERY_PARAM = "requestActionId";
private static final String API_AUTH_REQ_SESSION_ID_HEADER_NAME = "userSessionId";
public static final String MAIN_API_AUTHORISE_ENDPOINT = "/authorise";
private final AppEventHandler appEventHandler = new AppEventHandler();
private final WebClient mainApiWebClient;
public SettingsAPIAuthFilter(
@Qualifier("mainApiWebClient") WebClient webClient
) {
this.mainApiWebClient = webClient;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
ResponseEntity authResponse = authoriseRequest(
request.getHeader("userSessionId"),
"123");
if (authResponse.getStatusCode().value() == 200) {
appEventHandler.info("Authorisation successful. Moving on...");
filterChain.doFilter(request, response);
}
response.setStatus(authResponse.getStatusCode().value());
response.setHeader("Content-Type", "application/json");
response.getOutputStream().print((String) authResponse.getBody());
} catch (Exception exception) {
appEventHandler.error("Error occurred in SettingsAPIAuthFilter", exception);
}
}
public ResponseEntity<?> authoriseRequest(
String sessionId,
String requestedActionId
) throws Exception {
try {
return mainApiWebClient.get()
.uri(uriBuilder -> uriBuilder
.path(MAIN_API_AUTHORISE_ENDPOINT)
.queryParam(API_AUTHORISE_REQ_ACTION_ID_QUERY_PARAM, requestedActionId)
.build()
)
.header(API_AUTH_REQ_SESSION_ID_HEADER_NAME, sessionId)
.retrieve()
.onStatus(HttpStatusCode::isError, errorResponse -> Mono.empty())
.toEntity(String.class)
.block();
} catch (Exception exception) {
appEventHandler.error("Exception occurred in authorising request : ", exception);
throw new Exception("Exception occurred in authorising request : ", exception);
}
}
}
原因是因为我没有让 spring security 知道请求在 authAPI 身份验证成功后已通过身份验证。修复的方法是将身份验证设置为 SecurityContext,如下所示,取自 Spring Security 文档:
Authentication authentication = new TestingAuthenticationToken("user", "password", "ROLE_USER");
SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
securityContext.setAuthentication(authentication);
SecurityContextHolder.setContext(securityContext);
非常感谢@dur 的帮助。 Spring 安全文档