Apache Shiro——初识
Shrio是什么?
Shrio是一个用Java开发的安全框架,用来保证系统或系统数据安全的。他可以用在大多数程序上,比如移动应用程序、Web程序或者大型的企业应用程序等。
Shrio能干什么?
能用来做身份验证(如:用户名和密码登陆的验证)、授权(如:判断登陆的用户是否具有某个权限)、加密(把密码进行MD5加密成一串代码)、会话管理(类似于Web程序的Session管理)等等。
这里用web程序举例子:
通常用户请求一个资源或者访问一个功能的时候,需要检测下用户是不是登陆状态或者说检测下登陆的用户是不是有这个权限(为了数据安全),一般用session来储存状态的就需要去获取一下Session有没有储存此用户的信息,然后再检测这个用户的权限。这些操作可以说很繁琐。然而shrio已经实现好了,只要调用其一个api就可以验证用户的权限了。
Shrio还提供了在非web程序里也可以使用Session的api操作。
为什么用Shrio?
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——初识的更多相关文章
- Apache Shiro系列一,概述 —— 初识
一.什么是Shiro Apache Shiro是一个强大.灵活.开源的安全框架,它支持用户认证.权限控制.企业会话管理以及加密等. Apache Shiro的第一个也是最重要的一个目标就是易于使用和理 ...
- Apache Shiro(一)-登录认证和权限管理初识
What is Apache Shiro? Apache Shiro是一个功能强大.灵活的,开源的安全框架.它可以干净利落地处理身份验证.授权.企业会话管理和加密. Apache Shiro的首要目标 ...
- Apache Shiro系列之五,概述 —— 配置
Shiro设计的初衷就是可以运行于任何环境:无论是简单的命令行应用程序还是复杂的企业集群应用.由于运行环境的多样性,所以有多种配置机制可用于配置,本节我们将介绍Shiro内核支持的这几种配置机制. ...
- Apache Shiro系列四,概述 —— Shiro的架构
Shiro的设计目标就是让应用程序的安全管理更简单.更直观. 软件系统一般是基于用户故事来做设计.也就是我们会基于一个客户如何与这个软件系统交互来设计用户界面和服务接口.比如,你可能会说:“如 ...
- Apache Shiro系列三,概述 —— 10分钟入门
一.介绍 看完这个10分钟入门之后,你就知道如何在你的应用程序中引入和使用Shiro.以后你再在自己的应用程序中使用Shiro,也应该可以在10分钟内搞定. 二.概述 关于Shiro的废话就不多说了 ...
- Apache Shiro 学习记录5
本来这篇文章是想写从Factory加载ini配置到生成securityManager的过程的....但是貌似涉及的东西有点多...我学的又比较慢...很多类都来不及研究,我又怕等我后面的研究了前面的都 ...
- Apache Shiro 学习记录2
写完上篇随笔以后(链接).....我也想自己尝试一下写一个Strategy.....Shiro自带了3个Strategy,教程(链接)里作者也给了2个.....我想写个都不一样的策略.....看来看去 ...
- Apache Shiro系列(1)
Apache Shiro是啥呢,安全框架. 360百科是这么描述的: Apache Shiro(日语"堡垒(Castle)"的意思)是一个强大易用的Java安全框架, ...
- Apache Shiro 学习记录1
最近几天在学习Apache Shiro......看了一些大神们的教程.....感觉收获不少.....但是毕竟教程也只是指引一下方向....即使是精品教程,仍然有很多东西都没有说明....所以自己也稍 ...
随机推荐
- 修改oracle数据库用户名和密码
第一步:连接数据库 使用ssh工具以root身份连接服务器, 然后切换到oracle用户:su - oracle(回车) 使用sqlplus连接数据库:sqlplus /nolog(回车) 以管理员身 ...
- LitElement(六)生命周期
1.概述 基于LitElement的组件通过响应观察到的属性更改而异步更新. 属性更改是分批进行的,如果在请求更新后,更新开始之前,发生更多属性更改,则所有更改都将捕获在同一次更新中. 在较高级别上, ...
- CentOS 7升级gcc版本
Centos 7默认gcc版本为4.8,有时需要更高版本的,这里以升级至8.3.1版本为例,分别执行下面三条命令即可,无需手动下载源码编译 1.安装centos-release-scl sudo yu ...
- CentOS7.5升级OpenSSH
实验环境 OS:CentOS 7.5 当前openssh版本:OpenSSH_7.4p1 升级后的openssh版本:OpenSSH_8.0p1 开通telnet 为了防止升级过程中ssh断连,保险起 ...
- 53最大子序和.py
题目:给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. 来源:https://leetcode-cn.com/problems/maximum-s ...
- [IOI2002] 任务安排
题目链接 题意 一些不能改变顺序的任务被分成若干批,每批包含相邻的若干任务.第 $i$ 个任务单独完成所需的时间是 $T_i$.在每批任务开始前,机器需要启动时间 $S$,而完成这批任务所需的时间是各 ...
- AcWing 895. 最长上升子序列
//设上升序列的最后一个数字为第i个,那么就以第i-1个位分类标准, //i-1可以没有,也可以是在数组中下标为1,下标为2 //一直到下标为i-1的数字 #include <iostream& ...
- JQuery/JS插件 jsTree加载树,普通加载,点一级加载一级
前端: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <tit ...
- Spark 中 GroupByKey 相对于 combineByKey, reduceByKey, foldByKey 的优缺点
避免使用GroupByKey 我们看一下两种计算word counts 的方法,一个使用reduceByKey,另一个使用 groupByKey: val words = Array("on ...
- 关于MySQL的tinyint(3)问题
mysql 中int(1)和tinyint(1)中的1只是指定显示长度,并不表示存储长度.tinyint可以存储1字节, 即unsigned 0~255(signed -127~127).显示大小不受 ...