Olá
Estou desenvolvendo um API REST e estou utilizando o JWT junto com spring security com o objetivo de gerar um tokem de acesso.
Consegui desenvolver um código com pesquisa baseado em artigo que encontroei na internet. Porém o spring security não reconhece os ROLES ou Authoority, no caso ele acessa o tokem mas o tokem não gera o objeto do role dando acesso a qualquer usuario que tenha apenas um tokem entrar.
Gostaria de uma ajuda!
public class JWTAuthenticationFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
Authentication authentication = TokenAuthenticationService
.getAuthentication((HttpServletRequest) request);
SecurityContextHolder.getContext().setAuthentication(authentication);
filterChain.doFilter(request, response);
}
}
JWT Login Filter
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
protected JWTLoginFilter(String url, AuthenticationManager authManager) {
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authManager);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {
return getAuthenticationManager().authenticate(
new UsernamePasswordAuthenticationToken(
request.getParameter("username"),
request.getParameter("password"),
Collections.emptyList()
)
);
}
@Override
protected void successfulAuthentication(
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain,
Authentication auth) throws IOException, ServletException {
response.setStatus(200);
TokenAuthenticationService.addAuthentication(response, auth.getName());
}
}
Token Authentication
public class TokenAuthenticationService {
// EXPIRATION_TIME = 10 dias
static final long EXPIRATION_TIME = 860_000_000;
static final String SECRET = "MySecret";
static final String TOKEN_PREFIX = "Bearer";
static final String HEADER_STRING = "Authorization";
static void addAuthentication(HttpServletResponse response, String username) {
String JWT = Jwts.builder()
.setSubject(username)
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
response.addHeader(HEADER_STRING, TOKEN_PREFIX + " " + JWT);
}
static Authentication getAuthentication(HttpServletRequest request) {
String token = request.getHeader(HEADER_STRING);
if (token != null) {
// faz parse do token
String user = Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
.getBody()
.getSubject();
if (user != null) {
return new UsernamePasswordAuthenticationToken(user, null, Collections.emptyList());
}
}
return null;
}
}
WEBSecurity
@EnableWebSecurity
public class WebSecurityConfig{
@Configuration
@Order(1)
public static class RestWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private UsuarioDAO dao;
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()
.antMatcher("/rest/**")
.authorizeRequests()
.antMatchers("rest/login").permitAll()
.antMatchers("rest/arvore/**").hasRole("MASTER")
//ARVORE
.antMatchers(HttpMethod.POST,"rest/arvore/").hasRole("USUARIO")
.antMatchers(HttpMethod.GET,"rest/arvore/").hasRole("USUARIO")
.antMatchers(HttpMethod.PUT,"rest/arvore/").hasRole("USUARIO")
.antMatchers(HttpMethod.DELETE,"rest/arvore/").hasRole("USUARIO")
.antMatchers("rest/arvore/{username}").hasRole("USUARIO")
//USUARIO
.anyRequest().authenticated()
.and().cors().and().formLogin().loginPage("/rest/login").permitAll()
.and()
.addFilterBefore(new JWTLoginFilter("/rest/login", authenticationManager()),
UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JWTAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(dao);
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass=true)
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private UsuarioDAO dao;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// starts authorizing configurations
.authorizeRequests()
//Resources
.antMatchers("/rest/**").permitAll()
.antMatchers("/css/**").permitAll()
.antMatchers("/js/**").permitAll()
.antMatchers("/images/**").permitAll()
//Pages
.antMatchers("/authenticate").permitAll()
//Arvore
.antMatchers("/arvore/**").hasRole("MASTER")
.anyRequest().authenticated()
.and().cors().and().formLogin().loginPage("/login").permitAll()
.and().csrf().disable();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(dao);
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
}
}