我试图用JWT配置SpringBoot应用程序,并且每次尝试使用JWTAuthenticationFilter.class进行身份验证时,都会收到错误的凭据异常。我觉得整个问题都是由Bycrpt造成的,因为用户link,抱怨同样的问题。但是当我实现他的代码时,它对我不起作用。
下面是我的spring安全配置器类:
@EnableGlobalMethodSecurity(prePostEnabled = true)
// @配置 @EnableWebSecurity 公共类JwtSecurityConfiguration扩展了WebSecurityConfigurerAdapter {
private final CustomerDetailsService customerDetailsService;
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Autowired
public JwtSecurityConfiguration(CustomerDetailsService customerDetailsService) {
this.customerDetailsService = customerDetailsService;
}
@Autowired
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/welcome/login").permitAll()
.antMatchers("**/rest/**").authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler)
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(new JWTAuthenticationFilter(authenticationManager(),
(BCryptPasswordEncoder) passwordEncoder()), UsernamePasswordAuthenticationFilter.class);
http.addFilter(new JWTAuthorizationFilter(authenticationManager(),customerDetailsService));
http
.headers()
.frameOptions().sameOrigin()
.cacheControl();
}
}
这是JWTAuthenticationFiler类:
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private AuthenticationManager authenticationManager;
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
public JWTAuthenticationFilter(AuthenticationManager authenticationManager, BCryptPasswordEncoder bCryptPasswordEncoder) {
this.authenticationManager = authenticationManager;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
try {
User user = new ObjectMapper().readValue(request.getInputStream(), User.class);
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
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 {
ZonedDateTime expirationTimeUTC = ZonedDateTime.now(ZoneOffset.UTC).plus(EXPIRATION_TIME, ChronoUnit.MILLIS);
String token = Jwts.builder().setSubject(((User)authResult.getPrincipal()).getUserName())
.setExpiration(Date.from(expirationTimeUTC.toInstant()))
.signWith(SignatureAlgorithm.ES256, SECRET)
.compact();
response.getWriter().write(token);
response.addHeader(HEADER, TOKEN_PREFIX + token);
}
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
super.unsuccessfulAuthentication(request, response, failed);
response.getWriter().write(failed.getMessage());
}
}
最后这是我的customerdetailservice类:
@Component
public class CustomerDetailsService implements UserDetailsService {
@Autowired
DefaultUserDAOService defaultUserDAOService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = defaultUserDAOService.getByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username));
} else {
return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassword(),
AuthorityUtils.createAuthorityList("ROLE_USER"));
}
}
}
答案 0 :(得分:0)
添加新用户时,您做了吗?
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
在将其保存到数据库之前? Spring不会为您做到这一点,您必须自己做。并确保使用相同的算法和盐(如果有的话)
检查您的数据库以查看真正保存的密码是什么。
希望这对您有所帮助。