• springboot + shiro学习(配置SecurityManager,Realm)


    学习了shiro分析下源码

    从官网可以知道shiro的构成,核心:Subject,SecurityManager,Realm

    Realm中的核心Authorization(用于做权限配置)和Authentication(用于做身份认证),两个单词很接近但意义不同

    SecurityManager是核心用来管理个个组件

    网上可以找一大堆配置shiro的文件这里就不贴了,来写一下整个过程是怎么进行的

    首先是配置:

    配置自定义Ream 

    public class MyShiroRealm extends AuthorizingRealm {
        @Resource
        private UserInfoService userInfoService;
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            System.out.println("权限配置-->MyShiroRealm.doGetAuthorizationInfo()");
            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
            UserInfo userInfo  = (UserInfo)principals.getPrimaryPrincipal();
            for(SysRole role:userInfo.getRoleList()){
                authorizationInfo.addRole(role.getRole());
                for(SysPermission p:role.getPermissions()){
                    authorizationInfo.addStringPermission(p.getPermission());
                }
            }
            return authorizationInfo;
        }
    
        /*主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。*/
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
                throws AuthenticationException {
            System.out.println("MyShiroRealm.doGetAuthenticationInfo()");
            //获取用户的输入的账号.
            String username = (String)token.getPrincipal();
            System.out.println(token.getCredentials());
            //通过username从数据库中查找 User对象,如果找到,没找到.
            //实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法
            UserInfo userInfo = userInfoService.findByUsername(username);
            System.out.println("----->>userInfo="+userInfo);
            if(userInfo == null){
                return null;
            }
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                    userInfo, //用户名
                    userInfo.getPassword(), //密码
                    ByteSource.Util.bytes(userInfo.getCredentialsSalt()),//salt=username+salt
                    getName()  //realm name
            );
            return authenticationInfo;
        }
    
    
    
    }

     实现 AuthorizingRealm,实现权限配置和用户认证,注意下身份认证中 SimpleAuthenticationInfo 的四个参数

     

    principal 和 realmName相当于创建了一个 SimplePrincipalCollection ,并在其中的 realmPrincipals中添加了key是realmName value是principal 

    hashedCredentials 是用来判断密码的正确性 , credentialsSalt是为了确保在密码一致的情况下还可以进行唯一性验证(比如admin和test的密码都是123,如何确定当前的密码123是admin还是test就是靠credentialsSalt)

    我们再来看下继承类AuthorizingRealm 的配置

    还可以进行配置credentialsMatcher(用于进行密码加密),authenticationCache(缓存)

    credentialsMatcher是个借口看下他的实现

    我们可以使用 HashedCredentialsMatcher 

    配置一个bean

    配置到自定义realm里面

    我们的自定义realm就完成了,然后把realm注册到SecurityManager,把SecurityManager注入到ShiroFilterFactoryBean,我们的shiro就配置完成了

        @Bean
        public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
            System.out.println("ShiroConfiguration.shirFilter()");
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
            shiroFilterFactoryBean.setSecurityManager(securityManager);
            //拦截器.
            Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
            // 配置不会被拦截的链接 顺序判断
            filterChainDefinitionMap.put("/static/**", "anon");
            //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
            filterChainDefinitionMap.put("/logout", "logout");
            //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
            //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
            filterChainDefinitionMap.put("/**", "authc");
            // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
            shiroFilterFactoryBean.setLoginUrl("/login");
            // 登录成功后要跳转的链接
            shiroFilterFactoryBean.setSuccessUrl("/index");
    
            Map<String, Filter> filters = new LinkedHashMap<>();
        filters.put("authc",FormAuthenticationFilter());
    
            //未授权界面;
            shiroFilterFactoryBean.setUnauthorizedUrl("/403");
            shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        shiroFilterFactoryBean.setFilters(filters);
            return shiroFilterFactoryBean;
        }
    
        @Bean
        public SecurityManager securityManager(){
            DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
            securityManager.setRealm(myShiroRealm());
            return securityManager;
        }

     

  • 相关阅读:
    Zookeeper数据类型
    Zookeeper基本命令
    Redis集群
    Mysql 模拟自增主键
    git回滚版本操作
    Redis缓存穿透和雪崩
    日期格式jackson格式化
    Zookeeper安装
    redis主从复制
    Redis哨兵模式
  • 原文地址:https://www.cnblogs.com/lu-wei/p/8650677.html
Copyright © 2020-2023  润新知