zoukankan      html  css  js  c++  java
  • Spring Shiro 入门必看

    Shiro简介:Shiro是一个强大的简单易用的Java安全框架,主要用来更便捷的认证,授权,加密,会话管理。Shiro首要的和最重要的目标就是容易使用并且容易理解,通过Shiro易于理解的API,您可以快速、轻松地获得任何应用程序——从最小的移动应用程序最大的网络和企业应用程序。

    Shiro架构图

    • Authentication:身份认证/登录

    • Authorization:验证权限,即,验证某个人是否有做某件事的权限。

    • Session Management:会话管理。管理用户特定的会话,支持web,非web,ejb。

    • Cryptography: 加密,保证数据安全。

    • 其他特性。

    • Web Support:web支持,更容易继承web应用。

    • Caching:缓存

    • Concurrency :多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;

    • Testing:提供测试支持。

    • Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;

    • Remember Me:记住我,即记住登录状态,一次登录后,下次再来的话不用登录了 

    Shiro的架构有三个主要概念:SubjectSecurityManager 和 Realms。下图是一个高级的概述这些组件如何交互,下面我们将讨论每一个概念:

    Subject: 当前参与应用安全部分的主角。可以是用户,可以试第三方服务,可以是cron 任务,或者任何东西。主要指一个正在与当前软件交互的东西。所有Subject都需要SecurityManager,当你与Subject进行交互,这些交互行为实际上被转换为与SecurityManager的交互。

    SecurityManager:安全管理员,Shiro架构的核心,它就像Shiro内部所有原件的保护伞。然而一旦配置了SecurityManager,SecurityManager就用到的比较少,开发者大部分时间都花在Subject上面。当你与Subject进行交互的时候,实际上是SecurityManager在背后帮你举起Subject来做一些安全操作。

    Realms: Realms作为Shiro和你的应用的连接桥,当需要与安全数据交互的时候,像用户账户,或者访问控制,Shiro就从一个或多个Realms中查找。Shiro提供了一些可以直接使用的Realms,如果默认的Realms不能满足你的需求,你也可以定制自己的Realms。

    Shiro详细架构图

    The following diagram shows Shiro’s core architectural concepts followed by short summaries of each:

    Subject

        与应用交互的主体,例如用户,第三方应用等。
    SecurityManager
        SecurityManager是shiro的核心,负责整合所有的组件,使他们能够方便快捷完成某项功能。例如:身份验证,权限验证等。
    Authenticator
         认证器,负责主体认证的,这是一个扩展点,如果用户觉得Shiro默认的不好,可以自定义实现;其需要认证策略(Authentication Strategy),即什么情况下算用户认证通过了。
    Authorizer
          来决定主体是否有权限进行相应的操作;即控制着用户能访问应用中的哪些功能。
    SessionManager
         会话管理。
    SessionDAO
      数据访问对象,对session进行CRUD。
    CacheManager
         缓存管理器。创建和管理缓存,为 authentication, authorization 和 session management 提供缓存数据,避免直接访问数据库,提高效率。
    Cryptography
         密码模块,提供加密组件。
    Realms
          可以有1个或多个Realm,可以认为是安全实体数据源,即用于获取安全实体的;可以是JDBC实现,也可以是LDAP实现,或者内存实现等等;由用户提 供;注意:Shiro不知道你的用户/权限存储在哪及以何种格式存储;所以我们一般在应用中都需要实现自己的Realm。

    第一个Apache Shiro应用

    1.在pom.xml文件中添加Apache Shiro的依赖

    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.1.0</version>
    </dependency>
    <!-- Shiro uses SLF4J for logging. -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.6.1</version>
        <scope>test</scope>
    </dependency> 
     

    2.Shiro提供了一个通用的方案通过 INI 进行配置 ,当然也可以通过XML,YMAL,JSON等进行配置。
    在resource目录下面,创建一个shiro.ini的文件。内容如下:

    src/main/resources/shiro.ini

    # =============================================================================
    # Tutorial INI configuration
    #
    # Usernames/passwords are based on the classic Mel Brooks' film "Spaceballs" :)
    # =============================================================================
    
    # -----------------------------------------------------------------------------
    # Users and their (optional) assigned roles
    # username = password, role1, role2, ..., roleN
    # -----------------------------------------------------------------------------
    [users]
    root = secret, admin
    guest = guest, guest
    presidentskroob = 12345, president
    darkhelmet = ludicrousspeed, darklord, schwartz
    lonestarr = vespa, goodguy, schwartz
    
    # -----------------------------------------------------------------------------
    # Roles with assigned permissions
    # roleName = perm1, perm2, ..., permN
    # -----------------------------------------------------------------------------
    [roles]
    admin = *
    schwartz = lightsaber:*
    goodguy = winnebago:drive:eagle5
    

      

    引用Shiro.ini配置进行测试

    现在改变我们的Tutorial类文件,内容如下

    Final src/main/java/Tutorial.java

    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.config.IniSecurityManagerFactory;
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.session.Session;
    import org.apache.shiro.subject.Subject;
    import org.apache.shiro.util.Factory;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class Tutorial {
    
        private static final transient Logger log = LoggerFactory.getLogger(Tutorial.class);
    
        public static void main(String[] args) {
            log.info("My First Apache Shiro Application");
    
            Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
            SecurityManager securityManager = factory.getInstance();
            SecurityUtils.setSecurityManager(securityManager);
    
            // get the currently executing user:
            Subject currentUser = SecurityUtils.getSubject();
    
            // Do some stuff with a Session (no need for a web or EJB container!!!)
            Session session = currentUser.getSession();
            session.setAttribute("someKey", "aValue");
            String value = (String) session.getAttribute("someKey");
            if (value.equals("aValue")) {
                log.info("Retrieved the correct value! [" + value + "]");
            }
    
            // let's login the current user so we can check against roles and permissions:
            if (!currentUser.isAuthenticated()) {
                UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
                token.setRememberMe(true);
                try {
                    currentUser.login(token);
                } catch (UnknownAccountException uae) {
                    log.info("There is no user with username of " + token.getPrincipal());
                } catch (IncorrectCredentialsException ice) {
                    log.info("Password for account " + token.getPrincipal() + " was incorrect!");
                } catch (LockedAccountException lae) {
                    log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                            "Please contact your administrator to unlock it.");
                }
                // ... catch more exceptions here (maybe custom ones specific to your application?
                catch (AuthenticationException ae) {
                    //unexpected condition?  error?
                }
            }
    
            //say who they are:
            //print their identifying principal (in this case, a username):
            log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
    
            //test a role:
            if (currentUser.hasRole("schwartz")) {
                log.info("May the Schwartz be with you!");
            } else {
                log.info("Hello, mere mortal.");
            }
    
            //test a typed permission (not instance-level)
            if (currentUser.isPermitted("lightsaber:weild")) {
                log.info("You may use a lightsaber ring.  Use it wisely.");
            } else {
                log.info("Sorry, lightsaber rings are for schwartz masters only.");
            }
    
            //a (very powerful) Instance Level permission:
            if (currentUser.isPermitted("winnebago:drive:eagle5")) {
                log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'.  " +
                        "Here are the keys - have fun!");
            } else {
                log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
            }
    
            //all done - log out!
            currentUser.logout();
    
            System.exit(0);
        }
    }

     总结

    希望这个介绍教程帮助您理解如何在一个基本的应用程序设置Shiro Shiro的主要设计概念、主体和SecurityManager。

    但这是一个相当简单的应用程序。你可能会问自己,“如果我不想使用INI用户帐号,而想要连接到一个更复杂的用户数据来源?”

    回答这个问题需要一个小Shiro的架构的深入了解和支持配置机制。接下来我们将介绍Shiro的架构,请拭目以待吧!

    翻译自Apache Shiro 官方文档

    --------------少年不努力,长大搞程序。欢迎关注,如有错误,恳请指正。
  • 相关阅读:
    MySQL 一次非常有意思的SQL优化经历:从30248.271s到0.001s
    Oracle 11g 自动收集统计信息
    C# 获取当前方法的名称空间、类名和方法名称
    C# 数值的隐式转换
    C# using 三种使用方式
    C#、Unity 数据类型的默认值
    Unity for VsCode
    C# Lambda
    git push以后GitHub上文件夹灰色 不可点击
    C#保留小数
  • 原文地址:https://www.cnblogs.com/oycyqr/p/9465011.html
Copyright © 2011-2022 走看看