Выражения, связанные с безопасностью, имеют довольно ограниченный набор операций в Spring. Вы можете расширить этот набор, предоставив пользовательскую реализацию интерфейса org.springframework.security.access.expression.SecurityExpressionOperations
. Вот краткое руководство, как это сделать:
- Создайте оболочку над
SecurityExpressionOperations
и выполните нужные операции:
class MySecurityExpressionOperations implements SecurityExpressionOperations {
private SecurityExpressionOperations delegate;
public MySecurityExpressionOperations(SecurityExpressionOperations delegate) {
this.delegate = delegate;
}
public boolean hasProducts() {
MyUser user = (MyUser) delegate.getAuthentication().getPrincipal();
return !user.getProductList().isEmpty();
}
// Other methods
}
- Расширить
org.springframework.security.web.access.expression.WebExpressionVoter
и заменить стандартный обработчик выражений:
class MyWebExpressionVoter extends WebExpressionVoter {
public MyWebExpressionVoter() {
setExpressionHandler(new DefaultWebSecurityExpressionHandler() {
@Override
protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, FilterInvocation fi) {
SecurityExpressionOperations delegate = super.createSecurityExpressionRoot(authentication, fi);
return new MySecurityExpressionOperations(delegate);
}
});
}
}
- Предоставление диспетчера принятия пользовательских решений для доступа:
<bean id="affirmativeBased" class="org.springframework.security.access.vote.AffirmativeBased">
<constructor-arg>
<list>
<bean class="my.company.MyWebExpressionVoter"/>
</list>
</constructor-arg>
</bean>
- Применить диспетчер принятия решений по индивидуальному доступу:
<http pattern="/**" use-expressions="true" access-decision-manager-ref="affirmativeBased">
<!-- ... -->
</http>
- Защита одного из URL-адресов с помощью дополнительной операции безопасности:
<intercept-url pattern="/products" access="hasProducts()"/>