少なくとも4つの異なる方法があります。
春のセキュリティXML構成
これが最も簡単な方法です
<security:http auto-config="true" use-expressions="true" ...>
...
<security:intercept-url pattern="/forAll/**" access="permitAll" />
<security:intercept-url pattern="/**" access="isAuthenticated()" />
</security:http>
@Securedアノテーションごと
必要<global-method-security secured-annotations="enabled" />
@Secured("ROLE_ADMIN")
@RequestMapping(params = "onlyForAdmins")
public ModelAndView onlyForAdmins() {
....
}
@PreAuthorizeアノテーションごと
必要<global-method-security pre-post-annotations="enabled" />
@PreAuthorize("isAuthenticated()")
@RequestMapping(params = "onlyForAuthenticated")
public ModelAndView onlyForAuthenticatedUsers() {
....
}
プログラマティック
SecurityContextHolder.getContext().getAuthentication() != null &&
SecurityContextHolder.getContext().getAuthentication().isAuthenticated() &&
//when Anonymous Authentication is enabled
!(SecurityContextHolder.getContext().getAuthentication()
instanceof AnonymousAuthenticationToken)
カスタム式
組み込みの式では不十分な場合は、それらを拡張できます。メソッドアノテーションのSpEL式を拡張する方法については、たとえば次のように説明します。
しかし、インターセプターの<security:intercept-url ... access="myCustomAuthenticatedExpression" />
場合、プライベートクラスの問題に対処する必要がない、わずかに異なるアプローチが可能です。--Spring Security 3.0でのみ実行しましたが、3.1でも機能することを願っています。
1.)から拡張する新しいクラスを作成する必要がありますWebSecurityExpressionRoot
(プレフィックスWebは重要な部分です!)。
public class MyCustomWebSecurityExpressionRoot
extends WebSecurityExpressionRoot {
public MyCustomWebSecurityExpressionRoot(Authentication a,
FilterInvocation f) {
super(a, f);
}
/** That method is the one that does the expression evaluation! */
public boolean myCustomAuthenticatedExpression() {
return super.request.getSession().getValue("myFlag") != null;
}
}
DefaultWebSecurityExpressionRootHandler
2.)カスタム式のルートを提供するハンドラーを作成するには、を拡張する必要があります
public class MyCustomWebSecurityExpressionHandler
extends DefaultWebSecurityExpressionHandler {
@Override
public EvaluationContext createEvaluationContext(Authentication a,
FilterInvocation f) {
StandardEvaluationContext ctx =
(StandardEvaluationContext) super.createEvaluationContext(a, f);
WebSecurityExpressionRoot myRoot =
new MyCustomWebSecurityExpressionRoot(a, f);
ctx.setRootObject(myRoot);
return ctx;
}
}
3.)次に、ハンドラーを有権者に登録する必要があります
<security:http use-expressions="true"
access-decision-manager-ref="httpAccessDecisionManager" ...>
...
<security:intercept-url pattern="/restricted/**"
access="myCustomAuthenticatedExpression" />
...
</security:http>
<bean id="httpAccessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<constructor-arg name="decisionVoters">
<list>
<ref bean="webExpressionVoter" />
</list>
</constructor-arg>
</bean>
<bean id="webExpressionVoter"
class="org.springframework.security.web.access.expression.WebExpressionVoter">
<property name="expressionHandler"
ref="myCustomWebSecurityExpressionHandler" />
</bean>
<bean id="myCustomWebSecurityExpressionHandler"
class="MyCustomWebSecurityExpressionHandler" />
SpringSecurity3.1アップデート
Spring Security 3.1以降、カスタム式の実装が少し簡単になりました。sublcassWebSecurityExpressionHandler
してオーバーライドする必要はもうありませんcreateEvaluationContext
。代わりに、1つAbstractSecurityExpressionHandler<FilterInvocation>
のサブクラスまたはそのサブクラスDefaultWebSecurityExpressionHandler
とオーバーライドSecurityExpressionOperations createSecurityExpressionRoot(final Authentication a, final FilterInvocation f)
。
public class MyCustomWebSecurityExpressionHandler
extends DefaultWebSecurityExpressionHandler {
@Override
public SecurityExpressionOperations createSecurityExpressionRoot(
Authentication a,
FilterInvocation f) {
WebSecurityExpressionRoot myRoot =
new MyCustomWebSecurityExpressionRoot(a, f);
myRoot.setPermissionEvaluator(getPermissionEvaluator());
myRoot.setTrustResolver(this.trustResolver);
myRoot.setRoleHierarchy(getRoleHierarchy());
return myRoot;
}
}