shiro 结合 jwt
时间: 2023-12-06 15:38:37 浏览: 123
shiro-jwt-wx:微信小程序登录,使用shiro+JWT(Token)
Shiro可以与JWT(JSON Web Token)结合使用来实现认证和授权功能。具体步骤如下:
1.编写JWT工具类,用于生成和验证JWT token。
2.编写JWTToken,继承Shiro的AuthenticationToken接口,用于封装JWT token。
3.编写JWTFilter,继承Shiro的AuthenticatingFilter类,用于在请求中验证JWT token。
4.编写JWTRealm,继承Shiro的AuthorizingRealm类,用于从JWT token中获取用户信息并进行授权。
5.编写Shiro配置类,配置JWTFilter和JWTRealm。
下面是一个简单的示例代码:
```java
// JWT工具类
public class JWTUtil {
// 生成JWT token
public static String createToken(String username, String secret) {
Date now = new Date();
Date expireDate = new Date(now.getTime() + 3600 * 1000); // 过期时间为1小时
return Jwts.builder()
.setSubject(username)
.setIssuedAt(now)
.setExpiration(expireDate)
.signWith(SignatureAlgorithm.HS256, secret)
.compact();
}
// 验证JWT token
public static boolean verifyToken(String token, String username, String secret) {
try {
Claims claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
return claims.getSubject().equals(username) && !claims.getExpiration().before(new Date());
} catch (Exception e) {
return false;
}
}
}
// JWTToken
public class JWTToken implements AuthenticationToken {
private String token;
public JWTToken(String token) {
this.token = token;
}
@Override
public Object getPrincipal() {
return token;
}
@Override
public Object getCredentials() {
return token;
}
}
// JWTFilter
public class JWTFilter extends AuthenticatingFilter {
@Override
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
String token = getRequestToken((HttpServletRequest) request);
if (StringUtils.isBlank(token)) {
return null;
}
return new JWTToken(token);
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
String token = getRequestToken((HttpServletRequest) request);
if (StringUtils.isBlank(token)) {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpResponse.setHeader("Access-Control-Allow-Origin", ((HttpServletRequest) request).getHeader("Origin"));
httpResponse.setCharacterEncoding("UTF-8");
httpResponse.setContentType("application/json");
httpResponse.getWriter().print("{\"code\":401,\"msg\":\"未登录\"}");
return false;
}
return executeLogin(request, response);
}
private String getRequestToken(HttpServletRequest request) {
String token = request.getHeader("Authorization");
if (StringUtils.isBlank(token)) {
token = request.getParameter("token"); }
return token;
}
}
// JWTRealm
public class JWTRealm extends AuthorizingRealm {
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof JWTToken;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = JWTUtil.getUsername(principals.toString());
// 根据用户名获取用户角色和权限信息
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setRoles(user.getRoles());
info.setStringPermissions(user.getPermissions());
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
String token = (String) auth.getCredentials();
String username = JWTUtil.getUsername(token);
// 根据用户名获取用户信息
if (user == null) {
throw new UnknownAccountException("用户不存在");
}
if (!JWTUtil.verify(token, username, user.getPassword())) {
throw new IncorrectCredentialsException("token无效");
}
return new SimpleAuthenticationInfo(token, token, "jwtRealm");
}
}
// Shiro配置类
@Configuration
public class ShiroConfig {
@Bean
public JWTFilter jwtFilter() {
return new JWTFilter();
}
@Bean
public JWTRealm jwtRealm() {
return new JWTRealm();
}
@Bean
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(jwtRealm());
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager, JWTFilter jwtFilter) {
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
shiroFilter.setSecurityManager(securityManager);
Map<String, Filter> filters = new HashMap<>();
filters.put("jwt", jwtFilter);
shiroFilter.setFilters(filters);
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/**", "jwt");
shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilter;
}
}
// 异常处理类
@RestControllerAdvice
public class ExceptionHandler {
@ExceptionHandler(UnknownAccountException.class)
public Result handleUnknownAccountException(UnknownAccountException e) {
return Result.error("用户不存在");
}
@ExceptionHandler(IncorrectCredentialsException.class)
public Result handleIncorrectCredentialsException(IncorrectCredentialsException e) {
return Result.error("密码错误");
}
@ExceptionHandler(AuthenticationException.class)
public Result handleAuthenticationException(AuthenticationException e) {
return Result.error("认证失败");
}
@ExceptionHandler(Exception.class)
public Result handleException(Exception e) {
return Result.error("系统异常");
}
}
// Controller
@RestController
public class UserController {
@PostMapping("/login")
public Result login(String username, String password) {
// 根据用户名和密码验证用户信息
String token = JWTUtil.createToken(username, password);
return Result.success(token);
}
@GetMapping("/user")
public Result getUser() {
// 获取当前用户信息
return Result.success(user);
}
}
```
阅读全文