Spring MVC-检查用户是否已经通过Spring Security登录?
我有一个Spring MVC应用程序。它使用自己的自定义登录页面。成功登录后,在HTTPSession中放置一个“ LOGGED_IN_USER”对象。
我只允许经过身份验证的用户访问URL。我知道我可以通过使用网络过滤器来实现。但是,这部分是我想使用Spring Security要做的(我的检查将保持不变-如果已登录,请在HTTPSession中查找’LOGGED_IN_USER’对象)。
我的约束是我目前无法更改登录行为-不会使用Spring Security。
我可以使用Spring Security的哪个方面单独实现这一部分-检查请求是否已通过身份验证(来自登录用户)?
回答:
至少有4种不同的方式:
这是最简单的方法
<security:http auto-config="true" use-expressions="true" ...> ...
<security:intercept-url pattern="/forAll/**" access="permitAll" />
<security:intercept-url pattern="/**" access="isAuthenticated()" />
</security:http>
要求 <global-method-security secured-annotations="enabled" />
@Secured("ROLE_ADMIN")@RequestMapping(params = "onlyForAdmins")
public ModelAndView onlyForAdmins() {
....
}
要求 <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
(Prefix 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 Security 3.1更新
从Spring Security 3.1开始,实现自定义表达式要容易一些。一个不再需要sublcass WebSecurityExpressionHandler
和override createEvaluationContext
。取而代之的是一个sublas 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;
}
}
以上是 Spring MVC-检查用户是否已经通过Spring Security登录? 的全部内容, 来源链接: utcz.com/qa/423891.html