zoukankan      html  css  js  c++  java
  • shiro

    shiro架构图

    subject 主体,可以是用户也可以是程序,主体要访问系统,系统需要对主体进行认证、授权。
    securityManager 安全管理器,主体进行认证和授权都 是通过securityManager进行。它包含下面的认证器和授权器。
     authorizer  授权器,主体进行授权最终通过authorizer进行的。
     authenticator  认证器,主体进行认证最终通过authenticator进行的。 
     sessionManager  web应用中一般是用web容器对session进行管理,shiro也提供一套session管理的方式。可以实现单点登录。
     SessionDao  通过SessionDao管理session数据,针对个性化的session数据存储需要使用sessionDao。
     cache Manager  缓存管理器,主要对session和授权数据进行缓存,比如将授权数据通过cacheManager进行缓存管理,和ehcache整合对缓存数据进行管理。
     realm  域,领域,相当于数据源,通过realm存取认证、授权相关数据。(它的主要目的是与数据库打交道,查询数据库中的认证的信息(比如用户名和密码),查询授权的信息(比如权限的code等,所以这里可以理解为调用数据库查询一系列的信息,一般情况下在项目中采用自定义的realm,因为不同的业务需求不一样))
     cryptography  密码管理,提供了一套加密/解密的组件,方便开发。比如提供常用的散列、加/解密等功能。

    比如 md5散列算法。

       

     shiro的使用

      1、realm类的编写

    package com.jt.sys.service.realms;
    
    import com.alibaba.druid.util.StringUtils;
    
    public class ShiroUserRealm extends AuthorizingRealm {
        @Autowired
        private SysUserDao sysUserDao;
        /**
         * 获取授权信息
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            System.out.println("--doGetAuthorizationInfo(PrincipalCollection principals) ");
            //1、获取用户信息
            SysUser sysUser = sysUserDao.findUserByUsername(principals.toString());
            System.out.println(sysUser.toString());
            //2、获取用户权限
            List<String> list = sysUserDao.findUserPermissions(sysUser.getId());
            if(list==null)return null;
            Set<String> permissions = new HashSet<String>();
            for(String permission : list){
                if(!StringUtils.isEmpty(permission)){
                    permissions.add(permission);
                }
            }
            //3、返回封装的用户权限信息
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            info.setStringPermissions(permissions);
            //4、将授权信息返回给授权管理器
            return info;
        }
        
        /**
         * 获取认证信息
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            UsernamePasswordToken userToken = (UsernamePasswordToken)token;
            String username = userToken.getUsername();
            SysUser user = sysUserDao.findUserByUsername(username);
            if(user.getValid()==null || !"1".equals(user.getValid())){
                return null;
            }
            ByteSource salt = ByteSource.Util.bytes(user.getSalt());
            AuthenticationInfo ai = new SimpleAuthenticationInfo(username,user.getPassword(),salt,getName());
            //将认证信息返回给认证管理器
            return ai;
        }
    }
    class ShiroUserRealm extends AuthorizingRealm

      2、使用md5 对密码进行加密

    //使用md5对密码进行加密
            String salt = UUID.randomUUID().toString();
            String password = sysUser.getPassword();
            SimpleHash sHash = new SimpleHash("MD5",password,salt);
            String newPwd = sHash.toString();
            sysUser.setSalt(salt);
            sysUser.setPassword(newPwd);
    使用md5对密码进行加密

      3、登陆业务的处理

    public void login(String username, String password) {
            //0、参数合法性验证
            if(username==null || "".equals(username))
                throw new ServiceException("用户名不能为空");
            if(password==null || "".equals(password))
                throw new ServiceException("密码不能为空");
            //1、获取Subject(主体)对象
            Subject subject = SecurityUtils.getSubject();
            //2、封装用户名和密码
            UsernamePasswordToken token = new UsernamePasswordToken(username,password);
            //3、执行身份验证
            try {
                subject.login(token);
            }catch (UnknownAccountException e) {
                throw new ServiceException("认证失败:当前用户已被禁用!");
            } catch (AuthenticationException e) {
                e.printStackTrace();
                throw new ServiceException("认证失败:用户名或密码不正确!");
            }
            //4、记录用户的session
            SecurityUtils.getSubject().getSession().setAttribute("user", username);
        }
    执行用户登陆业务

      4、spring整合shiro配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans default-lazy-init="true"
        xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util"
        xmlns:jpa="http://www.springframework.org/schema/data/jpa"
        xsi:schemaLocation="  
           http://www.springframework.org/schema/beans   
           http://www.springframework.org/schema/beans/spring-beans-4.3.xsd  
           http://www.springframework.org/schema/mvc   
           http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd   
           http://www.springframework.org/schema/tx   
           http://www.springframework.org/schema/tx/spring-tx-4.3.xsd   
           http://www.springframework.org/schema/aop 
           http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
           http://www.springframework.org/schema/util 
           http://www.springframework.org/schema/util/spring-util-4.3.xsd
           http://www.springframework.org/schema/data/jpa 
           http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-4.3.xsd">
    
        <!-- 整合shiro配置 -->
        <!-- 配置shiro安全管理器 -->
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="rememberMeManager" ref="remeberManager" />
            <property name="cacheManager" ref="cacheManager"/>
            <property name="realm" ref="shiroUserRealm" />
        </bean>
        
        <!-- spring整合配置ehcache缓存 -->
          <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
            <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/> 
        </bean>
        
        <!-- 配置 -->
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <!-- shiro的核心安全接口 -->
            <property name="securityManager" ref="securityManager" />
            <!-- 要求登录时的连接 -->
            <property name="loginUrl" value="/loginUI.do"></property>
            <!-- 登录成功后要跳转的连接(此处已经在登录中处理了) -->
            <!-- <property name="successUrl" value="/index.jsp"></property> -->
            <!-- 访问未对其授权的资源时,要跳转的连接 <property name="unauthorizedUrl" value="/default.html"></property> -->
            <!-- shiro连接约束配置 -->
            <property name="filterChainDefinitions">
                <value>
                    <!-- 对静态资源设置允许匿名访问 -->
                    /bower_components/** = anon
                    /build/** = anon
                    /dist/** = anon
                    /plugins/** = anon
                    /doLogin.do = anon
                    <!-- 退出 -->
                    /logout.do = logout  <!-- 会调用Subject的logout方法,此方法会将session清空 -->
                    <!-- 剩余其他路径,必须认证通过才可以访问 -->
                    /** = authc
                </value>
            </property>
        </bean>
        
        <!-- 自定义Realm -->
        <bean id="shiroUserRealm" class="com.jt.sys.service.realms.ShiroUserRealm">
            <!-- 配置凭证算法匹配器 -->
            <property name="credentialsMatcher">
                <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                    <property name="hashAlgorithmName" value="MD5" />
                    <!-- <property name="hashIterations" value="1024"/> -->
                </bean>
            </property>
        </bean>
        <!--Shiro生命周期处理器 -->
        <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
    
        <!--启用shiro注解权限检查 -->
        <bean
            class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
            depends-on="lifecycleBeanPostProcessor" />
        <bean
            class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
            <property name="securityManager" ref="securityManager" />
        </bean>
        
        <!-- 记住我配置 -->
        <bean id="remeberManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
            <property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}" /> 
            <property name="cookie" ref="remeberMeCookie" />
        </bean>
        
        <!-- 记住我cookie -->
        <bean id="remeberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
            <constructor-arg value="remeberMe" />
            <property name="path" value="/" />
            <property name="httpOnly" value="true"/>
            <property name="maxAge" value="604800" />
        </bean>
        
        
        
        
    </beans>
    spring-shiro.xml

    权限控制方式

      可在方法前加注解:

        @RequiresPermissions("sys:role:roleUI")

        @RequiresPermissions(value = {"sys:role:update","sys:role:add"},logical=Logical.OR)

        @RequiresPermissions(value = {"sys:role:update","sys:role:add"},logical=Logical.AND)

  • 相关阅读:
    画册制作须知
    名片设计尺寸及名片设计的注意事项
    鼠标指到图片上会向上移动
    css3 实现鼠标放到一个div上显示出另一个隐藏的div
    React Native的原生路由
    React中input checked的使用
    Webpack打包React踩到的坑
    Linux下git的配置
    js变量提升的一个小坑
    SpringMVC中传入的对象存放在哪里
  • 原文地址:https://www.cnblogs.com/xiangyuqi/p/8611714.html
Copyright © 2011-2022 走看看