Reputation: 186
I have a problem with authentication in spring. I have authentication filter extends UsernamePasswordAuthenticationFilter.
public class AuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private final AuthenticationManager authenticationManager;
private final RefreshTokenProvider refreshTokenProvider;
private final AccessTokenProvider accessTokenProvider = new AccessTokenProvider();
public AuthenticationFilter(AuthenticationManager authenticationManager, RefreshTokenProvider refreshTokenProvider) {
this.authenticationManager = authenticationManager;
this.refreshTokenProvider = refreshTokenProvider;
setFilterProcessesUrl(SecurityConstants.AUTH_SIGN_IN_PATH);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
try {
SingInRequest singInRequest = new ObjectMapper().readValue(request.getInputStream(), SingInRequest.class);
UsernamePasswordAuthenticationToken authRequest =
new UsernamePasswordAuthenticationToken(singInRequest.getUsername(), singInRequest.getPassword());
return authenticationManager.authenticate(authRequest);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected void successfulAuthentication(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain,
Authentication auth) throws IOException, ServletException {
//
}
Implementation UserDetailsService
@RequiredArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {
private final PasswordEncoder encoder;
private final UserQueryRepository userQueryRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return userQueryRepository.findUserByUsername(username)
.map(this::getUserDetails)
.orElseThrow(() -> new UsernameNotFoundException("User with username " + username + " not found"));
}
private UserDetails getUserDetails(UserDto user) {
return org.springframework.security.core.userdetails.User.builder()
.username(user.getUsername())
.authorities(convertAuthorities(user))
.password(encoder.encode(user.getPassword()))
.disabled(!user.isActive())
.build();
}
private List<GrantedAuthority> convertAuthorities(UserDto user) {
return user.getRoles().stream().map(role ->
new SimpleGrantedAuthority(role.toString())
).collect(Collectors.toList());
}
}
And SecurityConfig class
@EnableWebSecurity
@Configuration
@RequiredArgsConstructor
class SecurityConfig extends WebSecurityConfigurerAdapter {
private final UserQueryRepository userQueryRepository;
private final RefreshTokenProvider refreshTokenProvider;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/auth/**").permitAll()
.antMatchers("/book/**").authenticated()
.and()
.addFilter(new AuthenticationFilter(authenticationManager(), refreshTokenProvider))
.addFilter(new AuthorizationFilter(authenticationManager()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService())
.passwordEncoder(passwordEncoder());
}
@Bean
public UserDetailsService userDetailsService() {
return new UserDetailsServiceImpl(passwordEncoder(), userQueryRepository);
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration corsConfiguration = new CorsConfiguration();
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
corsConfiguration.addAllowedOrigin("http://localhost:3000");
source.registerCorsConfiguration("/**", corsConfiguration);
return source;
}
And if I try with the postman send an auth request with good credentials, in debugger mode everything works fine (AuthFilter and UserDetailsService) but the server returns 401 and successfulAuthentication method in Authfilter doesn't invoke.
Request received for POST '/auth/sing-in':
org.apache.catalina.connector.RequestFacade@27b774b2
servletPath:/auth/sing-in pathInfo:null headers: content-type: application/json user-agent: PostmanRuntime/7.25.0 accept: / cache-control: no-cache postman-token: c5bb3320-9c22-4d3d-93e9-628fe0e6f82a host: localhost:9000 accept-encoding: gzip, deflate, br connection: keep-alive content-length: 54
Security filter chain: [ WebAsyncManagerIntegrationFilter SecurityContextPersistenceFilter HeaderWriterFilter LogoutFilter AuthenticationFilter AuthorizationFilter RequestCacheAwareFilter SecurityContextHolderAwareRequestFilter AnonymousAuthenticationFilter SessionManagementFilter ExceptionTranslationFilter FilterSecurityInterceptor ]
2020-06-13 20:52:42.048 INFO 9956 --- [nio-9000-exec-2] org.mongodb.driver.connection : Opened connection [connectionId{localValue:2, serverValue:126}] to 127.0.0.1:27017 2020-06-13 20:52:42.258 INFO 9956 --- [nio-9000-exec-2] Spring Security Debugger :
Request received for POST '/error':
org.apache.catalina.core.ApplicationHttpRequest@fafe057
servletPath:/error pathInfo:null headers: content-type: application/json user-agent: PostmanRuntime/7.25.0 accept: / cache-control: no-cache postman-token: c5bb3320-9c22-4d3d-93e9-628fe0e6f82a host: localhost:9000 accept-encoding: gzip, deflate, br connection: keep-alive content-length: 54
Security filter chain: [ WebAsyncManagerIntegrationFilter SecurityContextPersistenceFilter HeaderWriterFilter LogoutFilter AuthenticationFilter AuthorizationFilter RequestCacheAwareFilter SecurityContextHolderAwareRequestFilter AnonymousAuthenticationFilter SessionManagementFilter ExceptionTranslationFilter FilterSecurityInterceptor ]
Upvotes: 0
Views: 827
Reputation: 91
There is nothing in the successfulAuthentication() method. It should look like this.
@Override
protected void successfulAuthentication(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain,
Authentication auth) throws IOException, ServletException {
super.successfulAuthentication(req, res, chain, auth);
chain.doFilter(req, res);
}
Sorry I didn't notice that 'successfulAuthentication doesn't invoke'. Could you please share the stack trace in debug mode using
@EnableWebSecurity(debug = true)
Upvotes: 0