请给我一个用jwt和security做登录的模板
时间: 2024-03-09 10:49:12 浏览: 21
好的,以下是一个使用 JWT 和 Spring Security 实现登录认证的模板:
1. 添加依赖
在 pom.xml 文件中添加以下依赖:
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
```
2. 创建 User 类
创建一个 User 类来存储用户的信息,如下所示:
```java
public class User implements UserDetails {
private Long id;
private String username;
private String password;
private Collection<? extends GrantedAuthority> authorities;
public User(Long id, String username, String password, Collection<? extends GrantedAuthority> authorities) {
this.id = id;
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;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
```
3. 创建 JwtTokenUtil 类
创建一个 JwtTokenUtil 类来生成和验证 JWT,如下所示:
```java
public class JwtTokenUtil {
private static final String SECRET_KEY = "secret";
private static final long EXPIRATION_TIME = 864_000_000; // 10 days
private static final String TOKEN_PREFIX = "Bearer ";
private static final String HEADER_STRING = "Authorization";
public static String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
claims.put("sub", userDetails.getUsername());
claims.put("created", new Date());
claims.put("authorities", userDetails.getAuthorities());
return Jwts.builder()
.setClaims(claims)
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS512, SECRET_KEY)
.compact();
}
public static Authentication getAuthentication(String token) {
Claims claims = Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
Collection<? extends GrantedAuthority> authorities =
Arrays.stream(claims.get("authorities").toString().split(","))
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
UserDetails principal = new User(claims.getSubject(), "", authorities);
return new UsernamePasswordAuthenticationToken(principal, "", authorities);
}
public static boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
return true;
} catch (JwtException | IllegalArgumentException e) {
return false;
}
}
public static String getTokenFromHeader(HttpServletRequest request) {
String header = request.getHeader(HEADER_STRING);
if (header != null && header.startsWith(TOKEN_PREFIX)) {
return header.replace(TOKEN_PREFIX, "");
}
return null;
}
}
```
4. 创建 JwtAuthenticationFilter 类
创建一个 JwtAuthenticationFilter 类来拦截登录请求并生成 JWT,如下所示:
```java
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
if (username != null && password != null) {
Authentication authentication = new UsernamePasswordAuthenticationToken(username, password);
Authentication result = getAuthenticationManager().authenticate(authentication);
if (result.isAuthenticated()) {
String token = JwtTokenUtil.generateToken(result.getPrincipal());
response.addHeader(JwtTokenUtil.HEADER_STRING, JwtTokenUtil.TOKEN_PREFIX + token);
}
}
filterChain.doFilter(request, response);
}
}
```
5. 配置 Spring Security
在 Spring Security 配置类中添加 JwtAuthenticationFilter,并禁用 CSRF 防护,如下所示:
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("{noop}password").roles("ADMIN");
}
}
```
6. 实现登录接口
在 Controller 中实现登录接口,如下所示:
```java
@RestController
public class LoginController {
@PostMapping("/login")
public ResponseEntity<String> login(HttpServletRequest request) {
String token = JwtTokenUtil.getTokenFromHeader(request);
if (token != null && JwtTokenUtil.validateToken(token)) {
return ResponseEntity.ok("Login successful!");
}
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid username or password!");
}
}
```
以上就是一个使用 JWT 和 Spring Security 实现登录认证的模板,你可以根据自己的需求进行修改。注意在实际应用中,需要将 SECRET_KEY 设置为随机的字符串,并将 EXPIRATION_TIME 设置为合适的值。