SpringSecurity笔记3-Securing Methods
????? SpringSecurity方法层安全基于SpringAOP技术,它有自己的@Secured注解,SpringSecurity支持四种方法层
的安全:
????? (1) Methods annotated with @Secured.
????? (2) Methods annotated with JSR-250's @RolesAllowed.
????? (3) Methods annotated with Spring's pre- and post-invocation annotations.
????? (4) Methods matching one or more explicitly declared pointcuts.
????? 启用方法层注解
????? <global-method-security secured-annotations="enabled" />
1. Securing methods with @Secured
??? @Secured({"ROLE_SPITTER", "ROLE_ADMIN"})
??? public void addSpittle(Spittle spittle) {
?????????? // ...
??? }
??? 示例说明:指认证的用户必须被授予"ROLE_SPITTER", "ROLE_ADMIN"其中的一个权限才能访问该方法;如果没
??? 有这两个中任何一个权限将抛出异常或是AuthenticationException or AccessDeniedException的子异常。如
??? 果方法被在Web请求中调用,异常将被SpringSecurity自动调用。
2. Using JSR-250's @RolesAllowed
??? <global-method-security jsr250-annotations="enabled" />
??? JSR-250's @RolesAllowed与secured-annotations可同时被启用,推荐使用该方式启用注解,因为他是Java的
??? 标准注解。
3. Pre-/Post-invocation security with SpEL
??? <global-method-security pre-post-annotations="enabled" />
??? 主要有四个:
??? (1) @PreAuthorized: 基于表达式的结果在调用方法前限制方法被访问。
??? @PreAuthorize("hasRole('ROLE_SPITTER')")
??????????? public void addSpittle(Spittle spittle) {
??????????? // ...
???? }
??? 拥有角色ROLE_SPITTER的用户可以访问addSpittle方法。
??? @PreAuthorize("(hasRole('ROLE_SPITTER') and #spittle.text.length() <= 140)
?????????? or hasRole('ROLE_PREMIUM')")
???? public void addSpittle(Spittle spittle) {
??????????????? // ...
??? }
??? 拥有角色ROLE_SPITTER的用户的参数spittle字符只能少于140ge,而拥有角色ROLE_PREMIUM的用户则不受
??? 此限制。
??? (2) @PostAuthorized: 如果表达式结果为false,允许方法被调用,同时抛出一个安全异常。
??? 该注解主要是基于被保护的方法的返回值来决定执行表达式,例如:
??? @PostAuthorize("returnObject.spitter.username == principal.username")
??? public Spittle getSpittleById(long id) {
????????? // ...
??? }
??? 当返回的Spittle对象属于被认证的用户时才可以访问该方法,本例中returnObject是SpringEL提供的一个name
??? 用于方便获取返回的对象,而principal是SpringSecuroty提供的用于代表被当前认证的用户。如果认证失败,则
??? AccessDeniedException异常将抛出。
??? (3) @PostFilter:允许一个方法被调用,但是用每一个表达式去过滤方法的结果。
??? (4) @PreFilter: 允许一个方法被调用,但是过滤在进如方法之前的输入。
4. 声明方法层的安全切点
??? 用于同时给多个方法添加安全:
??? <global-method-security>
??? <protect-pointcut access="ROLE_SPITTER"? expression=
????????????? "execution(@com.habuma.spitter.Sensitive * *.*(String))"/>
??? </global-method-security>
??? 该配置将识别任何拥有@Sensitive的方法,而access属性则指,认证的用户必须拥有的角色去访问表达式识别的
??? 方法。