简体   繁体   中英

Wrong Authentication-Object in Controller [Spring-Boot]

I'm pretty new to Spring-Boot. I have tried to block certain routes, permit some and implement authentication for them. This works so far, but somehow I want to get the user who makes the request.

My WebSecurityConfig:

@Configuration
@Order(1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private final JwtTokenService tokenService;

    public WebSecurityConfig(JwtTokenService tokenService) {
        this.tokenService = tokenService;
    }

    @Bean
    public JwtTokenFilter tokenFilter() {
        return new JwtTokenFilter();
    }

    @Bean
    public SecurityContextHolderAwareRequestFilter securityContextHolderAwareRequestFilter() {
        return new SecurityContextHolderAwareRequestFilter();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .authorizeRequests()
                .antMatchers("/login", "/apply").permitAll()
                .anyRequest().authenticated();
        http.addFilterBefore(tokenFilter(), UsernamePasswordAuthenticationFilter.class);
        http.headers().cacheControl();
    }

    @Autowired
    public void configureAuthentication(AuthenticationManagerBuilder builder) {
        builder.authenticationProvider(new AuthenticationProvider() {
            @Override
            public Authentication authenticate(Authentication authentication) throws AuthenticationException {
                String token = (String) authentication.getCredentials();
                return tokenService.decode(token).map(AuthenticatedUser::new).orElseThrow(JwtAuthenticationException::new);
            }

            @Override
            public boolean supports(Class<?> authentication) {
                return JwtAuthentication.class.equals(authentication);
            }
        });
    }
}

The TokenFilter:

@Component
public class JwtTokenFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        String header = request.getHeader("Anima-Authentication-Token");
        if(header != null) {
            SecurityContextHolder.getContext().setAuthentication(new JwtAuthentication(header));
        }
        filterChain.doFilter(request, response);
    }

}

The Authentications:

public class JwtAuthentication implements Authentication {

    private final String token;

    public JwtAuthentication(String token) {
        this.token = token;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }

    @Override
    public Object getCredentials() {
        return token;
    }

    @Override
    public Object getDetails() {
        return null;
    }

    @Override
    public Object getPrincipal() {
        return null;
    }

    @Override
    public boolean isAuthenticated() {
        return false;
    }

    @Override
    public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {

    }

    @Override
    public String getName() {
        return null;
    }
}


public class AuthenticatedUser implements Authentication {

        private final AnimaUser user;

        public AuthenticatedUser(AnimaUser user) {
            this.user = user;
        }

        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return new ArrayList<>();
        }

        @Override
        public Object getCredentials() {
            return null;
        }

        @Override
        public Object getDetails() {
            return null;
        }

        @Override
        public Object getPrincipal() {
            return user;
        }

        @Override
        public boolean isAuthenticated() {
            return true;
        }

        @Override
        public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {

        }

        @Override
        public String getName() {
            return user.getName();
        }
    }

I also tried to override the Authentication in the SecurityContextHolder with the AuthorizedUser Object:

@Autowired
public void configureAuthentication(AuthenticationManagerBuilder builder) {
    builder.authenticationProvider(new AuthenticationProvider() {
        @Override
        public Authentication authenticate(Authentication authentication) throws AuthenticationException {
            String token = (String) authentication.getCredentials();
            return tokenService.decode(token).map(user - > {
                SecurityContextHolder.getContext().setAuthentication(new AuthenticatedUser(user));
                return new AuthenticatedUser(user);
            }).orElseThrow(JwtAuthenticationException::new);
        }

        @Override
        public boolean supports(Class<?> authentication) {
            return JwtAuthentication.class.equals(authentication);
        }
    });
}

But this hasn't worked either. I have tried to access the User with the following methods:

@GetMapping("")
@ResponseBody
public String handle() {
    // This returns the JwtAuthentication, not the AuthenticatedUser
    return SecurityContextHolder.getContext().getAuthentication().getCredentials().toString();
}

@GetMapping("")
@ResponseBody
public String handle(Authentication authentication) {
    // authentication is null
}

@GetMapping("")
@ResponseBody
public String handle(Principle principle) {
    // principle is null
}

It is because of @Component annotation on JwtTokenFilter class. Remove that and you will be good to go. You are already defining that as a @Bean in your WebSecurityConfig class. Since you have @Component on the class it is running after the AuthenticationProvider code overriding the AuthenticatedUser set in SecurityContext with JwtAuthentication

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM