Spring MVC - 检查用户是否已经通过 Spring Security 登录? [英] Spring MVC - Checking if User is already logged in via Spring Security?

查看:39
本文介绍了Spring MVC - 检查用户是否已经通过 Spring Security 登录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Spring MVC 应用程序.它使用自己的自定义登录页面.成功登录后,会在 HTTPSession 中放置一个LOGGED_IN_USER"对象.

I have a Spring MVC application.It uses its own custom Login page. Upon successful login, a 'LOGGED_IN_USER' object is placed in the HTTPSession.

我想只允许经过身份验证的用户访问 URL.我知道我可以通过使用网络过滤器来实现这一点.但是,这部分我想使用 Spring Security 来完成(我的检查将保持不变 - 在 HTTPSession 中查找LOGGED_IN_USER"对象,如果您已登录).

I want to allow only authenticated users to access URLs. I know i can achieve this by using a web filter. But, This part i want to do using Spring Security (my check will remain the same - look for 'LOGGED_IN_USER' object in HTTPSession, if present you are logged in).

我的限制是我目前无法更改登录行为 - 还不会使用 Spring Security.

我可以使用 Spring Security 的哪些方面来单独实现这一部分 - 检查请求是否经过身份验证(来自登录用户)?

推荐答案

至少有 4 种不同的方式:

There are at least 4 different ways:

这是最简单的方法

<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 Security Reference, Chapter 16.1.1 Common Built-In Expressions
  • @see Spring Security Reference, Chapter 16.2 Web Security Expressions
  • 需要

    @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 表达式:


    Custom Expression

    If the built-in expressions are not enough, you can extend them. How to extend the SpEL Expressions for the method annotations is discussed for example here:

    但是对于拦截器 <security:intercept-url ... access="myCustomAuthenticatedExpression"/> 可能有一种稍微不同的方法,不需要处理私有类问题.-- 我只为 Spring Security 3.0 做过,但我希望它也适用于 3.1.

    But for the interceptor <security:intercept-url ... access="myCustomAuthenticatedExpression" /> there is a slightly different approach possible, that does not need to deal with the private class problem. -- I have only done it for Spring Security 3.0, but I hope it works for 3.1 too.

    1.) 您需要创建一个从 WebSecurityExpressionRoot 扩展的新类(前缀 Web 是重要的部分!).

    1.) you need to create a new class that extends from WebSecurityExpressionRoot (Prefix Web is the important part!).

    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 以拥有一个提供自定义表达式根的处理程序

    2.) you need a extend the DefaultWebSecurityExpressionRootHandler to have a handler that provides your custom expression root

     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.) 然后你需要向选民登记你的处理程序

    3.) Then you need to register your handler with the voters

    <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 开始,实现自定义表达式更容易一些.一个不再需要子类WebSecurityExpressionHandler 和覆盖createEvaluationContext.取而代之的是一个子类 AbstractSecurityExpressionHandler 或其子类 DefaultWebSecurityExpressionHandler 并覆盖 SecurityExpressionOperations createSecurityExpressionRoot(final Authentication a, final FilterInvocation f).

    Since Spring Security 3.1 it is a bit easier to implement a custom expression. One does not longer need to sublcass WebSecurityExpressionHandler and override createEvaluationContext. Instead one sublass AbstractSecurityExpressionHandler<FilterInvocation> or its subclass DefaultWebSecurityExpressionHandler and override 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 登录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆