【问题标题】:spring security - access request parameters inside UserDetailsService implementationspring security - 在 UserDetailsS​​ervice 实现中访问请求参数
【发布时间】:2016-08-12 17:19:59
【问题描述】:

我正在开发一个 java spring mvc 应用程序。我已经实现了这样的UserDetailsService 接口:

@Component
@Transactional
public class SecurityDAO implements UserDetailsService{

     @Override
     public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {
         ...
     }

     ....
}

我需要在loadUserByUsername方法中找到用户登录url(因为项目有多个登录url)。其实我想访问UserDetailsService实现里面的请求参数。

【问题讨论】:

    标签: java spring-mvc spring-security


    【解决方案1】:

    简单的方法: 1) 注册RequestContextListener

    @Bean
    public RequestContextListener requestContextListener(){
    return new RequestContextListener();
    }
    

    2) 到主类:

    HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.
    currentRequestAttributes()).
    getRequest();
    

    3) 之后我们可以在自定义标题中获取参数:

    request.getHeader("OrganizationId")
    

    【讨论】:

      【解决方案2】:

      所有信息都可以通过HttpServletRequest 获得。您可以通过以下方式获得它:

      依赖注入

      最简单的方法是将 servlet 请求直接注入您的 UserDetailsService: 类:

      public MyDetailsService implements UserDetailsService {
      
        @Autowired
        private HttpServletRequest request;
      
        //...
      
      }
      

      public MyDetailsService implements UserDetailsService {
      
        @Autowired
        private HttpServletRequest request;
      
          public UserDetails loadUserByUsername(String username){
                      HttpServletRequest request  =
                   ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes())
                          .getRequest();
          }
      
      }
      

      如果您不是 Spring Boot,请记住将以下侦听器添加到您的 web.xml

      <listener>
          <listener-class>
              org.springframework.web.context.request.RequestContextListener
          </listener-class>
      </listener>
      

      如果你使用的是spring boot,请在下面添加。

      @Bean 
      public RequestContextListener requestContextListener(){
          return new RequestContextListener();
      }
      

      更新:这是因为 Spring 注入了实现HttpServletRequest 的特殊作用域代理,因此您可以从单例作用域MyDetailsService 访问请求作用域的请求“bean”。在后台,每次调用request 的参数都会被路由到org.springframework.web.context.request.RequestContextHolder#requestAttributesHolder ThreadLocal,您也可以直接访问它。如您所见,Spring 在范围规则方面非常灵活。它只是工作。

      RequestContextHolder

      另一种方法是使用RequestContextHolder

      HttpServletRequest request = 
        ((ServletRequestAttributes) RequestContextHolder.
          currentRequestAttributes()).
          getRequest();
      

      延伸阅读:

      【讨论】:

        【解决方案3】:

        只需将请求注入您的服务:

         @Autowired
         private HttpServletRequest request;
        

        要让它工作,您需要事先注册 RequestContextListener:

        @Bean 
        public RequestContextListener requestContextListener(){
            return new RequestContextListener();
        } 
        

        【讨论】:

        • 原因java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request...
        • 您没有声明RequestContextListener。你在使用 Spring Boot 吗?
        • 不,我不使用弹簧靴。我在 SecurityConfig 类中声明了 RequestContextListener
        • 你也碰巧在使用 web.xml 吗?
        • 在这种情况下,使用&lt;listener-class&gt;org.springframework.web.context.request.RequestContextListener&lt;/listener-class&gt; 添加一个新的监听器。
        【解决方案4】:

        您可以通过

        获取当前请求
        HttpServletRequest request  =
         ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes())
                .getRequest();
        

        然后从那里访问请求参数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-10-27
          • 2013-05-12
          • 2018-10-25
          • 2012-12-25
          • 2011-09-01
          • 2012-06-11
          • 2020-01-03
          • 1970-01-01
          相关资源
          最近更新 更多