我的身份验证基于
spring-boot-security-example.
当我输入无效令牌时,我想抛出401 Unauthorized异常.但是,我总是找不到404资源.我的配置设置了一个异常处理,但它被忽略 – 可能是因为之前添加了我的AuthenticationFilter而请求没有到达我的异常处理程序.
当我输入无效令牌时,我想抛出401 Unauthorized异常.但是,我总是找不到404资源.我的配置设置了一个异常处理,但它被忽略 – 可能是因为之前添加了我的AuthenticationFilter而请求没有到达我的异常处理程序.
我需要改变什么才能抛出401异常?
我有一个身份验证过滤器:
- 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;
- }
AuthenticationProvider实现:
- @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"));
- }
- ...
- }
以及如下配置:
- @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);
- }
- }
解决方法
我在这个帖子中找到了答案:
Return HTTP Error 401 Code & Skip Filter Chains
代替
- httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,authenticationException.getMessage());
我需要打电话
- httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);