注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

无线时代辐射无穷

抓紧生宝宝,小心辐射

 
 
 

日志

 
 

Spring Security-3.0.0升级  

2009-12-19 10:32:18|  分类: spring |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Spring Security于2009-05-27发布。

Spring Security从2.0.x一跃而至3.0.0.M1,这第一个里程碑里主要有三点值得我们注意:

  • 支持Spring-3.0.0.M3,现在只能在JDK-5.0以上环境使用,不再支持JDK-1.4以及之前的版本。

  • 大量重构代码结构,将核心库core,命名空间config,web验证部分都严格的分成独立的模块,不再像以前一样把所有代码都混放放core中。

  • 支持Expression,现在无论是命名空间,配置文件,taglib中都可以使用表达式来指定需要的配置了。

C.1. Hello World

使用Spring Security-3.0.0.M1制作了一个Helloworld,不需要修改项目中的任何配置就可以正常运行,这点上很佩服Spring系列的兼容性。

实例在x01下。

C.2. Spring-EL

下面详细介绍一下Spring Security 3中最新支持的Spring-EL表达式。

如果在配置中启用Spring-EL表达式功能,只要为http标签配置一个参数即可。

<http auto-config="true" use-expressions="true">      <intercept-url pattern="/admin.jsp" access="hasRole('ROLE_ADMIN') and hasIpAddress('192.168.1.0/24')" />      <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />  </http>          

唯一的问题就是,如果启用了Spring-EL就不能再使用原来的方式了,所有的权限都要使用Spring-EL表达,否则会在访问被保护资源时抛出无法解析Spring-EL的异常。

既然说到Spring-EL就不能不提Spring Security-3.0.0.M1中新支持的Pre-Post注解,它是用来替代MethodInvocationInterceptor和AfterInvocationInterceptor一套新注解。

启用Pre-Post注解

<global-method-security secured-annotations="enabled"                          pre-post-annotations="enabled">      <expression-handler ref="expressionHandler"/>  </global-method-security>          

调用前权限控制。

拥有ROLE_USER或ROLE_ADMIN才能调用save()方法。

@PreAuthorize("hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')")  public void save(String messageContent, String owner) {      // ...  }          

参数message的owner属性与principal的name属性相同才允许调用modifyMessage()方法。

@PreAuthorize("#message.owner == principal.name")  public void modifyMessage(Message message, String messageContent) {      // ...  }          

拥有对message的acl管理权限才可以调用deleteMessage()方法。

@PreAuthorize("hasPermission(#message, 'admin')")  public void deleteMessage(Message message) {      // ...  }          

调用后权限控制。

判断是否有权返回对象,拥有对返回对象的read或admin的acl权限才可以查看Message对象。

@PostAuthorize("hasPermission(returnObject, 'read') or hasPermission(returnObject, 'administration')")  public Message get(Long id) {      // ...  }          

将返回集合对象中无权限的信息过滤掉。将List中不符合不具有read或admin的acl权限的对象从list过滤掉。

@PostFilter("hasPermission(filterObject, 'read') or hasPermission(filterObject, 'administration')")  public List getAll() {      // ...  }          

Spring-EL十分强大,这样应用也比使用MethodInvocationInterceptor和AfterInvocationInterceptor更清晰便捷。

实例在x02下。

C.3. RoleHierarchy

这个问题后来发现是因为wesee同志搞错了,想用Role继承实现User继承的功能。实际上Sid中实现Rolehierarchy应该是没有任何意义的,反倒是user继承应该还有点儿意思。

使用RoleHierarchy的实例在x03下。

C.4. Success Handler

为了实现更好的扩展性,3.x中开始专门提供了AuthenticationSuccessHandler和AuthenticationFailureHandler,用这两者控制用户认证成功和失败的情况。我们可以自己实现successHandler,在用户登录成功之后向session中任意放任何东西了。

public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,          Authentication authentication) throws ServletException, IOException {        HttpSession session = request.getSession();      UserDetails userDetails = (UserDetails) authentication.getPrincipal();      if (userDetails.getUsername().equals("user")) {          session.setAttribute("email", "user@163.com");      } else if (userDetails.getUsername().equals("admin")) {          session.setAttribute("email", "admin@163.com");      }        super.onAuthenticationSuccess(request, response, authentication);  }          

实例在x04下。

C.5. REST下的权限控制

RESTful是蛮流行的一种web资源访问方式,它最大限度利用了http协议的功能表达资源请求的内涵。

  • GET /app/messages:表示获得所有Message的信息。

  • GET /app/messages/1:表示获得id=1的Message的信息。

  • POST /app/messages:表示创建一条Message信息。

  • PUT /app/messages/1:表示更新id=1的Message的信息。

  • DELETE /app/messages/1:表示删除id=1的Message的信息。

从上面的例子中可以看出来,我们只用了/app/messages和/app/messages/*两类URL,就表示了Message的CRUD所有操作。这时如果我们希望对这些操作进行权限控制,就不能仅仅根据URL地址来判断了,而是需要限制http请求的method参数。

下面我们对这些操作做出限制,只有ROLE_ADMIN才能添加,更新,删除Message,ROLE_USER只能查看Message的信息。

<http auto-config='true'>      <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" />      <intercept-url pattern="/app/messages" access="ROLE_ADMIN" method="POST" />      <intercept-url pattern="/app/messages/*" access="ROLE_ADMIN" method="PUT" />      <intercept-url pattern="/app/messages/*" access="ROLE_ADMIN" method="DELETE" />      <intercept-url pattern="/**" access="ROLE_USER" />  </http>          

在intercept-url中使用method指定对应的http请求method参数就可以限制REST下定义的不同功能请求了,可以每次只能定义一个method,如果支持method="PUT,DELETE"这种形式的配置就更方便了。

  评论这张
 
阅读(1737)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017