我在春季遇到认证问题。 我的身份验证过滤器扩展了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 {
//
}
实施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());
}
}
和SecurityConfig类
@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;
}
如果我尝试让邮递员发送具有良好凭据的auth请求,则在调试器模式下一切正常(AuthFilter和UserDetailsService),但服务器返回401,并且Authfilter中的successAuthentication方法不会调用。
答案 0 :(得分:0)
successAuthentication()方法中没有任何内容。看起来应该像这样。
@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);
}
对不起,我没有注意到“ successfulAuthentication不调用”。您能否使用以下方式在调试模式下共享堆栈跟踪?
@EnableWebSecurity(debug = true)
答案 1 :(得分:0)
已收到POST'/ auth / sing-in'请求:
org.apache.catalina.connector.RequestFacade@27b774b2
servletPath:/ auth /输入 pathInfo:null 标头: 内容类型:application / json 用户代理:PostmanRuntime / 7.25.0 接受: / 缓存控制:无缓存 邮递员令牌:c5bb3320-9c22-4d3d-93e9-628fe0e6f82a 主机:localhost:9000 接受编码:gzip,deflate,br 连接:保持活动状态 内容长度:54
安全过滤器链:[ WebAsyncManagerIntegrationFilter SecurityContextPersistenceFilter HeaderWriterFilter 注销过滤器 认证过滤器 授权过滤器 RequestCacheAwareFilter SecurityContextHolderAwareRequestFilter 匿名身份验证过滤器 SessionManagementFilter ExceptionTranslationFilter FilterSecurityInterceptor ]
2020-06-13 20:52:42.048信息9956 --- [nio-9000-exec-2] org.mongodb.driver.connection:打开的连接[connectionId {localValue:2,serverValue:126}] 127.0.0.1:27017 2020-06-13 20:52:42.258信息9956 --- [nio-9000-exec-2] Spring Security Debugger:
已收到POST'/ error'请求:
org.apache.catalina.core.ApplicationHttpRequest@fafe057
servletPath:/错误 pathInfo:null 标头: 内容类型:application / json 用户代理:PostmanRuntime / 7.25.0 接受: / 缓存控制:无缓存 邮递员令牌:c5bb3320-9c22-4d3d-93e9-628fe0e6f82a 主机:localhost:9000 接受编码:gzip,deflate,br 连接:保持活动状态 内容长度:54
安全过滤器链:[ WebAsyncManagerIntegrationFilter SecurityContextPersistenceFilter HeaderWriterFilter 注销过滤器 认证过滤器 授权过滤器 RequestCacheAwareFilter SecurityContextHolderAwareRequestFilter 匿名身份验证过滤器 SessionManagementFilter ExceptionTranslationFilter FilterSecurityInterceptor ]