spring web jwt
时间: 2023-09-14 11:08:40 浏览: 84
spring web
4星 · 用户满意度95%
Spring Web应用程序可以使用JSON Web Token(JWT)来实现身份验证和授权。JWT是一种开放标准(RFC 7519),用于在各方之间安全地传输信息作为JSON对象。它通常用于声明某些主题的身份以及针对该主题的其他声明。
在Spring Web应用程序中,可以使用Spring Security和jjwt库来实现JWT身份验证和授权。下面是一个简单的示例代码:
首先,需要在pom.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>
```
然后,在Spring Security配置类中配置JWT过滤器:
```
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/api/authenticate").permitAll()
.anyRequest().authenticated().and()
.addFilterBefore(new JWTFilter(), UsernamePasswordAuthenticationFilter.class);
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
@Bean
public AuthenticationProvider authenticationProvider() {
return new JWTAuthenticationProvider();
}
}
```
接下来,实现JWTFilter和JWTAuthenticationProvider类:
```
public class JWTFilter extends OncePerRequestFilter {
private static final String AUTHORIZATION_HEADER = "Authorization";
private static final String BEARER_PREFIX = "Bearer ";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
String authorizationHeader = request.getHeader(AUTHORIZATION_HEADER);
if (authorizationHeader != null && authorizationHeader.startsWith(BEARER_PREFIX)) {
String token = authorizationHeader.substring(BEARER_PREFIX.length());
try {
Jws<Claims> claimsJws = Jwts.parser().setSigningKey("mySecretKey".getBytes())
.parseClaimsJws(token);
String username = claimsJws.getBody().getSubject();
List<String> authorities = (List<String>) claimsJws.getBody().get("authorities");
Authentication authentication = new JWTAuthenticationToken(username, null, authorities.stream()
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList()));
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (JwtException e) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
}
chain.doFilter(request, response);
}
}
public class JWTAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
JWTAuthenticationToken jwtAuthenticationToken = (JWTAuthenticationToken) authentication;
return jwtAuthenticationToken;
}
@Override
public boolean supports(Class<?> authentication) {
return JWTAuthenticationToken.class.isAssignableFrom(authentication);
}
}
public class JWTAuthenticationToken extends AbstractAuthenticationToken {
private String username;
private String password;
public JWTAuthenticationToken(String username, String password, Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.username = username;
this.password = password;
}
@Override
public Object getCredentials() {
return password;
}
@Override
public Object getPrincipal() {
return username;
}
}
```
在JWTFilter中,首先从请求头中提取JWT令牌,然后对其进行验证。如果验证成功,则将身份验证信息存储在SecurityContextHolder中。
在JWTAuthenticationProvider中,只需将JWTAuthenticationToken返回即可。这里不需要进行任何身份验证,因为JWT令牌已经验证过了。
最后,在Controller类中,可以使用@PreAuthorize注释来保护API端点:
```
@RestController
@RequestMapping("/api")
public class MyController {
@GetMapping("/hello")
@PreAuthorize("hasRole('USER')")
public String hello() {
return "Hello World!";
}
}
```
这样,只有具有“USER”角色的用户才能访问/hello端点。
阅读全文