Ответ 1
Существует не менее 4 различных способов:
spring Конфигурация безопасности XML
это самый простой способ
<security:http auto-config="true" use-expressions="true" ...>
...
<security:intercept-url pattern="/forAll/**" access="permitAll" />
<security:intercept-url pattern="/**" access="isAuthenticated()" />
</security:http>
- @see spring Справочник по безопасности, глава 16.1.1 Общие встроенные выражения
- @see spring Справочник по безопасности, глава 16.2 Выражения веб-безопасности
Per @Secured Annotation
требуется <global-method-security secured-annotations="enabled" />
@Secured("ROLE_ADMIN")
@RequestMapping(params = "onlyForAdmins")
public ModelAndView onlyForAdmins() {
....
}
Per @PreAuthorize Annotation
требуется <global-method-security pre-post-annotations="enabled" />
@PreAuthorize("isAuthenticated()")
@RequestMapping(params = "onlyForAuthenticated")
public ModelAndView onlyForAuthenticatedUsers() {
....
}
Programmatic
SecurityContextHolder.getContext().getAuthentication() != null &&
SecurityContextHolder.getContext().getAuthentication().isAuthenticated() &&
//when Anonymous Authentication is enabled
!(SecurityContextHolder.getContext().getAuthentication()
instanceof AnonymousAuthenticationToken)
Пользовательское выражение
Если встроенных выражений недостаточно, вы можете их расширить. Расширение выражений SpEL для аннотаций метода обсуждается здесь:
- Как создать пользовательские методы для использования в spring аннотациях выражения выражения безопасности
- http://bmchild.blogspot.de/2012/02/creating-custom-regex-spring-security.html
Но для перехватчика <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;
}
}
2.) вам нужно расширить DefaultWebSecurityExpressionRootHandler
, чтобы иметь обработчик, который предоставляет свой собственный пользовательский корень выражения
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" />
spring Обновление безопасности 3.1
Так как spring Security 3.1, это немного проще реализовать пользовательское выражение. Больше не требуется подкаска WebSecurityExpressionHandler
и переопределить createEvaluationContext
. Вместо этого один подкласс 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;
}
}