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.