I'm following this article: https://auth0.com/blog/implementing-jwt-authentication-on-spring-boot/
Making a security layer to protect my Rest API.
I requested to the /login URL but it returns 403.
JwtGenerator:
public class JwtGenerator extends UsernamePasswordAuthenticationFilter {
private final AuthenticationManager authenticationManager;
public JwtGenerator(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response)
throws AuthenticationException {
try {
User user = new ObjectMapper()
.readValue(request.getInputStream(), User.class);
return authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(user.getUsername(),
user.getPassword())
);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
authResult.getAuthorities().forEach(authority -> System.out.println(authority.getAuthority()));
String token = JWT.create()
.withSubject(((org.springframework.security.core.userdetails.User) authResult.getPrincipal()).getUsername())
.withClaim(AUTHORITIES_KEY, authResult.getAuthorities()
.stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.joining(",")))
.withExpiresAt(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.sign(Algorithm.HMAC512(JWT_SECRET.getBytes()));
response.setHeader(HEADER_STRING, TOKEN_PREFIX + token);
}
}
And WebSecurityConfig:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
prePostEnabled = true
)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final UserDetailsService userDetailsService;
private final PasswordEncoder bCryptPasswordEncoder;
public WebSecurityConfig(@Qualifier("UserDetailsService") UserDetailsService userDetailsService, PasswordEncoder bCryptPasswordEncoder) {
this.userDetailsService = userDetailsService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/api/users/sign-up").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtGenerator(authenticationManager()))
.addFilter(new JwtVerifier(authenticationManager()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
}
As far as I know, the /login endpoint is created automatically by Spring Security and the JWT Generator is the modification code for that endpoint. It might be lacking permitAll() for this URL method in WebSecurityConfig?
When I request to that URL, it returned to me 403 without any message:
Even the log:
2020-03-30 07:52:59.916 INFO 1712 --- [nio-1408-exec-2] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-03-30 07:52:59.953 INFO 1712 --- [nio-1408-exec-2] o.s.web.servlet.DispatcherServlet : Completed initialization in 36 ms
Hibernate: select user0_.id as id1_5_, user0_.created_at as created_2_5_, user0_.updated_at as updated_3_5_, user0_.biography as biograph4_5_, user0_.date_of_birth as date_of_5_5_, user0_.displayname as displayn6_5_, user0_.email as email7_5_, user0_.password as password8_5_, user0_.username as username9_5_ from users user0_ where user0_.username=? or user0_....
