SESSIONID注入用于基本身份验证请求

时间:2016-09-27 16:11:43

标签: spring-security

我有一个基于Spring-cloud的微服务应用程序。我在所有这些服务之前也有一个API网关。

我需要支持两种类型的客户端。

其中一个可以使用授权令牌调用我的应用程序(例如通过调用/授权)。令牌基本上是SESSION ID。所有服务器都使用Spring Session Redis共享会话。

第二个客户端只能向我发送http基本身份验证(用户:传递为授权头)。

对于第二个客户端,我需要检查用户是否已经过身份验证并且在redis中有一个活动会话。我在安全配置中的BasicAuthenticationFilter之前添加了过滤器来检查它。

如果用户有一个活动会话,我将SESSIONID放在头部,并从请求中删除授权头(我正在使用自定义的HttpServletRequest包装器)。我的目的是从那时起,Spring将在下游微服务中管理请求,就好像它是用SESSIONID发送的一样。原因是为了避免很长的登录时间(超过1秒)。

这是我的问题:当spring检查SESSIONID是否存在时,它会检查没有任何sessionId的原始请求。

安全配置:

@Resource
    @Qualifier("sessions")
    private Map<String, String> sessions;

    @Autowired
    @Qualifier("httpSessionStrategy")
    HttpSessionStrategy sessionStrategy;

@Override
protected void configure(HttpSecurity http) throws Exception {
    //      // @formatter:off

    http
    .addFilterBefore(setSessionIdInHeader(), BasicAuthenticationFilter.class)
    .sessionManagement()
    .and()
    .exceptionHandling()
    .authenticationEntryPoint(restEntryPoint())
    .and()
    .headers().addHeaderWriter(new StaticHeadersWriter("Server",""))
    .and()
    .httpBasic()
    .authenticationEntryPoint(restEntryPoint())
    .and()  
    .logout().addLogoutHandler(clearTicketOnLogoutHandler())
    .logoutSuccessHandler(logoutSuccessHandler())
    .and()
    .authorizeRequests()
    .antMatchers("/index.html", "/login", "/").permitAll()
    .antMatchers(HttpMethod.OPTIONS).denyAll()
    .antMatchers(HttpMethod.HEAD).denyAll()  
    .anyRequest().authenticated()
    .and()
    .authenticationProvider(authenticationProvider)
    .csrf()
    .disable()
    .addFilterAfter(ticketValidationFilter(), SessionManagementFilter.class)
    .addFilterAfter(changePasswordFilter(), SessionManagementFilter.class)  
    .addFilterAfter(httpPolutionFilter(), SessionManagementFilter.class)
    .addFilterAfter(saveSessionId(), SessionManagementFilter.class);

    // @formatter:on
}

过滤以向请求添加标头:

private Filter setSessionIdInHeader(){
        return new OncePerRequestFilter() {         
            @Override
            protected void doFilterInternal(HttpServletRequest request,
                    HttpServletResponse response, FilterChain filterChain)
                            throws ServletException, IOException {
                Jedis jedis = null;
                String authorization = request.getHeader("authorization");
                String sessionId = null;
                if (authorization != null){   
                    if (sessions.get(authorization) != null){   //user already authenticated
                        sessionId = sessions.get(authorization);
                        jedis = getJedisPool().getResource();
                        if (jedis.hgetAll("spring:session:sessions:"+sessionId) != null){  //session alive in redis
                            log.info("session :"+ sessionId +" exists in redis");
                            HeaderMapRequestWrapper wrapper = new HeaderMapRequestWrapper(request); 
                            wrapper.addHeader("TOKEN", sessionId);
                            wrapper.addHeader("mock_authorization", authorization);

                            filterChain.doFilter(wrapper, response);
                        }
                    }
                }
                filterChain.doFilter(request, response);
            }
        };
    } 

更改SESSIONID的标题名称:

@Bean
    public HeaderHttpSessionStrategy httpSessionStrategy(){
        HeaderHttpSessionStrategy headerHttpSessionStrategy = new HeaderHttpSessionStrategy();
        headerHttpSessionStrategy.setHeaderName("TOKEN");
        return headerHttpSessionStrategy;
    }



private Filter saveSessionId() {
        return new OncePerRequestFilter() {         
            @Override
            protected void doFilterInternal(HttpServletRequest request,
                    HttpServletResponse response, FilterChain filterChain)
                            throws ServletException, IOException {
                if(request.getHeader("authorization") != null){
                    sessions.put(request.getHeader("authorization"), request.getSession().getId());
                }else{
                    sessions.put(request.getHeader("mock_authorization"), request.getSession().getId());
                }

            }
        };
    }

0 个答案:

没有答案