티스토리 뷰

728x90

인증 API - 동시 세션 제어

동시 세션 제어란?

동일한 계정으로 인증을 받을 때 생성되는 세션의 허용 개수가 초과되는 경우에 어떻게 세션을 유지하는 것에 대한 제어를 말한다.

최대 세션 허용 개수가 1개라고 가정

(1) 이전 사용자 세션 만료

  • 사용자 1이 로그인하고 서버에서 인증 성공 세션 생성
  • 사용자 2가 로그인하면 이전 사용자였던 사용자1의 세션을 만료시킴

(2) 현재 사용자 인증 실패

  • 사용자 1이 로그인하고 서버에서 인증 성공 세션 생성
  • 사용자 2가 로그인 하려고하면 인증 예외가 발생

@Override
protected void configure(HttpSecurity http) throws Exception {

    //동시 세션 제어
    http
            .sessionManagement()
            .maximumSessions(1)
            .maxSessionsPreventsLogin(false)
            .invalidSessionUrl("/invalid")
            .expiredUrl("/expired")
}

invalidSessionUrl과 expiredUrl 두 가지를 다 설정했을 경우에는 invalidSessionUrl이 우선순위를 갖는다.

인증 API - 세션 고정 보호

상황 설명

(1) 공격자가 웹 어플리케이션에 접속해서 JSESSIONID를 받음

(2) 사용자는 공격자의 세션쿠키를 사용해서 로그인 시도

(3) 웹 어플리케이션은 JSESSIONID 쿠키가 있으므로 인증 성공

(4) 공격자가 JSESSIONID 쿠키 값이 인증이 되어있기 때문에 사용자 정보를 공유받을 수 있다.

@Override
protected void configure(HttpSecurity http) throws Exception {

	http.sessionManagement()    //세션 관리 기능이 작동
        .sessionFixation()
        .changeSessionId(); //서블릿 3.1에서는 기본 값
}

changeSessionId가 기본 값으로 설정된다.  SessionManagementConfigure에 있는 내부 클래스 SessionFixationConfigurer에 정의되어있음.

public final class SessionFixationConfigurer {

	/**
	 * Specifies that a new session should be created, but the session attributes from
	 * the original {@link HttpSession} should not be retained.
	 * @return the {@link SessionManagementConfigurer} for further customizations
	 */
	public SessionManagementConfigurer<H> newSession() {
		SessionFixationProtectionStrategy sessionFixationProtectionStrategy = new SessionFixationProtectionStrategy();
		sessionFixationProtectionStrategy.setMigrateSessionAttributes(false);
		setSessionFixationAuthenticationStrategy(sessionFixationProtectionStrategy);
		return SessionManagementConfigurer.this;
	}

	/**
	 * Specifies that a new session should be created and the session attributes from
	 * the original {@link HttpSession} should be retained.
	 * @return the {@link SessionManagementConfigurer} for further customizations
	 */
	public SessionManagementConfigurer<H> migrateSession() {
		setSessionFixationAuthenticationStrategy(new SessionFixationProtectionStrategy());
		return SessionManagementConfigurer.this;
	}

	/**
	 * Specifies that the Servlet container-provided session fixation protection
	 * should be used. When a session authenticates, the Servlet method
	 * {@code HttpServletRequest#changeSessionId()} is called to change the session ID
	 * and retain all session attributes.
	 * @return the {@link SessionManagementConfigurer} for further customizations
	 */
	public SessionManagementConfigurer<H> changeSessionId() {
		setSessionFixationAuthenticationStrategy(new ChangeSessionIdAuthenticationStrategy());
		return SessionManagementConfigurer.this;
	}

	/**
	 * Specifies that no session fixation protection should be enabled. This may be
	 * useful when utilizing other mechanisms for protecting against session fixation.
	 * For example, if application container session fixation protection is already in
	 * use. Otherwise, this option is not recommended.
	 * @return the {@link SessionManagementConfigurer} for further customizations
	 */
	public SessionManagementConfigurer<H> none() {
		setSessionFixationAuthenticationStrategy(new NullAuthenticatedSessionStrategy());
		return SessionManagementConfigurer.this;
	}

}

인증 API - 세션 정책

설정

@Override
protected void configure(HttpSecurity http) throws Exception {
    
    http.sessionManagement()    //세션 관리 기능이 작동
	    .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
}

ALWAYS: 스프링 시큐리티가 항상 세션 생성

IF_Required: 스프링 시큐리티가 필요 시 생성(기본 값)

Never: 스프링 시큐리티가 생성하지 않지만 이미 존재하면 사용

Stateless: 스프링 시큐리티가 생성하지 않고 존재해도 사용하지 않음.

 

Stateless 설정이 세션, 쿠키로 인증을 하는 방식이 아니라 다른 인증을 사용할 때 사용한다. 예를 들어 jwt 토큰

/**
 * Specifies the various session creation policies for Spring Security.
 *
 * @author Luke Taylor
 * @since 3.1
 */
public enum SessionCreationPolicy {

	/**
	 * Always create an {@link HttpSession}
	 */
	ALWAYS,

	/**
	 * Spring Security will never create an {@link HttpSession}, but will use the
	 * {@link HttpSession} if it already exists
	 */
	NEVER,

	/**
	 * Spring Security will only create an {@link HttpSession} if required
	 */
	IF_REQUIRED,

	/**
	 * Spring Security will never create an {@link HttpSession} and it will never use it
	 * to obtain the {@link SecurityContext}
	 */
	STATELESS

}

Q&A

Q. 세션, 쿠키가 생성되는 조건은 로그인 같은 이벤트를 통해 인증 절차를 받아야 사용자 세션이 생기고 세션ID를 클라이너트 쿠키에 담아주는 것 아닌가요?

더보기

세션ID 는 클라이언트가 서버에 접속하게 되면 세션쿠키 형태로 발급이 됩니다.

서블릿에서는 JSESSIONID 로 생성합니다.

일반적으로 세션 ID 는 인증과는 무관합니다.

인증은 세션 ID 를 가진 사용자가 본인이 맞는지를 검증하는 단계이지 서버가 인증유무에 따라 세션 ID 를 발급하는 것은 아닙니다.

서버에서는 클라이언트에서 가지고 온 세션 ID 를 기준으로 해서 세션영역에 저장된 여러가지 속성들을 관리합니다.

거기에 로그인 관련된 정보도 포함됩니다.

한가지 기억하실 점은 세션 ID 는 웹 환경일 경우에는 WAS 가 생성을 합니다. 

스프링 시큐리티가 직접 생성을 하지 않더라고 WAS 단에서 먼저 생성을 하기 때문에 브라우저 전달을 한다고 볼 수 있습니다.

스프링 시큐리티는 기본적으로 인증을 하지 않거나 세션을 생성하지 않는 정책을 설정 할 경우 세션을 생성하지 않습니다. 하지만 만약 WAS 가 세션을 생성하거나 다른 영역에서 세션을 생성할 경우 그 세션을 사용합니다.

참고하시기 바랍니다.

Q. 세션 생성

더보기

일반적으로 세션을 WAS 가 먼저 생성을 합니다.

스프링 시큐리티는 세션을 참조할 때 기본적으로는 request.getSession(false) 입니다.

즉 세션을 가지고 오는데 세션이 있으면 참조하고 없으면 null 을 받습니다.

이 때 톰캣이 세션을 먼저 생성했다면 그 세션을 인증 유무에 관계 없이 그냥 이용한다는 의미로 보시면 됩니다.

그런데 만약에 아무데서도 세션을 생성하거나 존재하지 않았다고 가정한다면 스프링 시큐리티는 인증을 성공한 경우 request.getSession(true) 로 전환되어 직접 세션을 생성한다고 보시면 됩니다.

참고

https://www.inflearn.com/course/%EC%BD%94%EC%96%B4-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0/dashboard

 

스프링 시큐리티 - Spring Boot 기반으로 개발하는 Spring Security - 인프런 | 강의

초급에서 중.고급에 이르기까지 스프링 시큐리티의 기본 개념부터 API 사용법과 내부 아키텍처를 학습하게 되고 이를 바탕으로 실전 프로젝트를 완성해 나감으로써 스프링 시큐리티의 인증과

www.inflearn.com

 

728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
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
글 보관함