com.github.dennisit.vplus.data.security.jwt.JWTRealm Maven / Gradle / Ivy
package com.github.dennisit.vplus.data.security.jwt;
import com.github.dennisit.vplus.data.security.AuthorityIFace;
import com.github.dennisit.vplus.data.utils.JWTUtils;
import com.github.dennisit.vplus.data.utils.StringUtils;
import com.spring.boxes.dollar.JSONUtils;
import com.spring.boxes.dollar.enums.EnableEnum;
import com.spring.boxes.dollar.term.Authority;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
@Slf4j
public class JWTRealm extends AuthorizingRealm {
private AuthorityIFace authorityIFace;
public JWTRealm(AuthorityIFace authorityIFace) {
this.authorityIFace = authorityIFace;
}
/**
* 大坑!,必须重写此方法,不然Shiro会报错
*/
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof JWTToken;
}
/**
* 只有当需要检测用户权限的时候才会调用此方法,例如checkRole,checkPermission之类的
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
Authority authority = (Authority) principals.getPrimaryPrincipal();
log.info("[AuthorizationInfo] userId:{}, authority:{}", authority.getUserId(), JSONUtils.toJSON(authority));
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.addStringPermissions(authorityIFace.selectPermissions(authority.getUserId()));
authorizationInfo.addRoles(authorityIFace.selectRoles(authority.getUserId()));
return authorizationInfo;
}
/**
* 默认使用此方法进行用户名正确与否验证,错误抛出异常即可。
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
String token = (String) auth.getCredentials();
// 解密获得用户编号,用于和数据库进行对比
long userId = getJwtUserId(token);
Authority authority = authorityIFace.selectByUserId(userId);
log.info("[AuthenticationInfo] token:{}, userId:{}, authority:{}", token, userId, JSONUtils.toJSON(authority));
if (null == authority) {
throw new UnknownAccountException("账号不存在.");
}
if (EnableEnum.DISABLE.getValue() == authority.getEnabled()) {
throw new LockedAccountException("账号被锁定.");
}
if (!JWTUtils.jwtUidVerify(token, String.valueOf(authority.getUserId()), authority.getPassword())) {
throw new AuthenticationException("会话信息过期/无效,请重新登录.");
}
return new SimpleAuthenticationInfo(authority, token, getName());
}
/**
* 从Token中解析出来用户ID
*
* @param token 会话编号
* @return 用户编号
*/
public long getJwtUserId(String token) {
if (StringUtils.isBlank(token)) {
throw new IncorrectCredentialsException("会话凭证无效");
}
String uid = JWTUtils.jwtUidGet(token);
if (StringUtils.isBlank(uid)) {
throw new IncorrectCredentialsException("会话凭证无效");
}
return Long.parseLong(uid);
}
}