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散列算法。html

   

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 shiro的使用web

  一、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) ");
        //一、獲取用戶信息
        SysUser sysUser = sysUserDao.findUserByUsername(principals.toString());
        System.out.println(sysUser.toString());
        //二、獲取用戶權限
        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);
            }
        }
        //三、返回封裝的用戶權限信息
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setStringPermissions(permissions);
        //四、將受權信息返回給受權管理器
        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

  二、使用md5 對密碼進行加密spring

//使用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對密碼進行加密

  三、登錄業務的處理數據庫

public void login(String username, String password) {
        //0、參數合法性驗證
        if(username==null || "".equals(username))
            throw new ServiceException("用戶名不能爲空");
        if(password==null || "".equals(password))
            throw new ServiceException("密碼不能爲空");
        //一、獲取Subject(主體)對象
        Subject subject = SecurityUtils.getSubject();
        //二、封裝用戶名和密碼
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
        //三、執行身份驗證
        try {
            subject.login(token);
        }catch (UnknownAccountException e) {
            throw new ServiceException("認證失敗:當前用戶已被禁用!");
        } catch (AuthenticationException e) {
            e.printStackTrace();
            throw new ServiceException("認證失敗:用戶名或密碼不正確!");
        }
        //四、記錄用戶的session
        SecurityUtils.getSubject().getSession().setAttribute("user", username);
    }
執行用戶登錄業務

  四、spring整合shiro配置apache

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

 

權限控制方式spring-mvc

  可在方法前加註解:緩存

    @RequiresPermissions("sys:role:roleUI")安全

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

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

相關文章
相關標籤/搜索