Realm和認證和受權時的數據交互有關,至關於DAO層。前端
》層次關係圖java
》做用
繼承AuthorizingRealm類後重寫doGetAuthorizationInfo和doGetAuthenticationInfo就能夠實現受權和認證邏輯。apache
package com.xunyji.demo04.realm; import com.xunyji.demo0.StringUtilsXyj; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.crypto.hash.Md5Hash; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; /** * @author AltEnter * @create 2019-01-23 20:32 * @desc 自定義Realm,md **/ public class CustomRealm extends AuthorizingRealm { private Logger log = LoggerFactory.getLogger(this.getClass()); private Map<String, String> userMap = new HashMap<String, String>(); { getName(); // userMap.put("fury", "111111"); // userMap.put("fury", "96e79218965eb72c92a549dd5a330112"); userMap.put("fury", "66b747dd6c7c7c8ca4227a67fff8ea6e"); } /** * 受權邏輯 * @param principals * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // 01 獲取用戶名 String username = (String) principals.getPrimaryPrincipal(); // 02 獲取權限集合 Set<String> permissionSet = getPermissionSetByUsername(username); // 03 獲取角色集合 Set<String> roleSet = getRoleSetByUsername(username); // 04 封裝SimpleAuthorizationInfo對象 SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); simpleAuthorizationInfo.setRoles(roleSet); simpleAuthorizationInfo.setStringPermissions(permissionSet); return simpleAuthorizationInfo; } /** * 根據用戶名獲取權限集合 * @param username * @return */ private Set<String> getPermissionSetByUsername(String username) { HashSet<String> permissionSet = new HashSet<>(); permissionSet.add("user:create"); permissionSet.add("user:delete"); permissionSet.add("user:update"); return permissionSet; } /** * 根據用戶名獲取角色集合 * @param username * @return */ private Set<String> getRoleSetByUsername(String username) { HashSet<String> roleSet = new HashSet<>(); roleSet.add("admin"); roleSet.add("user"); return roleSet; } /** * 認證邏輯 * @param token * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { // 01 獲取前端用戶名和密碼 String username = (String) token.getPrincipal(); String passoword = new String((char[]) token.getCredentials()); if (StringUtilsXyj.isEmpty(passoword) || StringUtilsXyj.isEmpty(username)) { String msg = "doGetAuthenticationInfo - 用戶名和密碼不能爲空"; log.info(msg); throw new RuntimeException(msg); } log.info(String.format("doGetAuthenticationInfo - 前端傳過來的用戶信息爲 - 用戶名爲:%s ,用戶密碼爲:%s", username, passoword)); System.out.println(String.format("doGetAuthenticationInfo - 前端傳過來的用戶信息爲 - 用戶名爲:%s ,用戶密碼爲:%s", username, passoword)); // 02 根據用戶名獲取用戶密碼 String pwd = getPasswordByUsername(username); // 03 前端密碼加密加鹽處理 passoword = string2Md5Hash(passoword, "AltEnter"); System.out.println("加鹽加密後的密碼爲:" + pwd); // 04 密碼比對 if (passoword.equals(pwd)) { // 封裝SimpleAuthenticationInfo對象 SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, passoword, getName()); // 加鹽處理 simpleAuthenticationInfo.setCredentialsSalt(ByteSource.Util.bytes("AltEnter")); return simpleAuthenticationInfo; } else { String msg = "doGetAuthenticationInfo - 用戶名或者密碼錯誤"; log.info(msg); System.out.println(msg); throw new RuntimeException(msg); } } /** * 密碼加密加鹽處理 * @param password 待加密密碼 * @param salt 鹽 * @return 通過加密和加鹽處理後的密碼 */ private String string2Md5Hash(String password, String salt) { return new Md5Hash(password, salt).toString(); } /** * 根據用戶名獲取密碼 * @param username * @return */ private String getPasswordByUsername(String username) { String pwd = userMap.get(username); return pwd; } public static void main(String[] args) { // Md5Hash md5Hash = new Md5Hash("111111"); // System.out.println("111111加密後的結果爲:" + md5Hash.toString()); // 96e79218965eb72c92a549dd5a330112 Md5Hash md5Hash = new Md5Hash("111111", "AltEnter"); System.out.println("111111通過MD5加密和AltEnter加鹽後的結果爲:" + md5Hash.toString()); // 66b747dd6c7c7c8ca4227a67fff8ea6e } }
package com.xunyji.demo04.realm; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.authc.pam.FirstSuccessfulStrategy; import org.apache.shiro.authc.pam.ModularRealmAuthenticator; import org.apache.shiro.mgt.DefaultSecurityManager; import org.apache.shiro.subject.Subject; import org.junit.Test; import static org.junit.Assert.*; public class CustomRealmTest { @Test public void test01() { CustomRealm customRealm = new CustomRealm(); // shiro加密 start HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(); //選擇加密方式 matcher.setHashAlgorithmName("md5"); //加密次數 matcher.setHashIterations(1); // 給自定義Realm設置加密規則 customRealm.setCredentialsMatcher(matcher); // shiro加密 end // 更改認證策略 start DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager(); FirstSuccessfulStrategy firstSuccessfulStrategy = new FirstSuccessfulStrategy(); ModularRealmAuthenticator modularRealmAuthenticator = new ModularRealmAuthenticator(); modularRealmAuthenticator.setAuthenticationStrategy(firstSuccessfulStrategy); defaultSecurityManager.setAuthenticator(modularRealmAuthenticator); // 更改認證策略 end defaultSecurityManager.setRealm(customRealm); SecurityUtils.setSecurityManager(defaultSecurityManager); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("fury", "111111"); subject.login(token); System.out.println(String.format("認證信息爲:%s", subject.isAuthenticated())); System.out.println(String.format("擁有admin角色嗎? - %s", subject.hasRole("admin"))); System.out.println(String.format("擁有user:create權限嗎? - %s", subject.isPermitted("user:create"))); subject.logout(); System.out.println(String.format("認證信息爲:%s", subject.isAuthenticated())); } }