SameSite 문제 허용 설정

간단한 예로 외부 도메인에서 나의 도메인으로 POST 로 호출 할 경우 기존 나의 도메인 쿠키가 유지되지 않는 문제.
나의 경우문제 : 나의 도메인  -> 외부도메인 팝업 호출 -> 외부도메인에서 나의 도메인에 결과값을 넣어 POST로 호출
      - 이 경우 예전에는 브라우저에 나의 세션쿠키 정보가 남아 있어 누구의 결과값인지 바로 확인가 가능 했으나.
      - 크롬 80? 부터는 외부 도메인에서 POST로  호출지 쿠키 정보가 삭제됨.
              ( SameSite 속성의 기본 값을 "None"에서 "Lax"로 변경한 것 때문)
      - 이로인해 세션쿠키가 새로 발급되어 내가 누구인지를 읽어버림

그래서 외부 도메인의 POST 호출을 허용하긴위해서 SameSite ="None"으로 설정해야 합니다.
예시....

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


	@Bean
	public CookieSerializer cookieSerializer() {
		DefaultCookieSerializer serializer = new DefaultCookieSerializer();
		serializer.setCookieName("SESSION");
		
		serializer.setSameSite("None");
		serializer.setUseSecureCookie(true);
		return serializer;
	}


}

단 : None 설정시 http에서는 적용되지 않고 https(SSL) 적용된 경우만 적용이 된다고 합니다. (localhost는 적용됨)

자세한 사항은 제가 참고 했던 사이트를 확인해 주세요. ^^
아 그리고 부트 2.6 부터는 applications.yml 설정이 가능한 것 같습니다. 
저는 낮은 버전을 쓰고 있고. 버전을 올릴 수 없는 상태라 ^^

https://shanepark.tistory.com/349
 * https://github.com/spring-projects/spring-session/issues/1577
 * https://cublip.tistory.com/336

https://seob.dev/posts/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EC%BF%A0%ED%82%A4%EC%99%80-SameSite-%EC%86%8D%EC%84%B1/

 

Spring security 5.1.x에서 Crossorigin에서 요청시(결제모듈 등..) session cookie('SESSION' value) 초기화로 로그

spring boot를 2.1 이상으로 업데이트 하니(spring security 5.1 이상) lg uplus 결제모듈 호출 후 리턴값 받고나서 계속 로그인이 튕겨서 보니 세션값이 있는 쿠키가 계속 삭제되더라구요.. cors, csrf문제인가

cublip.tistory.com

 

Spring Session과 Cookie SameSite 정책

Intro SpringBoot 1.5 버전에서 2.5 버전으로 마이그레이션 작업이 대부분 완료 되었는데 SAML을 이용한 SSO 로그인 부분에서 굉장히 오래동안 해결하지 못하던 문제가 있었습니다. 분명 해당 부분의 코

shanepark.tistory.com

 

 

스프링 boot 버전이 올라 가면서 application.yml 로만 으로도 설정이 가능해 졌다고 합니다.
버전 높으시면 application.yml 찾아봐 주세요..

-----------------------------------------------------------------------------------------------

Spring Boot 를 이용해서 mysql+mybatis를 이용하여 application.yml 에 mysql 접속 정보 및
mybatis 설정을 하여 자동으로 SqlSession 을 사용해 사용 했습니다. 


이런 DB 두곳 접속 이슈가 발생 했습니다.
제가 못 찾은 건지 모르겠지만. 자동으로 멀티 데이터소스는 안되는 듯 해서 검색해서 열심히 찾아 작업을 해 보았습니다.

1. application.yml 에 db 접속정보 2개로 변경

1
2
3
4
5
6
7
8
9
10
11
12
13
spring:
    datasource1:
         driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
         jdbc-url: jdbc:log4jdbc:mysql:nananananan
         username: username
         password: password
         jmx-enabled: false
    datasource2:
         driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
         jdbc-url: jdbc:log4jdbc:mysql:nananananan
         username: username
         password: password
         jmx-enabled: false
cs


2. 우선 DataSourceConfig.java 파일을 만들어 DB 연결을 수동으로 처리 합니다. 
- Bean생성 할때 같은 종류의 Bean을 여러개 생성하면 오류 발생
- 처음 생성하는 Bean에 @Primary를 설정해야 복수게 생성 가능
  스프링부트는 기본적으로 DataSource 를 하나로 처리 하기 때문에   
  @Primary 설정을 해줘야 멀티로 잘 인식

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
 
@Configuration
@MapperScan(basePackages = {"com.pppp.tool"})
public class DataSourceConfig  {
 
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
 
    /** DataSource Main 생성 */
    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource1")
    public DataSource mysql1DataSource() {
        return DataSourceBuilder.create()
                .type(HikariDataSource.class)
                .build();
    }
 
    /** DataSource Sub 생성 */
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource2")
    public DataSource mysql2DataSource() {
        return DataSourceBuilder.create()
                .type(HikariDataSource.class)
                .build();
    }
 
    /** sqlSessionFactory Main 생성 */
    @Bean
    @Primary
    public SqlSessionFactory sqlSessionFactoryMain(@Autowired @Qualifier("mysql1DataSource") DataSource dataSource) throws Exception {
        logger.info("SqlSessionFactory Main Start");
        org.apache.ibatis.session.Configuration configuration = this.getMybatisConfig();
 
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        factoryBean.setVfs(SpringBootVFS.class);
        factoryBean.setConfiguration(configuration);
        factoryBean.setTypeHandlersPackage("com.commax.tool.framework.mybatis.typehandler");
 
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource[] resource = resolver.getResources("mybatis/**/*.xml");
        factoryBean.setMapperLocations(resource);
 
        return factoryBean.getObject();
    }
 
    /** sqlSessionFactory Sub 생성 */
    @Bean
    public SqlSessionFactory sqlSessionFactory(@Autowired @Qualifier("mysql2DataSource") DataSource dataSource) throws Exception {
        logger.info("SqlSessionFactory SUB Start");
        org.apache.ibatis.session.Configuration configuration = this.getMybatisConfig();
 
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        factoryBean.setVfs(SpringBootVFS.class);
        factoryBean.setConfiguration(configuration);
        factoryBean.setTypeHandlersPackage("com.commax.tool.framework.mybatis.typehandler");
 
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource[] resource = resolver.getResources("mybatis/**/*.xml");
        factoryBean.setMapperLocations(resource);
 
        return factoryBean.getObject();
    }
 
    /** sqlSession Main 생성 */
    @Bean
    @Primary
    public SqlSession sqlSessionMain(@Autowired @Qualifier("sqlSessionFactoryMain") SqlSessionFactory factory) {
        return new SqlSessionTemplate(factory);
    }
 
    /** sqlSession Sub 생성 */
    @Bean
    public SqlSession sqlSessionSub(@Autowired @Qualifier("sqlSessionFactory") SqlSessionFactory factory) {
        return new SqlSessionTemplate(factory);
    }
 
    /** MybatisConfig 설정정보 */
    private org.apache.ibatis.session.Configuration getMybatisConfig() {
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setCacheEnabled(true);
        configuration.setLazyLoadingEnabled(false);
        configuration.setAggressiveLazyLoading(false);
        configuration.setMultipleResultSetsEnabled(true);
        configuration.setUseColumnLabel(true);
        configuration.setAutoMappingBehavior(AutoMappingBehavior.PARTIAL);
        configuration.setDefaultExecutorType(ExecutorType.SIMPLE);
        configuration.setDefaultStatementTimeout(25000);
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setJdbcTypeForNull(JdbcType.NVARCHAR);
        configuration.setLazyLoadTriggerMethods(new HashSet<>(Arrays.asList("equals""clone""hashCode""toString")));
        configuration.setLogPrefix("[SQL]");
 
        return configuration;
    }
 
}
cs


3. 이제 그냥 사용 하시면 됩니다. 

1
2
3
4
5
6
7
    /** 메인DB 연결 */
    @Autowired @Qualifier("sqlSessionMain")
    protected SqlSession sqlSession;
 
    /** 서브DB 연결 */
    @Autowired @Qualifier("sqlSessionSub")
    protected SqlSession sqlSessionSub;
cs


* multi datasource 참고 블로그 
https://jodu.tistory.com/12
https://jojoldu.tistory.com/296
http://devgou.com/article/Spring-MyBatis/

+ Recent posts