大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節(jié)點(diǎn)LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 hot資訊 Shiro安全框架入門使用

Shiro安全框架入門使用

更新時(shí)間:2021-07-29 16:54:07 來源:動力節(jié)點(diǎn) 瀏覽1160次

Apache Shiro是一個(gè)強(qiáng)大且易用的Java安全框架,執(zhí)行身份驗(yàn)證、授權(quán)、密碼學(xué)和會話管理。使用Shiro的易于理解的API,您可以快速、輕松地獲得任

何應(yīng)用程序,從最小的移動應(yīng)用程序到最大的網(wǎng)絡(luò)和企業(yè)應(yīng)用程序。

Shrio的主要功能:

  • Authentication:用戶認(rèn)證(登錄)
  • Authorization:權(quán)限控制
  • Session Management:會話管理
  • Cryptography:數(shù)據(jù)加密
  • Web Support:支持web的API
  • Caching:緩存
  • Concurrency:支持多線程應(yīng)用程序
  • Testing:測試的支持
  • “Run As”:假設(shè)一個(gè)用戶為另一個(gè)用戶的身份
  • “Remember Me”:在Session中保存用戶身份

基本原理

Shiro的基本架構(gòu):

Shiro有三個(gè)核心的概念:Subject、SecurityManager和Realms。

  • Subject:Subject實(shí)質(zhì)上是一個(gè)當(dāng)前執(zhí)行用戶的特定的安全“視圖”,開發(fā)者所寫的應(yīng)用代碼就通過Subject與Shiro框架進(jìn)行交互。所有Subject實(shí)例都必須綁定到一個(gè)SecurityManager上,當(dāng)使用一個(gè)Subject實(shí)例時(shí),Subject實(shí)例會和SecurityManager進(jìn)行交互,完成相應(yīng)操作。
  • SecurityManager:SecurityManager是Shiro的核心部分,作為一種“保護(hù)傘”對象來協(xié)調(diào)內(nèi)部安全組件共同構(gòu)成一個(gè)對象圖。開發(fā)人員并不直接操作SecurityManager,而是通過Subject來操作SecurityManager來完成各種安全相關(guān)操作。
  • Realms:Realms擔(dān)當(dāng)Shiro和應(yīng)用程序的安全數(shù)據(jù)之間的“橋梁”或“連接器”。從本質(zhì)來講,Realm是一個(gè)特定安全的DAO,Realm中封裝了數(shù)據(jù)操作的模塊和用戶自定義的認(rèn)證匹配過程。SecurityManager可能配置多個(gè)Realms,但至少要有一個(gè)。

使用方法

注:該示例基于一個(gè)Maven管理的SSH項(xiàng)目

1.在Maven中添加Shiro依賴

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-all</artifactId>
    <version>1.2.3</version>
</dependency>

 

注:Shiro官方現(xiàn)在不推薦這種用法,因?yàn)榭赡軙?dǎo)致Maven運(yùn)行錯(cuò)誤

2.在web.xml添加核心過濾器,且必須放在Struts2核心過濾器前面

<filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

3.在Spring配置文件中添加如下代碼,且放在事務(wù)管理器之前

<!--Shiro安全框架產(chǎn)生代理子類的方式: 使用cglib方式,放在事務(wù)管理器之前-->
<aop:aspectj-autoproxy proxy-target-class="true" />

4.在Spring配置文件中配置Shiro,建議單獨(dú)出一個(gè)applicationContext-shiro.xml進(jìn)行配置(編寫完成后記得在總的配置文件中引入該配置文件)

applicationContext-shiro.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans    
    http://www.springframework.org/schema/beans/spring-beans.xsd    
    http://www.springframework.org/schema/aop    
    http://www.springframework.org/schema/aop/spring-aop.xsd    
    http://www.springframework.org/schema/tx    
    http://www.springframework.org/schema/tx/spring-tx.xsd    
    http://www.springframework.org/schema/context    
    http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- SecurityManager配置 -->
    <!-- 配置Realm域 -->
    <!-- 密碼比較器 -->
    <!-- 配置緩存:ehcache緩存 -->

    <!-- 安全管理 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!-- 引用自定義的realm -->
        <property name="realm" ref="authRealm"/>
        <!-- 緩存 -->
        <property name="cacheManager" ref="shiroEhcacheManager"/>
    </bean>

    <!-- 自定義權(quán)限認(rèn)證 -->
    <bean id="authRealm" class="com.songzheng.demo.shiro.AuthRealm">
        <property name="userService" ref="userService"/>
        <!-- 自定義密碼加密算法  -->
        <property name="credentialsMatcher" ref="passwordMatcher"/>
    </bean>

    <!-- 設(shè)置密碼加密策略 md5hash -->
    <bean id="passwordMatcher" class="com.songzheng.demo.shiro.DemoCredentialsMatcher"/>

    <!-- filter-name這個(gè)名字的值來自于web.xml中filter的名字 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <!--登錄頁面  -->
        <property name="loginUrl" value="/index.jsp"></property>
        <!-- 登錄成功后 -->      
        <property name="successUrl" value="/home.action"></property>
        <property name="filterChainDefinitions">
            <!-- /**代表下面的多級目錄也過濾 -->
            <value>
                /index.jsp* = anon
                /home* = anon
                /sysadmin/login/login.jsp* = anon
                /sysadmin/login/logout.jsp* = anon
                /login* = anon
                /logout* = anon
                /components/** = anon
                /css/** = anon
                /images/** = anon
                /js/** = anon
                /make/** = anon
                /skin/** = anon
                /stat/** = anon
                /ufiles/** = anon
                /validator/** = anon
                /resource/** = anon
                /** = authc
                /*.* = authc
            </value>
        </property>
    </bean>

    <!-- 用戶授權(quán)/認(rèn)證信息Cache, 采用EhCache  緩存 -->
    <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/>
    </bean>

    <!-- 保證實(shí)現(xiàn)了Shiro內(nèi)部lifecycle函數(shù)的bean執(zhí)行 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

    <!-- 生成代理,通過代理進(jìn)行控制 -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
          depends-on="lifecycleBeanPostProcessor">
        <property name="proxyTargetClass" value="true"/>
    </bean>

    <!-- 安全管理器 -->
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>

</beans>

在這里配置了核心的SecurityManager,SecurityManager中注入了realm和cacheManager,因此需要配置realm和cacheManager,Realm是自定義的,其中注入了userService,用來進(jìn)行查詢數(shù)據(jù)庫數(shù)據(jù)的相關(guān)操作,還注入了credentialsMatcher屬性,這個(gè)是開發(fā)者自定義的比較器。配置CacheManager時(shí),使用了ehcache,在最后也進(jìn)行了配置,并且編寫了ehcache的配置文件,這些操作在下述步驟進(jìn)行。

在shiroFilter的配置中配置了要過濾的目錄,其中一個(gè)*號表示匹配當(dāng)前目錄后的參數(shù),兩個(gè)*號表示匹配該目錄及其子目錄及參數(shù)。等號后面是Shiro各類過濾器的簡稱,anon表示匿名過濾器,表示可以匿名訪問這些資源,authc表示需要驗(yàn)證用戶身份才能訪問,還有8種過濾器,在此就不再詳述了。

5.Ehcache的配置文件

ehcache-shiro.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" name="shiroCache">

    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="false"
        diskPersistent="false"
        diskExpiryThreadIntervalSeconds="120"/>

</ehcache>

6.編寫自定義的credentialsMatcher

DemoCredentialsMatcher.java

public class DemoCredentialsMatcher extends SimpleCredentialsMatcher {

    /**
     * 密碼比較的規(guī)則
     * token:用戶在界面輸入的用戶名和密碼
     * info: 從數(shù)據(jù)庫中得到的加密數(shù)據(jù)
     */
    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        // 獲取用戶輸入的密碼,并加密
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String md5Pwd = Encrypt.md5(new String(upToken.getPassword()), upToken.getUsername());

        // 獲取數(shù)據(jù)庫中的加密密碼
        String pwd = (String) info.getCredentials();

        // 返回比較結(jié)果
        return this.equals(md5Pwd, pwd);
    }

}

Encrypt是一個(gè)進(jìn)行MD5加密的工具類

Encrypt.java

public class Encrypt {
    public static String md5(String password, String salt) {
        return new Md5Hash(password, salt, 2).toString();
    }
}

7.編寫自定義的realm

AuthRealm.java

public class AuthRealm extends AuthorizingRealm {

    private IUserService userService;

    public void setUserService(IUserService userService) {
        this.userService = userService;
    }

    /**
     * 授權(quán),當(dāng)jsp頁面遇到shiro標(biāo)簽會執(zhí)行該方法
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
        System.out.println("授權(quán)");
        User user = (User) pc.fromRealm(this.getName()).iterator().next();  // 根據(jù)realm名字找到對應(yīng)的realm

        List<String> permissions = new ArrayList<String>();

        Set<Role> roles = user.getRoles();
        for (Role role : roles) {
            Set<Module> modules = role.getModules();
            for (Module module : modules) {
                permissions.add(module.getName());
            }
        }

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermissions(permissions);     // 添加用戶的權(quán)限

        return info;
    }

    /**
     * 認(rèn)證
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("認(rèn)證");
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;

        List<User> list = userService.find("from User u where u.userName = ?", User.class, new String[]{upToken.getUsername()});

        if (list != null && list.size() > 0) {
            User user = list.get(0);
            AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
            return info;
        }

        return null;    // 返回null拋出異常
    }

}

8.登錄操作

try {
    // 1、得到Subject
    Subject subject = SecurityUtils.getSubject();

    // 2、調(diào)用登錄方法---AuthRealm#doGetAuthenticationInfo()
    subject.login(new UsernamePasswordToken(username, password));

    // 3、登錄成功
    User user = (User) subject.getPrincipal();

    // 4、放入session
    session.put(SysConstant.CURRENT_USER_INFO, user);
} catch (Exception e) {
    e.printStackTrace();
    request.put("errorInfo", "用戶名或密碼錯(cuò)誤!");
    return "login";
}

return SUCCESS;

在Shiro框架中,如果登陸失敗,則會拋出異常,所有在使用Subject的代碼外要使用try-catch,當(dāng)捕獲異常,表示用戶身份驗(yàn)證失敗。

以上就是動力節(jié)點(diǎn)小編介紹的"Shiro安全框架入門使用",希望對大家有幫助,想了解更多可查看Shiro視頻教程。動力節(jié)點(diǎn)在線學(xué)習(xí)教程,針對沒有任何Java基礎(chǔ)的讀者學(xué)習(xí),讓你從入門到精通,主要介紹了一些Java基礎(chǔ)的核心知識,讓同學(xué)們更好更方便的學(xué)習(xí)和了解Java編程,感興趣的同學(xué)可以關(guān)注一下。

提交申請后,顧問老師會電話與您溝通安排學(xué)習(xí)

免費(fèi)課程推薦 >>
技術(shù)文檔推薦 >>
主站蜘蛛池模板: 中文字幕在亚洲第一在线 | 日韩第一页在线 | 成人国内精品久久久久影 | 精品亚洲一区二区在线播放 | 欧洲美女高清一级毛片 | 精品一成人岛国片在线观看 | 国产大尺度福利视频在线观看 | 女人一级一级毛片 | 国产精品亚洲一区二区在线观看 | 免费毛片播放 | 国产成人免费视频精品一区二区 | 成人国产精品免费网站 | 国产成人精品一区二区视频 | sea8国产精品视频 | 日本黄色mv | 亚洲午夜久久久久国产 | 五月激情婷婷综合 | 天堂va亚洲va欧美va国产 | 欧美综合中文字幕久久 | 国产aa免费视频 | 久久亚洲精品一区二区三区浴池 | 四虎 2022 永久网站 | 亚洲网在线观看 | 国产精品99久久久久久夜夜嗨 | 久久国产经典视频 | 九九热在线免费 | 国产免费三a在线 | 亚洲视频www | 一级毛片在线看在线播放 | 国产一级aaa全黄毛片 | 久久久久毛片免费观看 | 香蕉蕉亚亚洲aav综合 | 欧美亚洲国产成人高清在线 | 四虎网站最新地址 | 老子影院午夜久久亚洲 | 麻豆成人久久精品二区三 | 欧美日韩亚洲国产精品 | 久久伊人中文字幕 | xxxx免费国产在线视频 | 国产极品粉嫩福利在线观看 | 国产毛片儿|