必威-必威-欢迎您

必威,必威官网企业自成立以来,以策略先行,经营致胜,管理为本的商,业推广理念,一步一个脚印发展成为同类企业中经营范围最广,在行业内颇具影响力的企业。

只要看看他简单的API必威,从Shiro内部来看

2019-09-27 22:08 来源:未知

3.6 授权流程分析

必威 1

1、首先调用Subject.isPermitted*/hasRole*接口,其会委托给SecurityManager,而SecurityManager接着会委托给Authorizer

2、Authorizer是真正的授权者,如果我们调用如isPermitted(“user:view”),其首先会通过PermissionResolver把字符串转换成相应的Permission实例;

3、在进行授权之前,其会调用相应的Realm获取Subject相应的角色/权限用于匹配传入的角色/权限;

4、Authorizer会判断Realm的角色/权限是否和传入的匹配,如果有多个Realm,会委托给ModularRealmAuthorizer进行循环判断,如果匹配如isPermitted*/hasRole*会返回true,否则返回false表示授权失败。

五 ssm 和 shiro 整合

  1. 导入依赖
    2)配置 web.xml(shiro过滤器)
 <!-- shiro过滤器定义 -->
    <filter>  
        <filter-name>shiroFilter</filter-name>  
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
    <init-param>  
    <!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 -->  
    <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)编写自己的 Realm(一般权限都是从数据库中查找,所以需要自定义)

public class MyRealm extends AuthorizingRealm{

    @Resource
    private UserService userService;

    /**
     * 为当前登录的用户授予角色和权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //获取用户名
        String userName=(String)principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
        //进行授权角色
        authorizationInfo.setRoles(userService.getRoles(userName));
        //进行授权权限
        authorizationInfo.setStringPermissions(userService.getPermissions(userName));
        return authorizationInfo;
    }

    /**
     *验证当前登录的用户
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String userName=(String)token.getPrincipal();
        //根据用户名查找用户信息
            User user=userService.getByUserName(userName);
            if(user!=null){
                AuthenticationInfo authcInfo=new SimpleAuthenticationInfo(user.getUserName(),user.getPassword(),getName());
                return authcInfo;
            }else{
                return null;                
            }
    }
}
  1. spring 和 shiro 配置整合
...
<!-- 自定义Realm -->
    <bean id="myRealm" class="com.acey.realm.MyRealm"/>

    <!-- 安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
      <property name="realm" ref="myRealm"/>  
    </bean>  

    <!-- Shiro过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
        <!-- Shiro的核心安全接口,这个属性是必须的 -->  
        <property name="securityManager" ref="securityManager"/>
        <!-- 身份认证失败,则跳转到登录页面的配置 -->  
        <property name="loginUrl" value="/index.jsp"/>
        <!-- 权限认证失败,则跳转到指定页面 -->  
        <property name="unauthorizedUrl" value="/unauthor.jsp"/>  
        <!-- Shiro连接约束配置,即过滤链的定义 -->  
        <property name="filterChainDefinitions">  
            <value>  
                 /login=anon
                /admin*=authc
                /student=roles[teacher]
                /teacher=perms["user:create"]
            </value>  
        </property>
    </bean>  

    <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->  
    <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>  
...

一般角色和权限都存在数据库中,所以我们还可以自定义一个 filter 去自己验证每一个请求的 Subject 是否有权限去访问,这样我们就可以减少对过滤链的维护.比如

<!-- Shiro过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
        <!-- Shiro的核心安全接口,这个属性是必须的 -->  
        <property name="securityManager" ref="securityManager"/>
        <!-- 身份认证失败,则跳转到登录页面的配置 -->  
        <property name="loginUrl" value="/index.jsp"/>
        <!-- 权限认证失败,则跳转到指定页面 -->  
        <property name="unauthorizedUrl" value="/unauthor.jsp"/>  
        <!-- Shiro连接约束配置,即过滤链的定义 -->  
        <property name="filterChainDefinitions">  
            <value>  
                 /login=anon
                /admin*=authc
                /student=roles[teacher]
                /teacher=perms["user:create"]
            </value>  
        </property>
    </bean>  

可以改成

<!-- Shiro过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
        <!-- Shiro的核心安全接口,这个属性是必须的 -->  
        <property name="securityManager" ref="securityManager"/>
        <!-- 身份认证失败,则跳转到登录页面的配置 -->  
        <property name="loginUrl" value="/index.jsp"/>
        <!-- 权限认证失败,则跳转到指定页面 -->  
        <property name="unauthorizedUrl" value="/unauthor.jsp"/>  
        <property name="ownFilter" class="ownFilter.class">
        <!-- Shiro连接约束配置,即过滤链的定义 -->  
        <property name="filterChainDefinitions">  
            <value>  
                 /login=anon
               /**=ownFilter
            </value>  
        </property>
    </bean>  

待续! 欢迎大家拍砖

源码地址:ShirDemos

一、功能简介

  • Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
  • Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能进行什么操作,如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
  • Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境,也可以是 Web 环境的;
  • Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
  • Web Support:Web 支持,可以非常容易的集成到Web 环境;
  • Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可
    以提高效率;
  • Concurrency:Shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
  • Testing:提供测试支持;
  • Run As允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
  • Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。
1.1、模块介绍
  • Authentication:用户身份识别,可以认为是登录;
  • Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限。
  • Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境的,也可以是如 Web 环境的。
  • Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储。
  • Web Support:Web支持,可以非常容易的集成到 web 环境。
  • Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率。
  • Concurrency:shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去。
  • Testing:提供测试支持。
  • Run As:允许一个用户假装为另一个用户的身份进行访问。
  • Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。

注意:shiro不会去维护用户和权限之间的关系,需要我们自己去设计、提供;然后通过相应的接口注入给shiro即可。

Subject:主体,代表了当前操作“用户”,这个用户不一定是具体的人,与当前应用交互的任何东西都是subject,即一个抽象概念。所有Subject都绑定到SecurityManager,与Subject交互都会委托给SercurityManager;

SecurityManager:安全管理器;即所有与subject安全有关的操作都会与SecurityManager交互;且它管理着所有的Subject;它负责与里面的各个组件的交互,也可以把它理解成springmvc中的DispatcherServlet前端控制器。

Realm:域,安全数据源。shiro从Realm获取安全数据(如用户、权限、角色),就是说SecurityManager要验证用户身份,那么它需要从Realm得到用户相应的角色、权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。

必威 2image

从上图可以看出:

1、应用代码通过Subject来进行认证和授权,而Subject又委托给SecurityManager;

2、SecurityManager要验证用户身份,那么它需要从Realm中获取相对应的用户、角色、权限进行比较以确定用户身份是否合法。

总结:shiro不提供维护用户、权限,而是通过Realm让开发人员自己注入。

必威 3image必威 4image

  1. Subject:主体,可以看到主体可以是任何与应用交互的“用户”。

  2. SecurityManager:相当于 SpringMVC 中的 DispatcherServlet 或者 Struts2 中的FilterDispatcher。它是 Shiro 的核心,所有具体的交互都通过 SecurityManager 进行控制。它管理着所有 Subject、且负责进行认证和授权、及会话、缓存的管理。

  3. Authenticator:认证器,负责主体认证的,这是一个扩展点,如果用户觉得 Shiro 默认的不好,我们可以自定义实现。其需要认证策略(Authentication Strategy),即什么情况下算用户认证通过了。

  4. Authrizer:授权器,或者访问控制器。它用来决定主体是否有权限进行相应的操作,即控制着用户能访问应用中的哪些功能。

  5. Realm:可以有1个或多个 Realm,可以认为是安全实体数据源,即用于获取安全实体的。它可以是 JDBC 实现,也可以是 LDAP 实现,或者内存实现等。

  6. SessionManager:如果写过 Servlet 就应该知道 Session 的概念,Session 需要有人去管理它的生命周期,这个组件就是 SessionManager。而 Shiro 并不仅仅可以用在 Web 环境,也可以用在如普通的 JavaSE 环境。

  7. SessionDAO:DAO 大家都用过,数据访问对象,用于会话的 CRUD。我们可以自定义 SessionDAO 的实现,控制 session 存储的位置。如通过 JDBC 写到数据库或通过 jedis 写入 redis 中。另外 SessionDAO 中可以使用 Cache 进行缓存,以提高性能。

  8. CacheManager:缓存管理器。它来管理如用户、角色、权限等的缓存的。因为这些数据基本上很少去改变,放到缓存中后可以提高访问的性能。

  9. Cryptography:密码模块,Shiro 提高了一些常见的加密组件用于如密码加密/解密的。

当 Shiro 被运用到 web 项目时,Shiro 会自动创建一些默认的过滤器对客户端请求进行过滤。以下是 Shiro 提供的过滤器:

必威 5SO1.png

解释:

必威 6SO2.png注意:anon,authcBasic,auchc,user 是认证过滤器。

perms,roles,ssl,rest,port 是授权过滤器。

推荐阅读:

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

2.2.5 存在的问题

1、用户名/密码硬编码在ini配置文件,以后需要改成如数据库存储,且密码需要加密存储;

一 shiro 是什么

shiro 是一个功能强大和易于使用的Java安全框架,为开发人员提供一个直观而全面的解决方案的认证,授权,加密,会话管理。

1. shiro(外部来看)

  • 从外部来看Shiro ,即从应用程序角度的来观察如何使用 Shiro 完成

    工作:

    必威 7

    从外部来看shiro架构

  • Subject:应用代码直接交互的对象是 Subject,也就是说 Shiro 的对外API 核心就是 Subject。 Subject 代表了当前“用户”, 这个用户不一定是一个具体的人,与当前应用交互的任何东西都是 Subject,如网络爬虫,机器人等;与 Subject 的所有交互都会委托给 SecurityManager;
    Subject 其实是一个门面,SecurityManager 才是实际的执行者;

  • SecurityManager:安全管理器;即所有与安全有关的操作都会与
    SecurityManager 交互;
    且其管理着所有 Subject;可以看出它是 Shiro的核心,它负责与 Shiro 的其他组件进行交互,它相当于 SpringMVC 中DispatcherServlet 的角色
  • Realm:Shiro 从 Realm 获取安全数据(如用户、角色、权限),就是说SecurityManager 要验证用户身份,那么它需要从 Realm 获取相应的用户进行比较以确定用户身份是否合法;也需要从 Realm 得到用户相应的角色/权限进行验证用户是否能进行操作;可以把 Realm 看成DataSource

shiro是一个安全框架,是Apache的一个子项目。shiro提供了:认证、授权、加密、会话管理、与web集成、缓存等模块。

也就是说对于我们而言,最简单的一个Shiro应用:

1.5 从系统结构角度理解什么是权限管理?

简单理解下图流程:最上层代表其他程序,进来后,先进入Security Manager 进行授权或者认证(authenticator authorizer),而授权或者认证的数据是从最底层的DB中查询出来的,然后放到不同的realms中(realms中的这些值用来和程序中传入的数据(程序中传入的数据被封装成subject主题)进行比对。

必威 8

Subject:主体,可以看到主体可以是任何可以与应用交互的“用户”;

SecurityManager:相当于SpringMVC中的DispatcherServlet或者Struts2中的FilterDispatcher;是Shiro的心脏;所有具体的交互都通过SecurityManager进行控制;它管理着所有Subject、且负责进行认证和授权、及会话、缓存的管理。

Authenticator:认证器,负责主体认证的,这是一个扩展点,如果用户觉得Shiro默认的不好,可以自定义实现;其需要认证策略(Authentication Strategy),即什么情况下算用户认证通过了;

Authorizer:授权器,或者访问控制器,用来决定主体是否有权限进行相应的操作;即控制着用户能访问应用中的哪些功能;

Realm:可以有1个或多个Realm,可以认为是安全实体数据源,即用于获取安全实体的;可以是JDBC实现,也可以是LDAP实现,或者内存实现等等;由用户提供;注意:Shiro不知道你的用户/权限存储在哪及以何种格式存储;所以我们一般在应用中都需要实现自己的Realm;

SessionManager:如果写过Servlet就应该知道Session的概念,Session呢需要有人去管理它的生命周期,这个组件就是SessionManager;而Shiro并不仅仅可以用在Web环境,也可以用在如普通的JavaSE环境、EJB等环境;所有呢,Shiro就抽象了一个自己的Session来管理主体与应用之间交互的数据;可以实现分布式的会话管理;

SessionDAO:DAO大家都用过,数据访问对象,用于会话的CRUD,比如我们想把Session保存到数据库,那么可以实现自己的SessionDAO,通过如JDBC写到数据库;比如想把Session放到redis中,可以实现自己的redis SessionDAO;另外SessionDAO中可以使用Cache进行缓存,以提高性能;

CacheManager:缓存控制器,来管理如用户、角色、权限等的缓存的;因为这些数据基本上很少去改变,放到缓存中后可以提高访问的性能

Cryptography:密码模块,Shiro提高了一些常见的加密组件用于如密码加密/解密的。

四 shiro 的主要功能 - 授权

权限授权就是访问控制,在应用中控制谁能访问哪些资源

1 权限认证中的几个元素

  • 权限:即操作某个资源的权限,这些资源可以是某个链接,也可以是某个图片,也可以是对某个模块的数据的 CURL
  • 角色:即权限的集合,一个角色可以有多个权限
  • 用户:代表访问的用户,即  Subject

2 授权的流程

授权流程

  1. 当用户访问应用中的某个资源时,会被 SecurityManager 拦截.
  2. SecurityManager 会去调用 Authorizer(授权器)
  3. Authorizer 会根据 Subject 的身份去相应的 Realm 中去查找该 Subject 是否有权限去访问该资源

3 授权实现

  1. 导包
  2. 配置 permission(权限) resources/shiro_permission.ini
[main] 
authc.loginUrl=/login  //表示用户登录失败跳转到 /login
roles.unauthorrizedUrl=/unauthorrized.jsp //表示用户没有对应的访问角色跳转到/unauthorrized.jsp
perms.unauthorrizedUrl=/unauthorrized.jsp  //表示用户没有对应的访问权限跳转到/unauthorrized.jsp

[users]
acey=123456,role1,role2
jack=123,role1
[roles]
role1=user:select // role1 角色有访问 user:select 的权限
role2=user:add,/delete //role2 角色有访问 user:add 和 /delete 的权限

[urls]
/login=anon  //表示任何用户都可以访问 /login
/index=authc //表示只有身份认证通过的用户才可以访问 /index
/index=roles[role1,role2...] //表示只有用户含有 role1 role2 ... 角色才可以访问 /index
/index=perms["user:create","/update"]  //表示只有用户含有 "user:create" 
                      和"/update"权限才可以访问 /index 
/index?=authc //`?`通配符,表示一个字符,如/index1 /indexa /index- (不能匹配/index) ,
                      将符合这种规则的请求进行`authc`拦截
/index*=authc  `*`通配符,表示零个或一个或多个字符,如/index1213asd /index /index2 ,
                      将符合这种规则的请求进行`authc`拦截
/index/**=authc  `**`表示匹配零个或一个或多个路径,如/index/create /index/create/update/...  ,
                      将符合这种规则的请求进行`authc`拦截
/index*/**authc  可以匹配 /index12/create/update/...

3)配置 roles (角色) resources/shiro_role.ini

[users]
acey=123456,role1,role2 //表示有一个用户,用户名是acey,密码为123456,有role1和role2角色
jack=123,role1
  1. 验证用户角色是否足够
public class RoleTest {

//  使用 checkRole 来检验角色时,若权限不足会返回 false
    @Test
    public void testHasRole() {
        Subject currentUser= ShiroUtil.login("classpath:shiro_role.ini", "acey", "123456");
        // Subject currentUser=ShiroUtil.login("classpath:shiro_role.ini", "jack", "123");
        System.out.println(currentUser.hasRole("role1")?"has role1":"has not role1");
        currentUser.logout();
    }

    //  使用 checkRole 来检验角色时,若权限不足会抛出异常
    @Test
    public void testCheckRole() {
        Subject currentUser=ShiroUtil.login("classpath:shiro_role.ini", "acey", "123456");
        // Subject currentUser=ShiroUtil.login("classpath:shiro_role.ini", "jack", "123");
        currentUser.checkRole("role1");

        currentUser.logout();
    }
}
  1. 验证用户权限是否足够
public class PermissionTest {

//  使用 checkPermission 来检验权限时,若权限不足会返回 false
    @Test
    public void testIsPermitted() {
        Subject currentUser= ShiroUtil.login("classpath:shiro_permission.ini", "acey", "123456");
        System.out.println(currentUser.isPermitted("user:select")?"has user:select":"hsa not user:select");

        currentUser.logout();
    }

//  使用 checkPermission 来检验权限时,若权限不足会抛出异常
    @Test
    public void testCheckPermitted() {
        Subject currentUser=ShiroUtil.login("classpath:shiro_permission.ini", "acey", "123456");
        // Subject currentUser=ShiroUtil.login("classpath:shiro_permission.ini", "jack", "123");
        currentUser.checkPermission("user:select");
        currentUser.logout();
    }
}

二、 shiro架构

必威 9image

Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。

3.5.2 添加shiro-permission-realm.ini配置文件

[main]

#声明一个realm

myReal=com.ssm.realm.PermissionRealm

#指定securityManager的realms实现

securityManager.realms=$myReal

四 shiro 的主要功能 - 身份认证

1 Subject 认证

身份认证就是在应用中谁能证明他就是他本人,一般会使用用户名和密码作为认证信息。

2 Subject 认证主体

Subject 认证主体包含两个信息:

  • Principals:身份,即用户名
  • Credentials:凭证,即密码

** 3 认证流程**

认证流程

  1. 用户发送请求进行 Subject 认证(调用 subject.login(token))
  2. SecurityManager 会去 Authenticator(认证器)中查找相应的 Realms(可能不止一个)源
  3. Realms 可以根据不同类型的 Realm 中去查找用户信息,并进行判断是否认证成功

4 快速搭建 helloWorld

  1. 导包
<dependencies>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.2.4</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.12</version>
        </dependency>
    </dependencies>
  1. 创建 Realm /resources/shiro.ini
[users]
acey=123456
jack=111
  1. 进行身份验证
public class HelloWorld {

    public static void main(String[] args) {
//        加载配置文件,初始化 SecurityManager 工厂
        Factory<SecurityManager> factory = new IniSecurityManagerFactory
          ("classpath:shiro.shiro.ini");
//        获取 SecurityManager 实例
        SecurityManager securityManager = factory.getInstance();
//        把 SecurityManager 绑定到 SecurityUtils 中
        SecurityUtils.setSecurityManager(securityManager);
//        得到当前执行的用户
        Subject currentUser = SecurityUtils.getSubject();
//        创建 token 令牌,用户名/密码
        UsernamePasswordToken token = new UsernamePasswordToken("acey", "123456");
        try {
//            身份验证
            currentUser.login(token);
            System.out.println("登录成功");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("登录失败");
        }
    }
}
  • Apache Shiro 是 Java 的一个安全(权限)框架
  • Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在
    JavaSE 环境,也可以用在 JavaEE 环境。
  • Shiro 可以完成:认证、授权、加密、会话管理、与Web 集成、 缓存
    等。
  • 下载:Shiro下载

Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;

3.2 授权流程

必威 10

二 shiro 能干什么


先上图:

所有功能

shiro 四个主要的功能

  • Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
  • Authorization:授权,即权限验证,判断某个已经认证过的用户是否拥有某些权限访问某些资源,一般授权会有角色授权和权限授权;
  • SessionManager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的,web 环境中作用是和 HttpSession 是一样的;
  • Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;

shiro 的其它几个特点

  • Web Support:Web支持,可以非常容易的集成到Web环境;
  • Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;
  • Concurrency:shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
  • Testing:提供测试支持;
  • Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
  • Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。

2. Shiro 架构(Shiro内部来看)

必威 11

从Shiro内部来看

  • Subject:任何可以与应用交互的“用户”;
  • SecurityManager :相当于SpringMVC 中的 DispatcherServlet;是 Shiro 的心脏;所有具体的交互都通过 SecurityManager 进行控制;它管理着所有Subject、且负责进行认证、授权、会话及缓存的管理。
  • Authenticator:负责 Subject 认证,是一个扩展点,可以自定义实现;可以使用认证策略(Authentication Strategy),即什么情况下算用户认证通过了;
  • Authorizer:授权器、 即访问控制器,用来决定主体是否有权限进行相应的操作;即控制着用户能访问应用中的哪些功能;
  • Realm:可以有 1 个或多个 Realm,可以认为是安全实体数据源,即用于获取安全实体的;可以是JDBC 实现,也可以是内存实现等等;由用户提供;所以一般在应用中都需要实现自己的 Realm;
  • SessionManager:管理 Session 生命周期的组件;而 Shiro 并不仅仅可以用在 Web环境,也可以用在如普通的 JavaSE 环境
  • CacheManager:缓存控制器,来管理如用户、角色、权限等的缓存的;因为这些数据基本上很少改变,放到缓存中后可以提高访问的性能
  • Cryptography:密码模块,Shiro 提高了一些常见的加密组件用于如密码加密/解密。

Authenticator:认证器,负责主体认证的,这是一个扩展点,如果用户觉得Shiro默认的不好,可以自定义实现;其需要认证策略(Authentication Strategy),即什么情况下算用户认证通过了;

Shiro框架(原理分析与简单实现)

三 shiro 架构

先上图

架构

从图中我们可以看到不管是任何请求都会经过 SecurityManager 拦截并进行相应的处理,shiro 几乎所有的功能都是由 SecurityManager 来管理。
其中:

  • Subject:主体,相当与是请求过来的"用户"
  • SecurityManager: 是 Shiro 的心脏;所有具体的交互都通过 SecurityManager 进行拦截并控制;它管理着所有 Subject、且负责进行认证和授权、及会话、缓存的管理
  • Authenticator:认证器,负责主体认证的,即确定用户是否登录成功,我们可以使用  Shiro 提供的方法来认证,有可以自定义去实现,自己判断什么时候算是用户登录成功
  • Authrizer:授权器,即权限授权,给 Subject 分配权限,以此很好的控制用户可访问的资源
  • Realm:一般我们都需要去实现自己的 Realm ,可以有1个或多个 Realm,即当我们进行登录认证时所获取的安全数据来源(帐号/密码)
  • SessionManager:为了可以在不同的环境下使用 session 功能,shiro 实现了自己的 sessionManager ,可以用在非 web 环境下和分布式环境下使用
  • SessionDAO:对 session 的 CURD 操作
  • CacheManager:缓存控制器,来管理如用户、角色、权限等的缓存的;
  • Cryptography:密码模块,Shiro提高了一些常见的加密组件用于如密码加密/解密的。

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

1.1 什么是权限管理?

基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源。

权限管理包括用户身份认证和授权两部分,简称认证授权。对于需要访问控制的资源用户首先经过身份认证,认证通过后用户具有该资源的访问权限方可访问。

  • 认证

身份认证,就是判断一个用户是否为合法用户的处理过程.最常用的简单身份认证方式是系统通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确.对于采用指纹等系统,则出示指纹;对于硬件Key等刷卡系统,则需要刷卡.

上边的流程图中需要理解以下关键对象:

Subject:主体 (抽象的概念:保存登录后的相关信息)

访问系统的用户,主体可以是用户、程序等,进行认证的都称为主体;

Principal:身份信息

是主体进行身份认证的标识,标识必须具有唯一性,如用户名、手机号、邮箱地址等,一个主体可以有多个身份,但是必须有一个主身份(Primary Principal)(类似于数据库表中的id,保持唯一)。

credential:凭证信息

是只有主体自己知道的安全信息,如密码、证书等。

匿名访问:类似于淘宝首页

是否认证通过:淘宝下单,检查是否登录,没有登录请登录后下单

必威 12

  • 授权

授权,即访问控制,控制谁能访问哪些资源。主体进行身份认证后需要分配权限方可访问系统的资源,对于某些资源没有权限是无法访问的。(前提:必须认证通过)

例如:假如你刚好看中了一个高清无码的种子,而你准备要下载了,这个时候会弹出一个非常恶心的框,让你登录才行,好,你辛辛苦苦注册登录后,点击下载,这时有弹出一个框,告诉你必须是VIP用户才能下载,这时候就是分配权限启最用,这时你就会去充值一个VIP,然后可以点击下载,这时他们就会检查你这个用户是否有权限,有权限下载,没有权限不允许下载。

必威 13

Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。

2.认证

Cryptography:密码模块,Shiro提高了一些常见的加密组件用于如密码加密/解密的。

2.2.3 登录/退出

package com.ssm.test;

import org.apache.shiro.SecurityUtils;

import org.apache.shiro.authc.UsernamePasswordToken;

import org.apache.shiro.config.IniSecurityManagerFactory;

import org.apache.shiro.mgt.SecurityManager;

import org.apache.shiro.subject.Subject;

import org.apache.shiro.util.Factory;

import org.junit.Test;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class ShiroTest {

private final static Logger logger = LoggerFactory.getLogger(ShiroTest.class);

@Test

public void testLogin() {

// 1、创建SecurityManager工厂对象:加载配置文件,创建工厂对象

Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");

//2、创建SecurityManager

SecurityManager securityManager = factory.getInstance();

//3、将securityManager设置到运行环境中:目的是让系统随时随地可以访问securityManger对象

SecurityUtils.setSecurityManager(securityManager);

//4、创建当前登录的主体,注意:此时主体没有经过认证

Subject subject = SecurityUtils.getSubject();

//5、收集主体登录的身份 / 凭证 (创建token令牌),记录用户认证的身份和凭证即账号和密码

//参数1:将要登录的用户名,参数2:登录用户的密码

// 如果参数1出错 :抛异常 org.apache.shiro.authc.UnknownAccountException

// 如果参数2出错 :抛异常org.apache.shiro.authc.IncorrectCredentialsException

UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "666");

//6、主题登录

try {

logger.info;

subject.login;

} catch (Exception e) {

// 登录失败

System.out.println("testLogin exception value : " + e.getMessage;

System.out.println("testLogin exception value e : " + e);

}

//7、判断登录是否成功

System.out.println("验证登录是否成功 :" + subject.isAuthenticated;

//8、登出

subject.logout();

System.out.println("验证登录是否成功 :" + subject.isAuthenticated;

}

}

登录常见异常 :

必威 14

如果身份验证失败请捕获AuthenticationException或其子类,常见的如: DisabledAccountException、LockedAccountException、UnknownAccountException、ExcessiveAttemptsException、IncorrectCredentialsException 、ExpiredCredentialsException等

从外部与内部两个方面介绍一下shiro的架构与组件:

TAG标签:
版权声明:本文由必威发布于必威-编程,转载请注明出处:只要看看他简单的API必威,从Shiro内部来看