1. Custom token: defines a class inherited from: UsernamePasswordToken
public class MyToken extend UsernamePasswordToken
2. Login operation:
Subject currentUser = SecurityUtils.getSubject(); currentUser.login(MyToken);
3. Custom password certificate: define a class, inherited from: authorizing realm
public class UserRealm extends AuthorizingRealm
4. User defined authorization (after login), rewrite doGetAuthorizationInfo method in user-defined password certificate
/** * Authorization (called when verifying permissions) */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { LoginUser loginUser = (LoginUser) principals.getPrimaryPrincipal(); int roleId = loginUser.getRoleId(); String userType = loginUser.getUserType(); //User permission list Set<String> permsSet = permissionBizService.getPermissionByRoleId(roleId, userType); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.setStringPermissions(permsSet); return info; }
5. User defined authentication operation (called at login time), rewrite doGetAuthenticationInfo in user-defined password certificate
/** * Authentication (called at login) */ @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) { //No account number found throw new UnknownAccountException(); } //Give it to authenticatingream to use CredentialsMatcher for password matching SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(loginUser, loginUser.getPassword(), getName()); //No need to save password in session loginUser.setPassword(null); //Put user information into session Session session = SecurityUtils.getSubject().getSession(); session.setAttribute(Constants.SESSION_USER, loginUser); return authenticationInfo; }
6. Use the custom password verification (called in the custom authentication operation method) to initialize the initCredentialsMatcher method in the custom password certificate
@PostConstruct public void initCredentialsMatcher() { //The function of this sentence is to rewrite the password verification of shiro and let shiro use my own verification setCredentialsMatcher(new CustomCredentialsMatcher()); }
7. Custom password verification: defines a class that inherits from SimpleCredentialsMatcher
/** * Custom password verification **/ 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(); //Verify the encrypted password with the encrypted password of the system. If the content is consistent, true will be returned. If the content is inconsistent, false will be returned try { if (loginType.equals("0")){//Login with user name + password return PasswordHash.validatePassword(tokenCredentials.toString(), accountCredentials.toString()); }else{//Login with mobile phone verification code return true; } } catch (Exception e) { throw new ServiceException("Wrong password!"); } } }