[Spring Security] 기본 API 이해

재호·2022년 7월 12일
0

스프링 시큐리티

목록 보기
1/1

사용 준비

의존성
== maven (pom.xml)
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

== gradle (build.gradle)
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-security'
SecurityConfig 생성

SecurityConfig라는 이름으로 클래스를 생성한다. 이는 사용자 정의 보안 클래스 용도이다.

@EnableWebSecurity
@Configuration(proxyBeanMethods = false)
@ConditionalOnDefaultWebSecurity
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
public class SecurityConfig{

	@Bean
    @Order(SecurityProperties.BASIC_AUTH_ORDER)
    protected SecurityFilterChain filterChain(HttpSecurity http) throws  Exception {
        http
                .authorizeRequests() 
                .anyRequest().authenticated(); //모든 요청에 대해 인증을 하도록 하는 설정
        htto
        		.formLogin(); // 스프링 시큐리티 로그인 방식을 폼로그인 방식으로 설정
                
        return http.build();
    }
}

스프링 시큐리티 버전이 올라가면서 설정 방법이 조금 바뀌었다. 기존에는 스프링 시큐리티의 WebSecurityConfigurerAdapter 를 상속받아 사용했었지만 이제 스프링은 이를 권장하지 않는다. 대신 SecurityFilterChain을 사용하도록 권장한다. 사용방법은 위와 같은데 이때 주의할 점은 클래스 레벨에 @ConditionalOnDefaultWebSecurity@ConditionalOnWebApplicaiton 어노테이션과 메소드 레벨에 @Order 어노테이션을 적용해야 한다는 것이다. 스프링 시큐리티 의존성을 주입하면 스프링이 자체적으로 SecurityFilterChain의 빈을 생성해 놓기 때문에 그것과 충돌을 일으키지 않도록하는 설정인 것이다.

인증 API

Form Login 인증

http.formLogin()
	.loginPage("/login.html")   				// 사용자 정의 로그인 페이지
    .defaultSuccessUrl("/home")					// 로그인 성공 후 이동 페이지
    .failureUrl("/login.html?error=true")		// 로그인 실패 후 이동 페이지
    .usernameParameter("username")				// 아이디 파라미터명 설정
    .passwordParameter("password")				// 패스워드 파라미터명 설정
    .loginProcessingUrl("/login")				// 로그인 Form Action Url
    .successHandler(loginSuccessHandler())		// 로그인 성공 후 핸들러
    .failureHandler(loginFailureHandler())		// 로그인 실패 후 핸들러

formLogin()에 대한 상세 설정 부분이다. 핸들러 부분은 익명 클래스를 사용해 좀더 세밀한 로직을 설정할 수 있다.

Logout

http.logout()						// 로그아웃 처리
	.logoutUrl(/logout")				// 로그아웃 처리 URL
    .logoutSuccessUrl(/login")			// 로그아웃 성공 후 이동페이지
    .deleteCookies("JSESSIONID“, "remember-me") 	// 로그아웃 후 쿠키 삭제
    .addLogoutHandler(logoutHandler())		 // 로그아웃 핸들러
    .logoutSuccessHandler(logoutSuccessHandler()) 	// 로그아웃 성공 후 핸들러

Remember Me

http.rememberMe()
	.rememberMeParameter(“remember”) // 기본 파라미터명은 remember-me
    .tokenValiditySeconds(3600) // Default 는 14일
    .alwaysRemember(true) // 리멤버 미 기능이 활성화되지 않아도 항상 실행
    .userDetailsService(userDetailsService)

리멤버미는 자동 로그인 기능을 의미한다. 로그아웃을 통해 로그인에 대한 쿠키가 삭제되더라도 remember me 쿠키에 대한 Http 요청을 확인한 후 토큰 기반 인증을 사용해 유효성을 검사하고 로그인이 되는 방식이다.

Remember Me 설정을 하고나면 로그인 화면에 체크박스가 나타나는 걸 확인할 수 있다.

SessionManagement

동시 세션 제어
http.sessionManagement()
	.maximumSessions(1)                 // 최대 허용 가능 세션 수 , -1 : 무제한 로그인 세션 허용
    .maxSessionsPreventsLogin(true) // 동시 로그인 차단함,  false : 기존 세션 만료(default)
    .invalidSessionUrl("/invalid")       // 세션이 유효하지 않을 때 이동 할 페이지
    .expiredUrl("/expired ")  	        // 세션이 만료된 경우 이동 할 페이지

사용자의 동시 접속을 제어하는 기능이다. 세션 허용 개수를 설정하고 만약 동시에 이 수를 초과하는 요청이 들어온다면 두 가지의 방법으로 이를 제어할 수 있다.

  1. 이전 사용자 세션 만료
  2. 현재 사용자 인증 실패
세션 고정 보호

스프링 시큐리티는 세션 고정 공격에 대한 보안 기능을 제공한다.
세션이 고정적이라면 외부 공격에 대해 취약하기 때문에 이에 대한 기능을 기본적으로 제공한다.

http.sessionManagement()
	.sessionFixation().changeSessionId() // 기본값
							    		// none, migrateSession, newSession

요청이 생길 때 마다 세션을 생성하지만 세션의 설정 값은 그대로 적용해주는 changeSessionId()가 기본값이고 none은 세션을 고정하는 것이고 newSession은 세션을 새로 생성하면서 설정값도 새로 만드는 것이다.

세션 정책
http.sessionManagement()
	.sessionCreationPolicy(SessionCreationPolicy. If_Required )
  • SessionCreationPolicy. Always : 스프링 시큐리티가 항상 세션 생성
  • SessionCreationPolicy. If_Required : 스프링 시큐리티가 필요 시 생성(기본값)
  • SessionCreationPolicy. Never : 스프링 시큐리티가 생성하지 않지만 이미 존재하면 사용
  • SessionCreationPolicy. Stateless : 스프링 시큐리티가 생성하지 않고 존재해도 사용하지 않음

인가 API

권한 설정

선언적 방식
  • URL
  • Method
동적 방식 - DB 연동 프로그래밍
  • URL
  • Method

권한 설정은 이후 진행될 실습에서 DB와 연동하여 자세하게 다룰 것이다.

인증/인가 API

예외처리 (ExceptionTranslationFilter)

AuthenticationException

RequestCache를 이용해 인증 예외가 발생하기 전의 요청 정보를 저장한다. 예를 들어 비회원으로 장바구니로 이동했더니 인증이 되어있지 않아 로그인 페이지로 이동시켰지만 장바구니 페이지를 요청했던 것을 기억해 뒀다가 사용자가 로그인을 하고 나면 바로 장바구니로 이동할 수 있도록 하는 기능이다.

AccessDeniedException

AccessDeniedHandler에서 예외처리 하도록 제공

 http.exceptionHandling() 					
 	.authenticationEntryPoint(authenticationEntryPoint())     // 인증실패 시 처리
    .accessDeniedHandler(accessDeniedHandler()) 			// 인증실패 시 처리

CSRF (사이트 간 요청 위조)

CsrfFilter
  • 모든 요청에 랜덤하게 생성된 토큰을 HTTP 파라미터로 요구
  • 요청 시 전달되는 토큰 값과 서버에 저장된 실제 값과 비교한 후 만약 일치하지 않으면 요청 실패

참고

https://honeywater97.tistory.com/264

profile
Java, Spring, SpringMVC, JPA, MyBatis

0개의 댓글