Method Security 通过JSR-250或Spring注解、或AspectJ的pointcuts,对Service层的Method进行Security控制。
Method Security的配置比较简单,只需在Context中定义标签<global-method-security> 即可 ,<global-method-security>对本Cotext的bean有效。
一、Method Security提供四种配置:
1、@Secured注解
<global-method-security secured-annotations="enabled" />
public interface BankService { @Secured("IS_AUTHENTICATED_ANONYMOUSLY") public Account readAccount(Long id); @Secured("IS_AUTHENTICATED_ANONYMOUSLY") public Account[] findAccounts(); @Secured("ROLE_TELLER") public Account post(Account account, double amount); }
2、JSR-250 annotations支持
<global-method-security jsr250-annotations="enabled" />
3、expression-based syntax
<global-method-security pre-post-annotations="enabled" />
public interface BankService { @PreAuthorize("isAnonymous()") public Account readAccount(Long id); @PreAuthorize("isAnonymous()") public Account[] findAccounts(); @PreAuthorize("hasAuthority('ROLE_TELLER')") public Account post(Account account, double amount); }
4、protect-pointcut
protect-pointcut可同时对多个Bean方法进行权限配置
<global-method-security> <protect-pointcut expression="execution(* com.mycompany.*Service.*(..))" access="ROLE_USER"/> </global-method-security>
二、Method Security 的认证(Authentication)与授权(Authorization)失败处理
Method Security并不是在Filter中进行Access Decision,而是在DispatcherServlet的AOP中进行。所以异常可通过Spring MVC的统一异常提醒捕捉到。
在Method Security中,无论是未认证或无权访问的异常都只是会抛出AccessDeniedException异常。
因为,对于未认证的请求,在FilterChainProxy的Filter运行后中会生成一个匿名(Anonymous)Authentication对象,在做是否有权访问判定时,就用Anonymous的Authentication进行权限判定,所以就只有AccessDeniedException。
所以要区分是Authentication异常还是Authorization异常,需要借用AuthenticationTrustResolver类的isAnonymous(Authentication)方法,判定当前是否为Anonymous。