Java 权限控制框架Shiro

Apache Shiro官网:http://shiro.apache.org/

什么是Shiro?

Apache组织下的名媛 ——JAVA安全控制框架 Shiro

一个强大且易用的轻量级Java安全框架, 执行身份验证(Authentication)、(Authorization)授权、(Cryptography)加密和(Session Management)会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序, 从最小的移动应用程序到最大的网络和企业应用程序。

  • Authentication:身份认证/登录,验证用户是不是拥有相应的身份;

  • Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;

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

  • Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;

  • Web Support:Web 支持,可以非常容易的集成到Web 环境;

  • Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;

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

  • Testing:提供测试支持

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

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

记住一点,Shiro 不会去维护用户、维护权限;这些需要我们自己去设计/提供;然后通过相应的接口注入给Shiro即可

另外也提供了很好的系统集成方案,用户可以轻松的运用到web应用中,还可以集成第三方框架,例如:Spring,Guice,CAS等。

Shiro 特点

  1. 易于理解的 Java Security API;

  2. 简单的身份认证(登录),支持多种数据源(LDAP,JDBC,Kerberos,ActiveDirectory 等);

  3. 对角色的简单的签权(访问控制),支持细粒度的签权;

  4. 支持一级缓存,以提升应用程序的性能;

  5. 内置的基于 POJO 企业会话管理,适用于 Web 以及非 Web 的环境;

  6. 异构客户端会话访问;

  7. 非常简单的加密 API;

  8. 不跟任何的框架或者容器捆绑,可以独立运行。

目前还有其他出现较早的安全框架,比如 JAAS,Spring Security。

JAAS —面世的时间最早,但是鉴于其在使用上有很大的限制,很少有人真正的使用它。可以说它不是一个好的应用程序级别的安全框架;

Spring Security —目前是 Java 安全框架领域当之无愧的老大,已经非常成熟了;如果使用 Spring 框架,可以首选 Spring Security,但是对于单应用来说,Shiro 更显简单方便。

Shiro三个核心组件:Subject, SecurityManager 和 Realms.

  1. Subject:即“当前操作用发户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。但考虑到大多数目的和用途,你可以把它认为是Shiro的“用户”概念。Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。

  2. SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。

  3. Realm: Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。

    从这个意义上讲,Realm实质上是一个安全相关的DAO:它封装了数据源的连接细节,并在需要时将相关数据提供给Shiro。当配置Shiro时,你必须至少指定一个Realm,用于认证和(或)授权。配置多个Realm是可以的,但是至少需要一个。

    Shiro内置了可以连接大量安全数据源(又名目录)的Realm,如LDAP、关系数据库(JDBC)、类似INI的文本配置资源以及属性文件等。如果缺省的Realm不能满足需求,你还可以插入代表自定义数据源的自己的Realm实现。

Hello Shiro

  1. 导入slf4j-api.jar,slf4j-logj12.jar,log4j.jar,shiro-core.jar包

  2. 在classpath下创建shiro.ini文件,文件内容如下表示用户名和密码

    [users]

    shiro = shiro


import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
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.Assert;
import org.junit.Test;

public class ShiroTest {

    @Test
    public void test() {
        // 1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
        Factory<SecurityManager> factroy = new IniSecurityManagerFactory("classpath:shiro.ini");

        // 2、得到SecurityManager实例并绑定给SecurityUtils
        SecurityManager securityManager = factroy.getInstance();
        SecurityUtils.setSecurityManager(securityManager);

        // 3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken("shiro", "shiro");
        try {
            // 4、登录,即身份验证
            subject.login(token);
        } catch (AuthenticationException e) {
            // 5、身份验证失败
            e.printStackTrace();
        }

        Assert.assertEquals(true, subject.isAuthenticated()); //断言用户已经登录

        // 6、退出
        subject.logout();
    }
}

(1)需要读取classpath下的shiro.ini配置文件,并通过工厂类创建SecurityManage对象,最终将其放入SecurityUtils中,方便Shiro框架随时获取

(2)通过SecurityUtils获取Subject(主体)对象,其实就是当前用户,只是叫法不同罢了

(3)首先使用一个Username与Password来创建一个UsernamePasswordToken对象,然后通过这个Token对象调用Subject的login方法进行身份认证

(4)当登录失败,可以使用AuthenticationException来捕获这个异常;当登录成功可以调用Subject对象的getPrincipal方法来获取Username,此时Shiro已经创建了一个Session

(5)最后还是通过Subject对象的logout来注销本次Sesson

只需要知道以上几个Shiro核心成员的基本用法,Shiro就是你的了

其实,Shiro的调用流程也不难理解,如下图

通过Subject调用SecurityManager,通过SecurityManager调用Realm,这个Realm说白了其实就是提供用户信息的数据源,例如上例子中的shiro.ini就是配置用户信息的一种Realm方式,在Shiro中叫做IniRealm,除此之外,还提供了其他几种Realm:有PropertiesRealm、JdbcRealm、JndiLdapRealm、ActiveDirectoryRealm等,当然也可以定制Realm来满足业务需求。

在Web开发中使用Shiro

在web开发中,还需要导入shiro-web.jar包,然后在web.xml中添加一个Listener与一个Filter。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">

    <!-- 添加Shiro监听器 -->
    <listener>
        <listener-class>org.apache.shiro.web.env.EnvironmentLoader-Listener</listener-class>
    </listener>

    <!-- 添加Shiro过滤器 -->
    <filter>
        <filter-name>ShiroFilter</filter-name>
        <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ShiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

实际上就是通过EnvironmentLoaderListener这个监听器来初始化SecurityManager,并通过ShiroFilter来完成认证认证与授权。

。。。

帮助资源:http://jinnianshilongnian.iteye.com/blog/2018398


赞(52) 打赏
未经允许不得转载:优客志 » JAVA开发
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏