在認證、授權內部實現機制中,最終處理都將交給Real進行處理。因為在Shiro中,最終是通過Realm來獲取應用程序中的用戶、角色及權限信息的。
在應用程序中要做的是自定義一個Realm類,繼承AuthorizingRealm抽象類,重載doGetAuthenticationInfo (),重寫獲取用戶信息的方法。而授權實現則與認證實現非常相似,在我們自定義的Realm中,重載doGetAuthorizationInfo()方法,重寫獲取用戶權限的方法。
public class ShiroDbRealm extends AuthorizingRealm { /** * 登錄認證/獲取用戶信息 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException { IShiro shiroFactory = ShiroFactroy.me(); UsernamePasswordToken token = (UsernamePasswordToken) authcToken; //根據前端傳的用戶,查找數據庫用戶的記錄封裝在user里 User user = shiroFactory.user(token.getUsername()); ShiroUser shiroUser = shiroFactory.shiroUser(user); SimpleAuthenticationInfo info = shiroFactory.info(shiroUser, user, super.getName()); return info; } /** * 權限認證/獲取用戶權限 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { IShiro shiroFactory = ShiroFactroy.me(); ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal(); List<Integer> roleList = shiroUser.getRoleList(); Set<String> permissionSet = new HashSet<>(); Set<String> roleNameSet = new HashSet<>(); for (Integer roleId : roleList) { List<String> permissions = shiroFactory.findPermissionsByRoleId(roleId); if (permissions != null) { for (String permission : permissions) { if (ToolUtil.isNotEmpty(permission)) { permissionSet.add(permission); } } } String roleName = shiroFactory.findRoleNameByRoleId(roleId); roleNameSet.add(roleName); } SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.addStringPermissions(permissionSet); info.addRoles(roleNameSet); return info; } /** * 設置認證加密方式 */ @Override public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) { super.setCredentialsMatcher(new CustomCredentialsMatcher()); } }
自定義密碼認證方式
自定義實現類繼承SimpleCredentialsMatcher,重載doCredentialsMatch方法,自定義驗證方式
public class CustomCredentialsMatcher extends SimpleCredentialsMatcher { @Override public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) { UsernamePasswordToken token = (UsernamePasswordToken) authcToken; Object tokenCredentials = encrypt(String.valueOf(token.getPassword())); //System.err.println("encryptionPw:"+encrypt(String.valueOf(token.getPassword()))); Object accountCredentials = getCredentials(info); //將密碼加密與系統加密后的密碼校驗,內容一致就返回true,不一致就返回false return equals(tokenCredentials, accountCredentials); } //密碼加密方法 private String encrypt(String data) { String encryptionPw = ShiroKit.md5(data); return encryptionPw; } }
最后在自定義的Realm類中設置。
/** * 設置認證加密方式 */ @Override public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) { super.setCredentialsMatcher(new CustomCredentialsMatcher()); }