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

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

Shiro安全框架入門使用

更新時間:2021-07-29 16:54:07 來源:動力節點 瀏覽1072次

Apache Shiro是一個強大且易用的Java安全框架,執行身份驗證、授權、密碼學和會話管理。使用Shiro的易于理解的API,您可以快速、輕松地獲得任

何應用程序,從最小的移動應用程序到最大的網絡和企業應用程序。

Shrio的主要功能:

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

基本原理

Shiro的基本架構:

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

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

使用方法

注:該示例基于一個Maven管理的SSH項目

1.在Maven中添加Shiro依賴

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

 

注:Shiro官方現在不推薦這種用法,因為可能會導致Maven運行錯誤

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配置文件中添加如下代碼,且放在事務管理器之前

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

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

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>

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

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

    <!-- filter-name這個名字的值來自于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>

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

    <!-- 保證實現了Shiro內部lifecycle函數的bean執行 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

    <!-- 生成代理,通過代理進行控制 -->
    <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,用來進行查詢數據庫數據的相關操作,還注入了credentialsMatcher屬性,這個是開發者自定義的比較器。配置CacheManager時,使用了ehcache,在最后也進行了配置,并且編寫了ehcache的配置文件,這些操作在下述步驟進行。

在shiroFilter的配置中配置了要過濾的目錄,其中一個*號表示匹配當前目錄后的參數,兩個*號表示匹配該目錄及其子目錄及參數。等號后面是Shiro各類過濾器的簡稱,anon表示匿名過濾器,表示可以匿名訪問這些資源,authc表示需要驗證用戶身份才能訪問,還有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 {

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

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

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

}

Encrypt是一個進行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;
    }

    /**
     * 授權,當jsp頁面遇到shiro標簽會執行該方法
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
        System.out.println("授權");
        User user = (User) pc.fromRealm(this.getName()).iterator().next();  // 根據realm名字找到對應的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);     // 添加用戶的權限

        return info;
    }

    /**
     * 認證
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("認證");
        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、調用登錄方法---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", "用戶名或密碼錯誤!");
    return "login";
}

return SUCCESS;

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

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

提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 久久久久久久国产精品视频 | 婷婷综合久久中文字幕一本 | 亚洲精品欧洲一区二区三区 | 四虎影视在线观看永久地址 | freesex寂寞老妇hd | 国产区精品一区二区不卡中文 | 亚洲欧美人成综合在线最新 | 成人爽a毛片在线视频 | 欧美激情毛片 | 成人私人影院www片免费高清 | 欧美顶级毛片在线播放 | 国自产拍在线视频天天更新 | 91久久国产 | 欧美精品亚洲精品日韩专区 | 久久国产一片免费观看 | 中文字幕婷婷 | 成人欧美视频在线看免费 | 四虎免费大片aⅴ入口 | 国产一区二区三区四区在线 | 伊人网综合在线观看 | 亚洲成人综合视频 | 久久亚洲国产欧洲精品一 | 日日爽天天干 | 精品外国呦系列在线观看 | 99热国产| 免费爱爱网站 | 99热免费在线 | 国产片久久 | 久久这里| 亚洲免费美女视频 | 伊人热人久久中文字幕 | a毛片免费全部在线播放毛 a毛片免费在线观看 | 久久精品国产精品亚洲艾 | 熊出没之重启未来免费观看 | 成人性色大片 | 久久网欧美 | 久久精品成人一区二区三区 | 中国毛片免费看 | 手机看片福利盒子久久青 | 在线观看国产一区亚洲bd | 色综合天天综合网看在线影院 |