Printemps de Démarrage de Sécurité ne pas jeter 401 non autorisé Exception, mais, 404 not Found
Mon authentification est basée sur un spring-boot-sécurité-exemple.
Quand j'entre dans une défaillance de jeton, je voudrais jeter un 401 non autorisé exception. Cependant, j'ai toujours une erreur 404 ressource non trouvée. Ma configuration définit une gestion des exceptions, mais il est ignoré - sans doute parce que mon AuthenticationFilter est ajouté avant, et la demande n'atteint pas mon gestionnaire d'exception.
De quoi aurais-je besoin de changer de jeter 401 exceptions à la place?
J'ai un filtre d'authentification:
public class AuthenticationFilter extends GenericFilterBean {
...
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = asHttp(request);
HttpServletResponse httpResponse = asHttp(response);
Optional<String> token = Optional.fromNullable(httpRequest.getHeader("X-Auth-Token"));
try {
if (token.isPresent()) {
logger.debug("Trying to authenticate user by X-Auth-Token method. Token: {}", token);
processTokenAuthentication(token);
addSessionContextToLogging();
}
logger.debug("AuthenticationFilter is passing request down the filter chain");
chain.doFilter(request, response);
} catch (InternalAuthenticationServiceException internalAuthenticationServiceException) {
SecurityContextHolder.clearContext();
logger.error("Internal authentication service exception", internalAuthenticationServiceException);
httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (AuthenticationException authenticationException) {
SecurityContextHolder.clearContext();
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authenticationException.getMessage());
} finally {
MDC.remove(TOKEN_SESSION_KEY);
MDC.remove(USER_SESSION_KEY);
}
}
private void addSessionContextToLogging() {
...
}
...
private void processTokenAuthentication(Optional<String> token) {
Authentication resultOfAuthentication = tryToAuthenticateWithToken(token);
SecurityContextHolder.getContext().setAuthentication(resultOfAuthentication);
}
private Authentication tryToAuthenticateWithToken(Optional<String> token) {
PreAuthenticatedAuthenticationToken requestAuthentication = new PreAuthenticatedAuthenticationToken(token, null);
return tryToAuthenticate(requestAuthentication);
}
private Authentication tryToAuthenticate(Authentication requestAuthentication) {
Authentication responseAuthentication = authenticationManager.authenticate(requestAuthentication);
if (responseAuthentication == null || !responseAuthentication.isAuthenticated()) {
throw new InternalAuthenticationServiceException("Unable to authenticate Domain User for provided credentials");
}
logger.debug("User successfully authenticated");
return responseAuthentication;
}
un AuthenticationProvider mise en œuvre:
@Provider
public class TokenAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
Optional<String> token = (Optional) authentication.getPrincipal();
if (!token.isPresent() || token.get().isEmpty()) {
throw new BadCredentialsException("No token set.");
}
if (!myCheckHere()){
throw new BadCredentialsException("Invalid token");
}
return new PreAuthenticatedAuthenticationToken(myConsumerObject, null, AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_API_USER"));
}
...
}
et une configuration qui ressemble comme suit:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.
csrf().disable().
sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).
and().
anonymous().disable().
exceptionHandling().authenticationEntryPoint(unauthorizedEntryPoint());
http.addFilterBefore(new AuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(tokenAuthenticationProvider());
}
@Bean
public AuthenticationProvider tokenAuthenticationProvider() {
return new TokenAuthenticationProvider();
}
@Bean
public AuthenticationEntryPoint unauthorizedEntryPoint() {
return (request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
}
Vous devez vous connecter pour publier un commentaire.
J'ai trouvé la réponse dans ce fil: De retour d'Erreur HTTP 401 Code & Sauter des Chaînes de filtres
Au lieu de
J'ai besoin d'appeler
Il semble que la chaîne s'arrête quand je n'ai pas continuer à l'appeler et en définissant le statut à un autre code - l'exception est levée correctement
Je l'ai résolu en ajoutant l'annotation suivante sur mon top-niveau
@SpringBootApplication
classe:Pourraient Printemps de Démarrage ont du mal à trouver sa page d'erreur par défaut?
En plus de la réponse ci-dessus, j'ai modifié mon code pour atteindre 401, auparavant j'ai eu 500 sur un invalide ou manquante de jeton.
}