이번 방학에 진행하는 프로젝트에서 보안 파트를 담당하게 됐다.
보안쪽은 어렵다고 듣기도 했었고 경험도 없어서 보안 쪽을 해볼까 말까 하다가 이번 기회에 보안 마스터가 되보자는 꿈을 갖고 도전해보기로 했다.
이번 글에서는 Spring Security를 적용했을 때 기본적인 작동 과정을 알아보았다.
Spring Security 적용
Spring Security을 통해 스프링에서 API, MVC 경로에 접근할 때 이에 대한 보안을 설정할 수 있다.
Spring Security를 적용하기 위해 아래와 같이 build.grade을 수정하고
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
기본적인 API도 만들었다.
@GetMapping("/welcome")
public String sayWelcome() {
return "Welcome to Spring Application with security";
}
이제 localhost:8080/welcome으로 API를 호출해보면?

위와 같은 로그인 화면이 뜬다. username의 기본값 user, 비밀번호는 콘솔에 뜨는 값을 입력하면 로그인이 성공하고 API가 호출된다.
로그인을 한번 성공하고 새로고침을 하면 로그인 폼이 뜨지않고 API를 바로 접근할 수 있는데, Spring Security가 브라우저 내부에서 생성된 세션을 기억하고 있기 때문이다.
build.gradle에 spring security 부분만 추가했는데 해당 폼은 어디서 오는지, username, password는 어디서 생성되는지 알아보자.
SecurityProperties.class
username, password는 Spring Security 라이브러리 내부에 있는 SecurityProperties.class에서 생성된다.
해당 클래스의 static class인 User 클래스가 있고, 여기서 name, password, roles의 default 값이 설정된다.

default user name은 "user"이고 password는 UUID클래스를 통해 실행 시마다 무작위로 생성되며 roles은 설정되지 않음을 확인할 수 있다.
application.properties를 수정하여 username, password을 명시적으로 설정할 수 있다.

@ConfigurationProperties에서 prefix로 "spring.security"가 붙어있는데, Spring Security와 관련된 모든 속성을 정의할 땐 spring.security를 사용한다.
name, password는 User 클래스 내부에 있으므로 property 이름은 spring.security.user.name와 같이 작성하면 된다.
property 이름은 spring 공식 문서에서도 확인할 수 있다.

username, password 설정
spring.security.user.name=${SECURITY_USERNAME:bingseok}
spring.security.user.password=${SECURITY_PASSWORD:12345}
application.properties를 위와 같이 설정하면 로그인 시 name과 password를 변경할 수 있고, 다시 프로그램을 재시작하면 콘솔에 생성된 password이 보이지 않는다.
이는 SecurityProperties.class 내부 로직으로 인해 시작 시 비밀번호가 생성되지 않고, application.properties에 정의된 속성을 활용하기 때문이다.
SecurityProperties.class 내부에 비밀번호가 생성되었는지를 나타내는 passwordGenerated라는 변수가 있는데, 우리가 설정 파일에서 password를 설정하였기 때문에 클래스 내부에서 새롭게 password를 생성하지 않는다.
