zoukankan      html  css  js  c++  java
  • Shrio04 自定义Realm

    1 说明

    1.1 Realm的作用

    Realm和认证和授权时的数据交互有关,相当于DAO层。

    1.2 AuthorizingRealm

    》层次关系图

    》作用
    继承AuthorizingRealm类后重写doGetAuthorizationInfo和doGetAuthenticationInfo就可以实现授权和认证逻辑。

    2 代码实现

    2.1 创建一个maven项目并引入shiro、junit依赖

    2.2 创建一个类继承AuthorizingRealm

    2.3 重写doGetAuthorizationInfo和doGetAuthenticationInfo

    2.4 完整代码

    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
        }
    }

    3 测试类

    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()));
    
    
        }
    }

    4 注意

    4.1 可以给SecurityManager设置认证策略

    4.2 可以给Realm设置MD5加密

    4.3 SecurityManager必须先设置认证策略再设置Realm

  • 相关阅读:
    LIBSVM使用介绍
    Symbian开发平台的搭建之VC++6.0&&Carbide C++ 2.0
    traits:Traits技术初探
    SDK与IDE的选择(附上设置默认SDK)
    浅析COM的思想及原理
    Windows Live Writer 支持的博客
    JQuery笔记(四) 通用选择的尝试
    JQuery笔记(一)
    JQuery笔记(二) animate支持的属性
    在DW绿化版或者精简版中使用扩展管理
  • 原文地址:https://www.cnblogs.com/NeverCtrl-C/p/10311703.html
Copyright © 2011-2022 走看看