收藏私塾在线
 

欢迎您来到私塾在线网!   

请登录! 

免费注册 


renqiwang的笔记
状态: 离线
人气:2663036
访问用户量:2498
笔记经验:
总积分:389
级别:普通会员
搜索本笔记
ta的交流分类
ta的交流主题贴(61)
ta的所有交流贴(81)
ta的全部笔记
全部笔记(189)
未分类笔记(15)
JAVA(73)
课程问题(0)
Hibernate4(7)
Spring3(11)
Struts2(1)
ant(1)
maven(1)
jBPM(5)
Java Web(11)
研磨Struts2(15)
jquery(1)
Oracle&JDB……(2)
PL-SQL(1)
Android(0)
log4j&slf4……(1)
Mybaits(4)
研磨设计模式(28)
SpringMVC(11)
Spring Dat……(1)
存档
2013-11(10)
2013-07(12)
2012-11(1)
2012-08(28)
2012-03(6)
2012-02(132)

2013-11-12 14:33:29
第五章:Shiro的授权(Authorization)——深入浅出学Shiro细粒度权限开发框架——私塾在线原创
浏览(58786)|评论(0)   交流分类:Java|笔记分类: JAVA

Authorization概述

n概述

  授权,又称作为访问控制,是对资源的访问管理的过程。换句话说,控制谁有权限在应用程序中做什么。

  授权检查的例子是:该用户是否被允许访问这个网页,编辑此数据,查看此按钮,或打印到这台打印机?这些都是决定哪些是用户能够访问的。

n授权的三要素

  授权有着三个核心元素:权限、角色和用户 。

  我们需要在应用程序中对用户和权限建立关联,通常的做法就是将权限分配给某个角色,然后将这个角色关联一个或多个用户。

n权限

  是Shiro安全机制最核心的元素。它在应用程序中明确声明了被允许的行为和表现。一个格式良好的权限声明可以清晰表达出用户对该资源拥有的权限。

n权限声明和粒度

  在shiro中主要通过前面学过的通配符表达式来完成。

 

n角色

  角色是一个命名的实体,通常代表一组行为或职责。这些行为演化为你在一个软件应用中能或者不能做的事情。角色通常是分配给用户帐户的,因此,通过分配,用户能够“做”的事情可以归属于各种角色。

nShiro支持的角色类型

1:隐式角色:一个角色代表着一系列的操作,当需要对某一操作进行授权验证时,只需判断是否是该角色即可。这种角色权限相对简单、模糊,不利于扩展。

2:显式角色:一个角色拥有一个权限的集合。授权验证时,需要判断当前角色是否拥有该权限。这种角色权限可以对该角色进行详细的权限描述,适合更复杂的权限设计。 Shiro官方推荐使用这种方式。

nShiro的三种授权方式

1:编写代码——在Java 代码中用像if 和else 块的结构执行授权检查。

2:JDK 的注解——你可以添加授权注解给你的Java 方法。

3:JSP/GSP 标签库——你可以控制基于角色和权限的JSP 或者GSP 页面输出。

 

编程授权

n通过使用subject的方法来实现角色的判断,常见的api:

hasRole(String roleName) :返回true 如果Subject 被分配了指定的角色

hasRoles(List<String> roleNames) :返回一个与方法参数中目录一致的hasRole 结果的数组。

hasAllRoles(Collection<String> roleNames):返回true 如果Subject 被分配了所有的角色

n断言支持

  Shiro还支持以断言的方式进行授权验证。断言成功,不返回任何值,程序继续执行;断言失败时,将抛出异常信息。方法大致如下:

checkRole(String roleName) 、checkRoles(Collection<String>roleNames)、checkRoles(String… roleNames)

n基于权限对象的实现

Permission printPermission = new PrinterPermission("laser400n", "print");

相关方法:isPermitted(Permission p)、isPermitted(List<Permission> perms)、isPermittedAll(Collection<Permission> perms)  

 

n基于字符串的实现

if (currentUser.isPermitted("printer:print:laserjet4400n"))

相关方法:isPermitted(String perm)、isPermitted(String... perms)、isPermittedAll(String... perms)

 

n当然上述权限的实现也都可以采用断言的方式

  相关方法:

checkPermission(Permission p)

checkPermission(String perm)

checkPermissions(Collection<Permission> perms)

checkPermissions(String... perms)

 

基于注解的授权

n需要有AOP框架的支持,这里选择spring,先看看怎么集成配置,看例子:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xmlns:context="http://www.springframework.org/schema/context"

  xmlns:aop="http://www.springframework.org/schema/aop"

  xmlns:tx="http://www.springframework.org/schema/tx"

  xsi:schemaLocation="

  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd

  http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

      <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

      <context:component-scan base-package="cn.javass"></context:component-scan>     

      <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"

  depends-on="lifecycleBeanPostProcessor" >

  <property name="proxyTargetClass" value="true"/>

  </bean>

  <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

 

  <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">

  <property name="securityManager" ref="securityManager" />

  </bean>

  <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">

  <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>

  <property name="arguments" ref="securityManager"/>

  </bean>

 

      <bean id="securityManager" class="org.apache.shiro.mgt.DefaultSecurityManager"> 

      <property name="cacheManager" ref="cacheManager"/> 

          <property name="realm" ref="myRealm"/> 

          <property name="sessionManager" ref="sessionManager"/>  

  </bean>

  <bean id="sessionManager" class="org.apache.shiro.session.mgt.DefaultSessionManager">

  </bean>

  <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager" />

  <bean id="myRealm" class="org.apache.shiro.realm.text.IniRealm">

  <property name="resourcePath" value="D:/wp/src/TestShiro.ini"></property> 

  </bean>

</beans>

 

n测试用的HelloAnno

@Service

public class HelloAnno {

  @Autowired

  private org.apache.shiro.mgt.SecurityManager sm = null;

 

  @RequiresAuthentication

  @RequiresPermissions({"p1"})

  public void t(){

  System.out.println("ok=========");

  }

  public void login(){

  UsernamePasswordToken token = new UsernamePasswordToken("javass","cc"); 

  token.setRememberMe(true);

  SecurityUtils.setSecurityManager(sm);

 

  Subject currentUser = SecurityUtils.getSubject(); 

  currentUser.login(token);

  }

  public static void main(String[] args) {

   ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

   HelloAnno t = (HelloAnno)ctx.getBean("helloAnno"); 

   t.login();

   t.t();

  }

}

 

nShiro提供的注解

1:@RequiresAuthentication :要求当前Subject 已经在当前的session 中被验证通过才能被注解的类/实例/方法访问或调用。

2:@RequiresGuest :要求当前的Subject 是一个“guest”,也就是他们必须是在之前的session中没有被验证或记住才能被注解的类/实例/方法访问或调用。

3:@RequiresPermissions:要求当前的Subject 被允许一个或多个权限,以便执行注解的方法,比如:@RequiresPermissions("account:create")

4:@RequiresRoles:要求当前的Subject 拥有所有指定的角色。如果他们没有,则该方法将不会被执行,而且AuthorizationException 异常将会被抛出。比如:@RequiresRoles("administrator")

5:@RequiresUser:需要当前的Subject 是一个应用程序用户才能被注解的类/实例/方法访问或调用。要么是通过验证被确认,或者在之前session 中的'RememberMe'服务被记住。

 

授权的顺序

 

nStep 1:应用程序或框架代码调用任何Subject的hasRole*, checkRole*, isPermitted*,或者checkPermission*方法的变体,传递任何所需的权限或角色
nStep 2:Subject的实例,通常是DelegatingSubject(或子类)代表应用程序的SecurityManager 通过调用securityManager的几乎各自相同的方法。
nStep 3:SecurityManager,实现org.apache.shiro.authz.Authorizer 接口,他定义了所有Subject 具体的授权方法 。默认情况下,authorizer 实例是一个ModularRealmAuthorizer 实例,它支持协调任何授权操作过程中的一个或多个Realm 实例。
nStep 4:每个配置好的Realm 被检查是否实现了相同的Authorizer接口。如果是,Realm 各自的hasRole*, checkRole*,isPermitted*,或checkPermission*方法将被调用。

 

理解ModularRealmAuthorizer

nModularRealmAuthorizer 将遍历其内部的Realm 集合,并按迭代顺序与每一个进行交互。每个Realm 的交互功能如下:

1:如果Realm 自己实现了Authorizer 接口,它的各个Authorizer方法将被调用。

(1)如果Realm 的方法导致异常,该异常将会以AuthorizationException 的形式传递给调用者。这将短路授权过程,任何剩余的Realm 将不会被访问

(2)如果该Realm 的方法是一个返回布尔值的hasRole*或者isPermitted*的变体,并且该返回值为true,真值将会立即被返回,同时任何剩余的Realm 都将被短路,这种行为能提高性能。

2:如果Realm 不实现Authorizer 接口,它会被忽略

 

 

了解全局的PermissionResolver

n当执行基于字符串的权限检查是,大多数Shiro 的默认Realm 实现首先将该字符串转换成一个实际的Permission 实例,用的是内部默认实现的WildcardPermissionResolver
n
n如果你想要支持自己的权限字符串语法,而且你想要所有配置的Realm 实例支持该语法,你可以将你的PermissionResolver 设置为全局的
n
n如果你想配置一个全局的PermissionResolver,每个用来接收配置的PermissionResolver 的Realm 必须实现PermissionResolverAware 接口。这样保证了配置的实例能够被每个支持该配置的Realm 转发。
n
n类似的,还有全局的RolePermissionResolver,但请注意:由于这种转换角色名到权限的概念非常特定于应用程序,Shiro 默认Realm 的实现并不使用它们
精品视频课程推荐

透彻理解JavaBean视频教程
深入浅出的讲解JavaBen的写法、JavaBean的用法、JavaBean的实现机制、JavaBean对应翻译的代码理解。

深入浅出学Shrio视频教程
内容概述:Shiro是目前最热门、最易用、功能超强大的Java权限管理框架,强烈推荐,每个项目都必备的权限管理技术!通过本课程,你将从零开始直到彻底掌握Shiro的相关开发知识,达到可以进行实际项目开发的能力。包括:权限管理基础、Shiro入门、配置、身份认证、授权、Realms、Session管理、和Spring的集成、Web、Cache等众多开发细节技术 技术要点:源码级分析Shiro的授权过程、自定义开发Realm、多个Realms的开发配置、自定义开发AuthenticationStrategy、自定义开发自定义SessionDAO、和Struts2+Spring3的集成(包括修正struts2的bug)、Shiro和SpringMVC+Spring3的集成、包装使用其他的Cache框架、缓存数据同步更新的解决方案等等实际开发中常用的内容

研磨设计模式——跟着cc学设计系列视频教程
本视频课程是北京Java私塾原创精品书籍《研磨设计模式》一书的配套学习视频,由《研磨设计模式》的第一作者CC录制 课程目标:全面、系统的掌握GoF设计模式的知识,达到可以在实际项目开发中运用的能力 技术要点:如何实现可配置、如何实现缓存以及缓存的管理、如何实现用缓存来控制多实例的创建、如何实现参数化工厂、 如何实现可扩展工厂、如何实现原型管理器、如何实现Java的静态代理和动态代理、如何实现多线程处理队列请求、 如何实现命令的参数化配置、可撤销的操作、宏命令、队列请求和日志请求、如何实现翻页迭代、如何检测环状结构、 如何实现通用的增删改查、如何模拟工作流来处理流程、如何实现简单又通用的XML读取、如何实现模拟AOP的功能......

ssh+jbpm项目(某集团OA)视频教程
达到能综合使用Struts2+Spring3+Hibernate3+Jbpm4来进行实际项目开发的能力。 包括:ssh和jbpm的整合;数据字典;通用DAO(Spring+Hibernate+泛型+反射+SpEL+模板方法模式);自动生成UUID的加强版;分层开发、SSH联合的基本开发;翻页的taglib;示范真实值和表现值,数据参照的实现;文件上传下载;主子表操;登录验证码;登录控制的拦截器

高级软件架构师实战培训阶段一
内容概述:本课程专注于构建:高可扩展性、高性能、大数据量、高并发、分布式的系统架构。 从零开始、全面系统、成体系的软件架构课程,循序渐进的讲述构建上述系统架构所需要的各种技术知识和技能。
技术要点: 1:构建基本的业务功能块,基于Maven+Git+Spring mvc+spring+mybatis+ehcache+mysql+X-gen代码生成
 2:高扩展性的分布式体系架构(基于Nginx+Varnish+Memcache+ActiveMQ)
 3:NoSQL的合理使用和架构优化(基于MongoDB)
 4:分布式文件存储和架构优化(基于MogileFS)

浏览(58786)|评论(0)   交流分类:Java|笔记分类: JAVA

评论(0)
请登录后评论 登录

关于我们 | 联系我们 | 用户协议 | 私塾在线服务协议 | 版权声明 | 隐私保护

版权所有 Copyright(C)2009-2012 私塾在线学习网