shiro安全框架

shiro的作用
shiro是一个安全框架。主要可以帮助我们解决程序开发中认证和授权的问题。上次做的权限系统,权限控制的粒度到模块级别了,如果只要能看到操作的菜单,就能操作菜单下所有的功能。以后这种权限设计模式,可能不太好满足什么的需求的需要?以后项目中,有坑你权限粒度控制的更细,有可能要控制到模块下的按钮级别,更有甚者,控制到数据的级别。以后为了方便各种各样的常用的权限管理需求的实现。我们有必要使用了比较好的安全框架。早期的Spring Security作为一个比较完善的安全框架比较火,但是spring security学习成本比较高。之后又出现了一个shiro的安全框架,学习成本降低了很多。而且基本的功能也比较完善。shiro也提供很多其他的功能:
shiro的架构
  Subject:主题 被验证的对象,一般指的当前用户对象。但是不仅仅可以指当前用户对象,还可以是是其他东西,
线程等等。spring mvc中一个一个的用户的请求。
  SecurityManager:安全认证管理器。是shiro的核心,会在安全认证管理器中所做所有的认证操作。类似于之前
spring mvc中的前端控制器(DispacherServlet)
  Realm: 域的意思。负责访问安全认证数据。shiro 框架并不存储安全认证数据,安全认证数据需要用户自己存
储。shiro支持很多的Realm实现,也就 是说安全认证数据我们可以放到数据库中,也可以放到文件中等等。
可以把realm理解为以前web项目中的dao层。
shiro的认证 
要做一个最简单的shiro的框架。实现的功能:用户的登录身份认证。用户如果用户名和密码都输入正确,认证成功,否则认证失败。
第一步,新建maven项目,导入shiro的jar包 
现在使用的maven项目还是一个简单的java项目,暂时不使用web项目。 
<!--导入shiro依赖的commons-loggin的jar包-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.0.4</version>
</dependency>
<!--导入shiro的jar包-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.3</version>
</dependency>
第二步,创建shiro的认证文件 
这次我们需要把用户的认证信息放到认证文件中。在resources下面建立shiro.ini: 
#声明用户的对象
[users]
#=号前面是用户名 后面是密码
zhang=123456
li=654321
第三步,创建测试类 
/**
* 测试shiro身份认证
*/
public class Test01 {
public static void main(String[] args) {
//创建生成SecurityManager的工厂类对象
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//创建SecurityManager对象
SecurityManager securityManager = factory.getInstance();
//把SecurityManager对象设置给SecurityUtils对象
SecurityUtils.setSecurityManager(securityManager);
//获取验证的主题,主题是用户对象
Subject subject = SecurityUtils.getSubject();
//声明要比对的用户名和密码的用户对象 相当于之前前台传过来的要校验的用户登录的信息
UsernamePasswordToken token = new UsernamePasswordToken("zhansdd","123");
try {
//进行用户校验
subject.login(token);
System.out.println("校验成功");
}catch (UnknownAccountException e){
System.out.println("您输入的用户名不存在");
}catch (IncorrectCredentialsException e){
System.out.println("您输入的密码不正确");
}catch (AuthenticationException e){
System.out.println("校验失败");
}
//退出登录
subject.logout();
}
}

realm

realm是用来读取认证的数据,上一个例子的认证的数据是存储在配置文件中的,一般项目认证数据都不会存到配
置文件中,一般在数据中,所以针对这种情况 我们就需要自定义realm。 
自定义realm
第一步,声明自定义realm
/**
* 自定义realm1
*/
public class MyRealm implements Realm {
//设置本realm的名称
public String getName() {
return "MyRealm1";
}
//设置本realm支持什么样的数据校验
public boolean supports(AuthenticationToken authenticationToken) {
return authenticationToken instanceof UsernamePasswordToken;
}
//获取认证信息
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken authenticationToken) throws
AuthenticationException {
//获取用户传递过来的用户名和密码
String username = (String)authenticationToken.getPrincipal();
String password = new String((char[])(authenticationToken.getCredentials()));
//根据用户名和密码查询数据库,看看能不能查询到数据
if(username.equals("zhangsan")&&password.equals("123456")){
return new SimpleAuthenticationInfo(username,password,this.getName());
}else{
//校验失败 抛出校验失败异常
throw new AuthenticationException("用户名或者密码错误");
}
}
}
第二步,在shiro的主配置文件中声明我们自定义的realm
创建shiro的主配置文件shiro-custom.ini:
#声明自定义的realm
myRealm1=com.aaa.shiro.realm.MyRealm
#设置安全管理器使用我们自定义的realm
securityManager.realms=$myRealm1
第三步,测试
/**
* 测试shiro身份认证 自定义realm
*/
public class Test02 {
public static void main(String[] args) {
//创建生成SecurityManager的工厂类对象
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-custom.ini");
//创建SecurityManager对象
SecurityManager securityManager = factory.getInstance();
//把SecurityManager对象设置给SecurityUtils对象
SecurityUtils.setSecurityManager(securityManager);
//获取验证的主题,主题是用户对象
Subject subject = SecurityUtils.getSubject();
//声明要比对的用户名和密码的用户对象 相当于之前前台传过来的要校验的用户登录的信息
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan123","123456");
try {
//进行用户校验
subject.login(token);
System.out.println("校验成功");
}catch (UnknownAccountException e){
System.out.println("您输入的用户名不存在");
}catch (IncorrectCredentialsException e){
System.out.println("您输入的密码不正确");
}catch (AuthenticationException e){
System.out.println("校验失败");
}
//退出登录
subject.logout();
}
}
JdbcRealm
jdbcRealm的实现允许我们从一个数据源中读取认证的数据,只需要简单的配置即可。
假如要从oracle数据库中读取认证数据
第一步,在oracle中创建用户认证需要的表
JdbcRealm默认会找数据库中名称为Users的表进行查询,Users必须要有username列,password列。 
第二步,引入oracle的驱动包,数据库连接池实现的包dbcp 
第三步,在shiro主配置文件中配置JdbcRealm
在resources下面创建shiro-jdbcrealm.ini: 
#声明数据源
dataSource=org.apache.commons.dbcp.BasicDataSource
#声明数据源的一些链接的属性
dataSource.driverClassName=oracle.jdbc.driver.OracleDriver
dataSource.url=jdbc:oracle:thin:@localhost:1521:orcl
dataSource.username=scott
dataSource.password=tiger
#声明jdbcrealm
jdbcrealm=org.apache.shiro.realm.jdbc.JdbcRealm
#声明jdbcrealm需要用到的数据源属性
jdbcrealm.dataSource=$dataSource
##设置安全管理器使用的jdbcrealm
securityManager.realms=$jdbcrealm
第四步,测试
/**
* 测试shiro身份认证 自定义realm
*/
public class Test03 {
public static void main(String[] args) {
//创建生成SecurityManager的工厂类对象
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-jdbcrealm.ini");
//创建SecurityManager对象
SecurityManager securityManager = factory.getInstance();
//把SecurityManager对象设置给SecurityUtils对象
SecurityUtils.setSecurityManager(securityManager);
//获取验证的主题,主题是用户对象
Subject subject = SecurityUtils.getSubject();
//声明要比对的用户名和密码的用户对象 相当于之前前台传过来的要校验的用户登录的信息
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","123456");
try {
//进行用户校验
subject.login(token);
System.out.println("校验成功");
}catch (UnknownAccountException e){
System.out.println("您输入的用户名不存在");
}catch (IncorrectCredentialsException e){
System.out.println("您输入的密码不正确");
}catch (AuthenticationException e){
e.printStackTrace();
System.out.println("校验失败");
}
//退出登录
subject.logout();
}
}
原文地址:https://www.cnblogs.com/duguangming/p/11045644.html