2016-07-02 36 views
0

私はクラスタ内でwebappを実行するために、春のセッションredisでCSRFトークンを追加しようとしています。redis springセッションのCSRFトークン

(旧バージョン用)

を両方の春のJavaのconfig/XMLのソリューションを必要とし、私はすでにセッション部分のためRedisHttpSessionConfigurationを使用しています(最初の段階でそれを実装)

マイWebSecurityConfigが

です
package com.groupon.website.config; 

import javax.servlet.FilterRegistration; 

import org.apache.logging.log4j.LogManager; 
import org.apache.logging.log4j.Logger; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Qualifier; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.core.annotation.Order; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 
import org.springframework.security.web.csrf.CsrfTokenRepository; 
import org.springframework.security.web.util.matcher.RequestMatcher; 

@EnableWebSecurity 
@Configuration 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

private Logger logger = LogManager.getLogger(WebSecurityConfig.class); 
@Autowired 
@Qualifier("csrfSecurityRequestMatcher") 
RequestMatcher csrfSecurityRequestMatcher; 

@Autowired 
@Qualifier("redisCsrfTokenRepository") 
private CsrfTokenRepository redisCsrfTokenRepository; 

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    logger.info("Inside WebSecurityConfig"); 

    //403 issue 


    http.headers().xssProtection().and().csrf().requireCsrfProtectionMatcher(csrfSecurityRequestMatcher) 
      .csrfTokenRepository(redisCsrfTokenRepository) 
     ; 

    } 

    } 

そしてCsrfTokenRepositoryはRedisCsrfTokenRepositoryある

package com.groupon.website.config; 


import java.util.UUID; 

import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import javax.servlet.http.HttpSession; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.beans.factory.InitializingBean; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Qualifier; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; 
import org.springframework.security.web.csrf.CsrfToken; 
import org.springframework.security.web.csrf.CsrfTokenRepository; 
import org.springframework.security.web.csrf.DefaultCsrfToken; 
import org.springframework.session.ExpiringSession; 
import org.springframework.session.data.redis.RedisOperationsSessionRepository; 
import org.springframework.stereotype.Component; 
import org.springframework.util.SerializationUtils; 

import redis.clients.jedis.Jedis; 

@Component 
public class RedisCsrfTokenRepository implements   CsrfTokenRepository,InitializingBean { 

private static final Logger log =   LoggerFactory.getLogger(RedisCsrfTokenRepository.class); 

public static final String CSRF_PARAMETER_NAME = "_csrf"; 

public static final String CSRF_HEADER_NAME = "X-CSRF-TOKEN"; 

@Value("${redis.host.name}") 
private String redisHostName; 
@Value("${redis.port}") 
private int redisPort; 

private Jedis tokenRepository; 

@Autowired 
private JedisConnectionFactory jedisConnectionFactory; 

//@Autowired 
//private RedisOperationsSessionRepository sessionRepository; 


public RedisCsrfTokenRepository() { 
    log.info("Creating {}", RedisCsrfTokenRepository.class.getSimpleName()); 

} 

@Override 
public CsrfToken generateToken(HttpServletRequest request) { 
    return new DefaultCsrfToken(CSRF_HEADER_NAME, CSRF_PARAMETER_NAME, createNewToken()); 
} 

@Override 
public void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response) { 
    String key = getKey(request); 
    if (key == null) 
     return; 

    if (token == null) { 
     //Use connection factory 
     //tokenRepository.del(key.getBytes()); 
     jedisConnectionFactory.getConnection().del(key.getBytes()); 
    } else { 
     //Use connection factory 
     //tokenRepository.set(key.getBytes(), SerializationUtils.serialize(token)); 
     jedisConnectionFactory.getConnection().set(key.getBytes(), SerializationUtils.serialize(token)); 
    } 

} 

@Override 
public CsrfToken loadToken(HttpServletRequest request) { 
    String key = getKey(request); 
    if (key != null) { 
     //Use connection factory 
     //byte[] tokenString = tokenRepository.get(key.getBytes()); 
     byte[] tokenString = jedisConnectionFactory.getConnection().get(key.getBytes()); 
     if (tokenString != null) { 
      return (CsrfToken) SerializationUtils.deserialize(tokenString); 
     } 
    } 
    return null; 
} 

private String getKey(HttpServletRequest request) { 

    //getKey going to be changed 
    HttpSession session = request.getSession(false); 
    //RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(redisConnectionFactory) 

    //ExpiringSession session = sessionRepository.getSession(request.getSession().getId()); 
    if (session == null) { 
     return null; 
    } 

    String result = session.getId()+CSRF_PARAMETER_NAME; 
    //String result = request.getHeader("X-CSRF-TOKEN"); 
    return result; 
} 

private String createNewToken() { 
    return UUID.randomUUID().toString(); 
} 

@Override 
public void afterPropertiesSet() throws Exception { 
    tokenRepository = new Jedis(redisHostName, redisPort, 30000); 
} 
} 

(tokenRpositoryが使用されていない、私はちょうどそれがあるように、コードを貼り付けコピーしていますが、jedisConnectionFatcoryが使用されている)

CSRFトークンが取得されていないことを示すためとして、私はまだ断続的に403を取得します。

Java設定のみが表示されています。誰か助けてもらえますか?

+0

@dsyerここでお手伝いできますか –

答えて

0

私たちは私たちが働いていたクッキーを使用していた

Cookie sessionCookies = WebUtil.getCookie (request, WebAppConstants.SESSION); 


if (sessionCookies == null || sessionCookies.getValue() == null) { 
    return null; 
} 

String sessionId = sessionCookies.getValue(); 

原因を使用している代わりに

HttpSession session = request.getSession(false); 

からキーを取得するために私たちのRedisCsrfTokenRepositoryを変更することによってそれを解決しています。

パイプラインでは、この変更が不要になるようにdefaultSessionFilterを変更してください。

関連する問題