Java校验用户名和密码并颁发一个token
时间: 2023-08-08 08:12:26 浏览: 117
Hiveserver2 Beeline连接设置用户名和密码.docx
5星 · 资源好评率100%
可以使用Java中的Spring Security框架来实现这个功能。
首先,需要定义一个User类来表示用户,包含用户名和密码字段:
```java
public class User {
private String username;
private String password;
public User(String username, String password) {
this.username = username;
this.password = password;
}
// getter and setter methods
}
```
然后,在Spring Security的配置类中定义用户和角色:
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password("{noop}password")
.roles("USER");
}
// other security configurations
}
```
在上述代码中,使用了内存中的用户认证,用户名为"user",密码为"password",角色为"USER"。
接下来,可以使用JWT(JSON Web Token)来生成token。可以使用Java JWT库来实现。在生成token之前,需要定义一个JwtUser类来表示JWT中的用户信息:
```java
public class JwtUser implements UserDetails {
private final String username;
private final String password;
private final Collection<? extends GrantedAuthority> authorities;
public JwtUser(String username, String password, Collection<? extends GrantedAuthority> authorities) {
this.username = username;
this.password = password;
this.authorities = authorities;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
// other methods, such as isAccountNonExpired, isAccountNonLocked, isCredentialsNonExpired, isEnabled
}
```
然后,在Spring Security配置类中,定义一个JwtTokenProvider类来生成token:
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private JwtTokenProvider jwtTokenProvider;
@Autowired
public SecurityConfig(JwtTokenProvider jwtTokenProvider) {
this.jwtTokenProvider = jwtTokenProvider;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/authenticate").permitAll()
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.apply(new JwtTokenFilterConfigurer(jwtTokenProvider));
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password("{noop}password")
.roles("USER");
}
@Bean
public JwtTokenProvider jwtTokenProvider() {
return new JwtTokenProvider();
}
}
```
在上述代码中,定义了一个"/api/authenticate"的接口用来进行用户认证,其他请求都需要进行认证。由于使用了JWT,所以不需要使用session,将sessionCreationPolicy设置为STATELESS。最后,使用JwtTokenFilterConfigurer类来处理token的验证。
下面是生成JWT token的具体实现:
```java
public class JwtTokenProvider {
private static final String SECRET_KEY = "mySecretKey";
private static final long EXPIRATION_TIME = 864_000_000; // 10 days
public String generateToken(User user) {
Claims claims = Jwts.claims().setSubject(user.getUsername());
claims.put("auth", user.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()));
Date now = new Date();
Date expiration = new Date(now.getTime() + EXPIRATION_TIME);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(expiration)
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public Authentication getAuthentication(String token) {
UserDetails userDetails = getUserDetails(token);
return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
}
public boolean validateToken(String token) {
try {
Jws<Claims> claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
return !claims.getBody().getExpiration().before(new Date());
} catch (JwtException | IllegalArgumentException e) {
return false;
}
}
private UserDetails getUserDetails(String token) {
String username = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getSubject();
List<GrantedAuthority> authorities = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().get("auth", List.class)
.stream().map(authority -> new SimpleGrantedAuthority((String) authority)).collect(Collectors.toList());
return new JwtUser(username, "", authorities);
}
}
```
在上述代码中,使用了HS256算法来进行签名,SECRET_KEY是用来加密的密钥。EXPIRATION_TIME设置token的过期时间。generateToken方法用来生成token,getAuthentication方法用来获取用户的认证信息,validateToken方法用来验证token是否有效,getUserDetails方法用来获取用户信息。
最后,在Controller中定义一个authenticate接口来进行用户认证,并返回生成的token:
```java
@RestController
@RequestMapping("/api")
public class AuthController {
private AuthenticationManager authenticationManager;
private JwtTokenProvider jwtTokenProvider;
public AuthController(AuthenticationManager authenticationManager, JwtTokenProvider jwtTokenProvider) {
this.authenticationManager = authenticationManager;
this.jwtTokenProvider = jwtTokenProvider;
}
@PostMapping("/authenticate")
public ResponseEntity<?> authenticate(@RequestBody User user) {
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));
String token = jwtTokenProvider.generateToken(user);
Map<Object, Object> response = new HashMap<>();
response.put("username", user.getUsername());
response.put("token", token);
return ResponseEntity.ok(response);
} catch (AuthenticationException e) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
}
}
```
在上述代码中,使用了AuthenticationManager来进行用户认证,如果认证成功,则生成token并返回。如果认证失败,则返回401 Unauthorized状态码。
阅读全文