Shrio是什么?

Shrio是一个用Java开发的安全框架,用来保证系统或系统数据安全的。他可以用在大多数程序上,比如移动应用程序、Web程序或者大型的企业应用程序等。


Shrio能干什么?

能用来做身份验证(如:用户名和密码登陆的验证)、授权(如:判断登陆的用户是否具有某个权限)、加密(把密码进行MD5加密成一串代码)、会话管理(类似于Web程序的Session管理)等等。

这里用web程序举例子:

通常用户请求一个资源或者访问一个功能的时候,需要检测下用户是不是登陆状态或者说检测下登陆的用户是不是有这个权限(为了数据安全),一般用session来储存状态的就需要去获取一下Session有没有储存此用户的信息,然后再检测这个用户的权限。这些操作可以说很繁琐。然而shrio已经实现好了,只要调用其一个api就可以验证用户的权限了。

Shrio还提供了在非web程序里也可以使用Session的api操作。


为什么用Shrio?

推荐:传送门1传送门2


Shrio种的一些名词

官网传送门:http://shiro.apache.org/

Subject:主体;代表当前操作对象,这个主体更具不同的操作对象来定。可以是一个程序也可以是一个人。如:一个博客那么操作的是一个人,那么此时的subject就代表当前登陆的用户。验证权限,验证登陆使用这个对象就行了。

SecurityMannager:安全管理;这是整个框架的核心。一些验证操作和实现逻辑都是通过SecurityManage来处理的,调用想使用什么功能调用Subject的接口,然后Subject会自动调用SecurityMananger里面的代码。

Realms:域;如果你熟悉MVC会发现,realms像是个DAO层的东西,这个要根据需求自己实现,至少有一个自己实现的realm,封装跟数据源的链接细节。比如:用户登陆的时候,用户信息(用户名,密码等)存在数据库里。那么再编写reams的时候就可以在里面写一些链接数据库,获取用户名密码等代码了。当然这里举的例子数据源在数据库,也可以是一个配置文件等。


Shrio简单案例

做个用户登陆验证的例子。为了测试的简单,就建库写sql了,直接用个Map代表数据库,详细看第二段。

1、为了方便导包,建个maven程序,并添加依赖。

       <!-- 导入apaceh shrio依赖包 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.4.0</version>
        </dependency>
        <!-- 为了方便测试所以导入了junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency> 

2、实现AuthorizingRealm接口,里面自定义了获取数据源的方式MyRealm

public class MyRealm extends AuthorizingRealm {

    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String permission1="admin";
        String permission2="common";
        Set<String> permissions=new HashSet<String>();
        permissions.add(permission1);
        permissions.add(permission2);

        Set<String> roles=new HashSet<String>();
        roles.add("admin");

        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        info.setStringPermissions(permissions);
        info.setRoles(roles);
        return info;
    }

    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获取的用户输入的用户名;
        String username=(String) authenticationToken.getPrincipal();
        //模拟从数据库根据用户名获取密码
        String password=getPasswordByUserName(username);

        //获取到为null,就是没有此用户,直接抛出UnknownAccountException异常,代表不存在此用户。
        if(password==null){
            throw new UnknownAccountException();
        }
        //这里的username是获取前端用户输入的,而密password是从数据库中获取的,放到token里框架自动会检测。
        AuthenticationInfo info=new SimpleAuthenticationInfo(username,password,"MyRealm");
        return info;
    }

    //这里模拟从数据库根据用户名获取密码
    public String getPasswordByUserName(String userName){
        Map<String,String> db=new HashMap<String, String>();
        db.put("admin","123456");
        return db.get(userName);
    }

}

3、测试

public class MainTest {

    @Test
    public void test(){
        //模拟用户输入的用户名和密码
        String username="admin";
        String password="123456";

        //生成一个自定义的MyRealm对象,里面有自定义的权限设置和验证方式。
        Realm realm=new MyRealm();

        //讲MyReam当作参数创建一个SecurityManager对象
        //这里的DefaultSecurityManager只是一个SecurityMannager的实现
        SecurityManager securityManager=new DefaultSecurityManager(realm);

        //然后把securityMannager配置到框架中。
        SecurityUtils.setSecurityManager(securityManager);

        //获取代表当前对象,如果没登陆。调用subject.isAuthenticated()会返回false,否则反之。
        Subject subject=SecurityUtils.getSubject();

        //生成一个AuthenticationToken的对象,把用户输入的用户名和密码放进去
        //这个UsernamePasswordToken只是AuthenticationToken的一个实现。
        UsernamePasswordToken token=new UsernamePasswordToken(username,password);

        try {
            //这样就是验证登陆了,这是在try catch中。
            //这就是Shrio的验证方法,如果验证不通过,会直接抛出异常。
            //根据验证不通过的原因,会抛出不同的异常。
            subject.login(token);
        } catch ( UnknownAccountException uae ) {
            //用户名不存在的时候抛的异常
            System.out.println("登陆失败,不存在此用户:"+uae.getMessage());
        } catch ( IncorrectCredentialsException ice ) {
            //密码错误
            System.out.println("登陆失败,密码错误:"+ice.getMessage());

        } catch ( AuthenticationException ae) {
            //其他的异常
            //当然还有更详细的具体异常,看官网文档。
            System.out.println("登陆失败:"+ae.getMessage());
        }

        //使用subject.isAuthenticated()检测是否验证通过,也即使是否登陆成功
        if(subject.isAuthenticated()){
            //获取登陆的用户信息
            System.out.println("用户("+subject.getPrincipal()+")登陆成功!");
            //查看登陆的用户是否有某个权限。详细见:myRealm.doGetAuthorizationInfo()
            System.out.println("用户("+subject.getPrincipal()+")是否有admin权限?"+subject.isPermitted("admin"));
            System.out.println("用户("+subject.getPrincipal()+")是否有common权限?"+subject.isPermitted("common"));
            System.out.println("用户("+subject.getPrincipal()+")是否有super admin权限?"+subject.isPermitted("super admin"));
            //如果登陆成功输出如下:
            //用户(admin)登陆成功!
            //用户(admin)是否有admin权限?true
            //用户(admin)是否有common权限?true
            //用户(admin)是否有super admin权限?false

        }else{
            System.out.println("用户登陆失败");
        }

    }
}

好了,以后任何地方都可以通过Subject subject=SecurityUtils.getSubject();获取当前的登陆对象,然后通过这个subject对后验证是否登陆,验证是否含有权限等操作。


后面记录下在Web里面怎么用Shrio的过滤器。

Apache Shiro——初识的更多相关文章

  1. Apache Shiro系列一,概述 —— 初识

    一.什么是Shiro Apache Shiro是一个强大.灵活.开源的安全框架,它支持用户认证.权限控制.企业会话管理以及加密等. Apache Shiro的第一个也是最重要的一个目标就是易于使用和理 ...

  2. Apache Shiro(一)-登录认证和权限管理初识

    What is Apache Shiro? Apache Shiro是一个功能强大.灵活的,开源的安全框架.它可以干净利落地处理身份验证.授权.企业会话管理和加密. Apache Shiro的首要目标 ...

  3. Apache Shiro系列之五,概述 —— 配置

    Shiro设计的初衷就是可以运行于任何环境:无论是简单的命令行应用程序还是复杂的企业集群应用.由于运行环境的多样性,所以有多种配置机制可用于配置,本节我们将介绍Shiro内核支持的这几种配置机制.   ...

  4. Apache Shiro系列四,概述 —— Shiro的架构

    Shiro的设计目标就是让应用程序的安全管理更简单.更直观.     软件系统一般是基于用户故事来做设计.也就是我们会基于一个客户如何与这个软件系统交互来设计用户界面和服务接口.比如,你可能会说:“如 ...

  5. Apache Shiro系列三,概述 —— 10分钟入门

     一.介绍 看完这个10分钟入门之后,你就知道如何在你的应用程序中引入和使用Shiro.以后你再在自己的应用程序中使用Shiro,也应该可以在10分钟内搞定. 二.概述 关于Shiro的废话就不多说了 ...

  6. Apache Shiro 学习记录5

    本来这篇文章是想写从Factory加载ini配置到生成securityManager的过程的....但是貌似涉及的东西有点多...我学的又比较慢...很多类都来不及研究,我又怕等我后面的研究了前面的都 ...

  7. Apache Shiro 学习记录2

    写完上篇随笔以后(链接).....我也想自己尝试一下写一个Strategy.....Shiro自带了3个Strategy,教程(链接)里作者也给了2个.....我想写个都不一样的策略.....看来看去 ...

  8. Apache Shiro系列(1)

    Apache Shiro是啥呢,安全框架. 360百科是这么描述的:        Apache Shiro(日语"堡垒(Castle)"的意思)是一个强大易用的Java安全框架, ...

  9. Apache Shiro 学习记录1

    最近几天在学习Apache Shiro......看了一些大神们的教程.....感觉收获不少.....但是毕竟教程也只是指引一下方向....即使是精品教程,仍然有很多东西都没有说明....所以自己也稍 ...

随机推荐

  1. 记录 shell学习过程(6)while 以及 while的嵌套 以及 until

    while中的5种条件 1.数学比较 read -p "Num :" num1 ] do echo 'greater' sleep done 2.字符串比较 read -p &qu ...

  2. Big research problems (1)

    1. how to measure the uncertainty of prediction model or data analysis? 2.

  3. Motif

    Motif discovery is in loose terms the problem of finding interesting patterns in sequences. motif: i ...

  4. Binary Number(位运算)

    #include<bits/stdc++.h> using namespace std; int n; int getBits1(int n)//求取一个数的二进制形式中1的个数. { i ...

  5. RemoteViews 整理

    前言 RemoteViews表面意思就是远程的view,这个就很难理解了,远程的view.但是英语是抽象,remote本身就是偏僻的,偏远的意思. 所以remoteViews 就是地方view,天高皇 ...

  6. 常用的 19 条 MySQL 优化

    一.EXPLAIN 做MySQL优化,我们要善用 EXPLAIN 查看SQL执行计划. 下面来个简单的示例,标注(1,2,3,4,5)我们要重点关注的数据 type列,连接类型.一个好的sql语句至少 ...

  7. b 解题报告

    本题已收录至2019/9/15 本周总结 题目 [问题描述] Hja有一棵\(n\)个点的树,树上每个点有点权,每条边有颜色.一条路径的权值是这条路径上所有点的点权和,一条合法的路径需要满足该路径上任 ...

  8. 并发队列 ConcurrentLinkedQueue 及 BlockingQueue 接口实现的四种队列

    队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作.进行插入操作的端称为队尾,进行删除操作的端称为队头.队列中没有元素时,称为空队列. 在队列这 ...

  9. Yum与list结合

    我用两台Linux LinuxA      IP:192.168.10.101 LinuxB      IP:192.168.10.102 首先我们在LinuxA上挂载光驱和安装FTP服务器 然后安装 ...

  10. 密码学笔记——Rot13

    Rot13:将每个在字母表上的字母,用后数13个后的字母代替,若超过时则重新绕回26字母开头即可. eg:A换成N.B换成O.依此类推到M换成Z,然后序列反转:N换成A.O换成B.最后Z换成M 1.密 ...