Spring Security

[Spring Security 6.x] Default Authentication(기본 인증 설정, 기본 로그인 페이지)

person456 2024. 6. 10. 21:17

Spring Security에 대한 의존성을 추가하고 Spring Boot를 실행하여 8080포트에 예상과는 다른 화면을 볼 수 있다.

해당 포스트에서는 Spring Security의 초기화 및 기본 설정에 대한 원리에 대한 내용을 다룬다.

기본 로그인 페이지 해결 방법을 위해 방문한 것이라면 해결 방법은 다음과 같다.

  • Username : user
  • Password : 콘솔창에서 "Using generated Security password : " 이후 등장한 문자열

 


목차

  1. Spring Security의 기본 설정
  2. Spring Security 소스 기반 작동 원리

1. Spring Security 기본 설정

 

가장 기본이 되는 Index Controller를 생성해주었다.

 

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IndexController {
    @GetMapping("/")
    public String index(){
        return "index";
    }
}

 

실행 결과는 다음과 같다. 주소창의 url 역시 localhost:8080/이 아니라 localhost:8080/login으로 이동한 것을 볼 수 있다.

별도의 login.html, login.jsp 등의 파일을 생성하지 않았어도 localhost:8080에 대한 모든 요청은 이 페이지에서

인증 여부를 검사받아야 접근이 가능하도록 바뀐 것이다.

 

이러한 동작을 하는 원인은, Spring Security에 대한 의존성을 추가하였을 때 Security의 초기화 작업 및 보안 설정이 이루어지기 때문이다.

즉, 사용자가 별도의 보안 설정을 하지 않았더라도 Security가 기본적인 웹 보안 기능을 현재 시스템에 적용시켜 작동한다.

초기화가 진행된 기본 설정은 다음과 같다.

 

Spring Security의 기본 보안 기능

  1. 기본 설정은 모든 url 요청에 대해 인증 여부를 검사하고, 인증이 승인되어야 url 자원에 접근이 가능하다.
  2. 인증 방식은 기본으로 Form 로그인 방식과 HttpBasic 로그인 방식을 제공한다.
  3. 인증을 시도할 수 있는 로그인 페이지가 별도로 자동 생성되어 제공된다.
  4. 인증 승인이 이루어 질 수 있도록 한 개의 계정이 기본적으로 제공된다.

 하지만 이 방식은 말 그대로 Spring Security가 제공해주는 아주 기본적인 기능일 뿐 이것을 사용한다고 보안 문제가

해결되는 것은 아니다.

 접근하는 사용자에 대한 계정이 1개만 있을 수는 없을 뿐더러, 사용자의 역할 구분(인가 처리) 역시 여러 개가 존재 할 수 있기 때문이다. 

 


2. Spring Security 소스 기반 작동 원리

 

2-1 User 계정 자동 생성의 원리

 

기본 인증 기능을 통해 저 Login Page에 대한 인가 처리를 받을 수 있는 계정은 다음과 같다.

  • Username : user
  • Password : UUID로 생성된 랜덤 문자열

user라는 아이디는 고정되어있으나 Password는 랜덤 문자열이기 때문에 사용자는 알 방법이 없을 것 같지만, Spring Boot가 동작할 때 Console창에 해당 Password가 출력되어 확인이 가능하다.

 

"Using generated Security password : " 이후 적힌 랜덤 문자열이 UUID로 생성된 문자열이며 이를통해 인가 받을 수 있다.

사용자에게 "user"라는 Username과 UUID를 통한 랜덤문자열의 "password"를 제공하는 원리는 다음과 같다.

SecurityProperties

앞서 Spring Security는 Spring Boot가 실행될 때 자동 설정에 의해 내부적으로 웹 보안 기능이 작동하기 시작한다.

이를 통해 Bean 등록 및 설정을 진행하는데 SecurityProperties라는 클래스에서 기본 계정 하나를 제공하는 클래스라 볼 수 있다.

SecurityProperties 내부 User class

SecurityProperties 클래스 내부에는 static으로 선언된 User라는 클래스가 따로 존재한다.

이 클래스에서는 기본 보안 설정에 사용될 계정을 생성해주며 내용은 앞서 언급한 아이디, 패스워드를 기반으로 한다.

 

2-2 Spring Security 기본 보안 작동 원리

 

SecurityProperties는 기본적인 계정을 설정해주는 모습을 볼 수 있었다. 반면, SpringBootWebSecurityConfiguration이라는 클래스는 Spring Security의 기본 보안에 대한 설정이 적혀있는 클래스라고 볼 수 있다.

 

SpringBootWebSecurityConfiguration class

해당 클래스의 코드에는 아래와 같은 코드가 존재한다.

 

코드의 윗 줄 부터 살펴보자면 다음과 같다.

1. @ConditionalOnDefaultWebSecurity 애너테이션

해당 애너테이션을 Control+클릭을 통해 계속 파고 들어가다보면 DefaultWebSecurityCondition이라는 클래스가 나온다.

이 클래스에서는 @ConditionOnMissingBean과 @ConditionalOnClass라는 애너테이션이 존재하는데, 이 두 가지 Condition을 만족해야 기본 Security Condition을 만족한다고 볼 수 있는 것이다.

 

1-1 @ConditionalOnClass 애너테이션

- "SecurityFilterChain 클래스와 HttpSecurity 클래스가 Class Path에 존재하는가?" 에 대한 참/거짓 여부를 판별한다.

- 현재 Spring Security에 대한 의존성을 추가하였기 때문에 저 두 개의 클래스는 모두 존재하여 조건은 "참"이다.

 

1-2 @ConditionalOnMissingBean 애너테이션

- "SpringFilterChian 클래스가 Bean으로 생성이 되어있지 않는가?" 에 대한 참/거짓 여부를 판별한다.

- OnMissingBean이기 때문에 Bean으로 생성이 되어있다면 거짓, 생성되어있지 않다면 참이다.

 

따라서 현재 우리는 별도의 SecurityFilterChain을 Bean으로 등록하지 않았고, Security 의존성을 프로젝트에 추가하였기 때문에 두 가지 조건이 모두 참이라 Security의 기본 보안 기능이 작동한 것이다.

 

2. authenticated()

	@Bean
        @Order(2147483642)
        SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
            http.authorizeHttpRequests((requests) -> {
                ((AuthorizeHttpRequestsConfigurer.AuthorizedUrl)requests.anyRequest()).authenticated();
            });
            http.formLogin(Customizer.withDefaults());
            http.httpBasic(Customizer.withDefaults());
            return (SecurityFilterChain)http.build();
        }

 

다음은 위의 두 조건을 만족했을 때  기본적으로 Security가 생성하는 SecurityFilterChain Bean이다.

별 다른 내용은 없고 다음과 같은 내용만 확인하면 된다.

- anyRequest() : 어떠한 요청에 대해서라도. 즉, 모든 요청에 대해서

- authenticated() : 인증 진행한다.

즉, Security의 기본 보안은 URL에 어떠한 요청에 대해서라도 인증을 진행한다는 의미가 된다.

이후 기본적으로 제공하는 formLogin 방식과 httpBasic 방식을 제공하는 것을 코드로 확인할 수 있다.