下面是一个示例,我使用jwt实现了授权,添加了我的用户,但是授权期间出现问题,授权没有发生,邮件在我的项目中将始终是唯一的,我该怎么办?在这种情况下,是否使用相同的UsernamePasswordAuthenticationToken方法?
@RestController
@RequestMapping(value = "/api/v1/auth/")
public class AuthenticationRestControllerV1 {
private final AuthenticationManager authenticationManager;
private final JwtTokenProvider jwtTokenProvider;
private final UserService userService;
@Autowired
public AuthenticationRestControllerV1(AuthenticationManager authenticationManager, JwtTokenProvider jwtTokenProvider, UserService userService) {
this.authenticationManager = authenticationManager;
this.jwtTokenProvider = jwtTokenProvider;
this.userService = userService;
}
@PostMapping("/login")
public ResponseEntity login(@RequestBody AuthenticationRequestDto requestDto) {
System.out.println(requestDto.getUsername());
System.out.println(requestDto.getPassword());
try {
String username = requestDto.getUsername();
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, requestDto.getPassword()));
User user = userService.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User with username: " + username + " not found");
}
String token = jwtTokenProvider.createToken(username, user.getRoles());
Map<Object, Object> response = new HashMap<>();
response.put("username", username);
response.put("token", token);
return ResponseEntity.ok(response);
} catch (AuthenticationException e) {
throw new BadCredentialsException("Invalid username or password");
}
}
}
此刻出现问题authenticationManager.authenticate(新的UsernamePasswordAuthenticationToken(用户名,requestDto.getPassword()));
public class JwtConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
private JwtTokenProvider jwtTokenProvider;
public JwtConfigurer(JwtTokenProvider jwtTokenProvider) {
this.jwtTokenProvider = jwtTokenProvider;
}
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
JwtTokenFilter jwtTokenFilter = new JwtTokenFilter(jwtTokenProvider);
httpSecurity.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
}
public class JwtTokenFilter extends GenericFilterBean {
@Autowired
private JwtTokenProvider jwtTokenProvider;
public JwtTokenFilter(JwtTokenProvider jwtTokenProvider) {
this.jwtTokenProvider = jwtTokenProvider;
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain)
throws IOException, ServletException {
String token = jwtTokenProvider.resolveToken((HttpServletRequest) req);
if (token != null && jwtTokenProvider.validateToken(token)) {
Authentication auth = jwtTokenProvider.getAuthentication(token);
if (auth != null) {
SecurityContextHolder.getContext().setAuthentication(auth);
}
}
filterChain.doFilter(req, res);
}
}
@Component
public class JwtTokenProvider {
@Value("${jwt.token.secret}")
private String secret;
@Value("${jwt.token.expired}")
private long validityInMilliseconds;
@Autowired
private UserDetailsService userDetailsService;
@Bean
public BCryptPasswordEncoder passwordEncoder() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
return bCryptPasswordEncoder;
}
@PostConstruct
protected void init() {
secret = Base64.getEncoder().encodeToString(secret.getBytes());
}
public String createToken(String username, Set<Role> roles) {
Claims claims = Jwts.claims().setSubject(username);
claims.put("roles", getRolesName(roles));
Date now = new Date();
Date validity = new Date(now.getTime() + validityInMilliseconds);
return Jwts.builder()//
.setClaims(claims)//
.setIssuedAt(now)//
.setExpiration(validity)//
.signWith(SignatureAlgorithm.HS256, secret)//
.compact();
}
/*
Метод возвращает аутентификацию по токену
*/
public Authentication getAuthentication(String token) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(getUsername(token));
return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
}
public String getUsername(String token) {
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getSubject();
}
public String resolveToken(HttpServletRequest req) {
String bearerToken = req.getHeader("Authorization");
if (bearerToken != null && bearerToken.startsWith("Bearer_")) {
return bearerToken.substring(7, bearerToken.length());
}
return null;
}
public boolean validateToken(String token) {
try {
Jws<Claims> claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
if (claims.getBody().getExpiration().before(new Date())) {
return false;
}
return true;
} catch (JwtException | IllegalArgumentException e) {
throw new JwtAuthenticationException("JWT token is expired or invalid");
}
}
private List<String> getRolesName(Set<Role> roles) {
List<String> result = new ArrayList<>();
roles.forEach(role -> {
result.add(role.name());
});
return result;
}
}
public class JwtUser implements UserDetails {
private final Integer id;
private final String username;
private final String surname;
private final String patronymic;
private final String email;
private final String password;
private final Date birthDay;
private final Boolean active;
private final String mobileNumber;
private final Collection<? extends GrantedAuthority> authorities;
private final String activationCode;
public JwtUser(Integer id,
String username,
String surname,
String patronymic,
String email,
String password,
Date birthDay,
Boolean active,
String mobileNumber,
Collection<? extends GrantedAuthority> authorities,
String activationCode) {
this.id = id;
this.username = username;
this.surname = surname;
this.patronymic = patronymic;
this.email = email;
this.password = password;
this.birthDay = birthDay;
this.active = active;
this.mobileNumber = mobileNumber;
this.authorities = authorities;
this.activationCode = activationCode;
}
public final class JwtUserFactory {
public JwtUserFactory() {
}
public static JwtUser create(User user) {
return new JwtUser(
user.getId(),
user.getUsername(),
user.getSurname(),
user.getPatronymic(),
user.getEmail(),
user.getPassword(),
user.getBirthDay(),
user.getActive(),
user.getMobileNumber(),
mapToGA(user.getRoles()),
user.getActivationCode()
);
}
public static Set<GrantedAuthority> mapToGA(Set<Role> roles) {
return roles.stream().map(role ->
new SimpleGrantedAuthority(role.name())).
collect(Collectors.toSet());
}
}
@Service
public class JwtUserDetailsService implements UserDetailsService {
@Autowired
private UserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userService.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User with this username" + username + " not found");
}
JwtUser jwtUser = JwtUserFactory.create(user);
return jwtUser;
}
}
授权不起作用。我在行org.springframework.security.authentication.BadCredentialsException: Invalid username or password
中收到错误authenticationManager.authenticate (new UsernamePasswordAuthenticationToken (username, requestDto.getPassword ())) ;
。正如我在本案例中所指出的,这是唯一的邮件,如何使用她的授权?要改变什么?
这是调试org.springframework.security.authentication.UsernamePasswordAuthenticationToken@4138b2c7时跟踪的内容:主体:xxx@gmail.com;凭证:[受保护];已验证:假;详细信息:null;没有授予任何权限
public enum Role implements GrantedAuthority {
ADMIN,
USER,
WATCHER;
public static Role lookup(String name) {
for (Role role : Role.values()) {
if (role.name().equals(name)) {
return role;
}
}
throw new IllegalArgumentException("No matching constant for " + Role.class.getSimpleName() + " name = " + name);
}
@Override
public String getAuthority() {
return null;
}
}