1、自定义令牌:定义一个类,继承自:UsernamePasswordToken
public class MyToken extend UsernamePasswordToken
2、登陆操作:
Subject currentUser = SecurityUtils.getSubject();
currentUser.login(MyToken);
3、自定义密码凭证:定义一个类,继承自:AuthorizingRealm
public class UserRealm extends AuthorizingRealm
4、自定义授权操作(登陆之后),在自定义密码凭证里面重写doGetAuthorizationInfo方法
/**
* 授权(验证权限时调用)
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
LoginUser loginUser = (LoginUser) principals.getPrimaryPrincipal();
int roleId = loginUser.getRoleId();
String userType = loginUser.getUserType();
//用户权限列表
Set<String> permsSet = permissionBizService.getPermissionByRoleId(roleId, userType);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setStringPermissions(permsSet);
return info;
}
5、自定义认证操作(登陆时候调用),在自定义密码凭证里面重写doGetAuthenticationInfo
/**
* 认证(登录时调用)
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) {
MyToken myToken = (MyToken ) token;
String username = (String) myToken.getPrincipal();
String password = new String((char[]) myToken.getCredentials());
String userType = myToken.getUserType();
LoginUser loginUser = userBizService.getUserByMobile(username, userType);
if (loginUser == null) {
//没找到帐号
throw new UnknownAccountException();
}
//交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(loginUser, loginUser.getPassword(), getName());
//session中不需要保存密码
loginUser.setPassword(null);
//将用户信息放入session中
Session session = SecurityUtils.getSubject().getSession();
session.setAttribute(Constants.SESSION_USER, loginUser);
return authenticationInfo;
}
6、使用自定义密码校验(在自定义认证操作方法里面调用),在自定义密码凭证里面初始化initCredentialsMatcher方法
@PostConstruct
public void initCredentialsMatcher() {
//该句作用是重写shiro的密码验证,让shiro用我自己的验证
setCredentialsMatcher(new CustomCredentialsMatcher());
}
7、自定义密码校验:定义一个类,继承自SimpleCredentialsMatcher
/**
* 自定义密码校验
**/
public class CustomCredentialsMatcher extends SimpleCredentialsMatcher {
@Override
public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
Object tokenCredentials = String.valueOf(token.getPassword());
Object accountCredentials = getCredentials(info);
MyToken myToken = (MyToken) token;
String loginType = myToken.getLoginType();
//将密码加密与系统加密后的密码校验,内容一致就返回true,不一致就返回false
try {
if (loginType.equals("0")){//使用用户名+密码登陆
return PasswordHash.validatePassword(tokenCredentials.toString(), accountCredentials.toString());
}else{//使用手机验证码登陆
return true;
}
} catch (Exception e) {
throw new ServiceException("密码错误!");
}
}
}