springsecurity整合jwt具体代码
时间: 2023-08-24 12:06:13 浏览: 93
springBoot + SpringSecurity + JWT(适用微服务)
下面是Spring Security整合JWT的具体代码实现:
1. 首先需要引入相关的依赖,包括Spring Security和JWT:
```xml
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
```
2. 创建一个JwtUser类,用来存储从数据库中查询出来的用户信息:
```java
public class JwtUser implements UserDetails {
private Long id;
private String username;
private String password;
private Collection<? extends GrantedAuthority> authorities;
public JwtUser(Long id, String username, String password, Collection<? extends GrantedAuthority> authorities) {
this.id = id;
this.username = username;
this.password = password;
this.authorities = authorities;
}
//省略getter和setter方法
@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. 创建一个JwtUtils工具类,用来生成和解析JWT:
```java
public class JwtUtils {
private static final String SECRET_KEY = "my_secret_key";
private static final long EXPIRATION_TIME = 864_000_000; // 10 days
public static String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
claims.put("sub", userDetails.getUsername());
claims.put("iat", new Date().getTime() / 1000);
claims.put("exp", new Date().getTime() / 1000 + EXPIRATION_TIME / 1000);
return Jwts.builder()
.setClaims(claims)
.signWith(SignatureAlgorithm.HS512, SECRET_KEY)
.compact();
}
public static String getUsernameFromToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody()
.getSubject();
}
public static boolean isTokenValid(String token, UserDetails userDetails) {
String username = getUsernameFromToken(token);
return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
}
private static boolean isTokenExpired(String token) {
Date expiration = Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody()
.getExpiration();
return expiration.before(new Date());
}
}
```
4. 创建一个JwtAuthenticationFilter过滤器,用来拦截登录请求并生成JWT:
```java
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private final AuthenticationManager authenticationManager;
public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
try {
LoginRequest loginRequest = new ObjectMapper().readValue(request.getInputStream(), LoginRequest.class);
Authentication authentication = new UsernamePasswordAuthenticationToken(
loginRequest.getUsername(),
loginRequest.getPassword(),
new ArrayList<>()
);
return authenticationManager.authenticate(authentication);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
JwtUser jwtUser = (JwtUser) authResult.getPrincipal();
String token = JwtUtils.generateToken(jwtUser);
response.addHeader("Authorization", "Bearer " + token);
}
}
```
5. 创建一个JwtAuthorizationFilter过滤器,用来验证JWT的有效性:
```java
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {
public JwtAuthorizationFilter(AuthenticationManager authenticationManager) {
super(authenticationManager);
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
String authorizationHeader = request.getHeader("Authorization");
if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
chain.doFilter(request, response);
return;
}
String token = authorizationHeader.replace("Bearer ", "");
if (JwtUtils.isTokenValid(token, null)) {
String username = JwtUtils.getUsernameFromToken(token);
UserDetails userDetails = new JwtUser(1L, username, "", new ArrayList<>());
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
} else {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
chain.doFilter(request, response);
}
}
```
6. 在SecurityConfig配置类中配置过滤器链:
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
```
以上就是整合Spring Security和JWT的具体代码实现,需要根据具体业务场景进行调整。
阅读全文