1. 개요
이 예제에서는 Security에 대한 Spring Boot의 독창적인 접근 방식을 살펴보겠습니다.
간단히 말해서 기본 Security 구성과 필요한 경우 비활성화하거나 사용자 지정할 수 있는 방법에 중점을 둘 것입니다.
2. 기본 Security 설정
Spring Boot 애플리케이션에 Security을 추가하려면 Security 스타터 의존성 을 추가해야 합니다 .
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
여기에는 초기/기본 Security 구성 을 포함하는 SecurityAutoConfiguration 클래스도 포함됩니다.
프로젝트가 이미 Boot를 부모로 사용하고 있다는 가정하에 여기에서 버전을 지정하지 않은 방법에 주목하십시오.
기본적으로 인증은 애플리케이션에 대해 활성화됩니다. 또한 콘텐츠 협상은 basic 또는 formLogin을 사용해야 하는지 결정하는 데 사용됩니다.
몇 가지 미리 정의된 속성이 있습니다.
spring.security.user.name
spring.security.user.password
미리 정의된 spring.security.user.password 속성을 사용하여 비밀번호를 구성하지 않고 애플리케이션을 시작하면 기본 비밀번호가 무작위로 생성되어 콘솔 로그에 인쇄됩니다.
Using default security password: c8be15de-4488-4490-9dc6-fab3f91435c6
더 많은 기본값은 Spring Boot 공통 애플리케이션 속성 참조 페이지의 Security 속성 섹션을 참조하세요.
3. 자동 구성 비활성화
Security 자동 구성을 버리고 자체 구성을 추가하려면 SecurityAutoConfiguration 클래스를 제외해야 합니다.
간단한 제외를 통해 이 작업을 수행할 수 있습니다.
@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
public class SpringBootSecurityApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootSecurityApplication.class, args);
}
}
또는 application.properties 파일 에 일부 구성을 추가할 수 있습니다 .
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration
그러나 이 설정이 충분하지 않은 특정 경우도 있습니다.
예를 들어 거의 모든 Spring Boot 애플리케이션은 클래스 경로에서 Actuator로 시작됩니다. 다른 자동 구성 클래스에 방금 제외된 클래스가 필요하기 때문에 문제가 발생합니다. 따라서 응용 프로그램이 시작되지 않습니다.
이 문제를 해결하려면 해당 클래스를 제외해야 합니다. Actuator 상황에 따라 ManagementWebSecurityAutoConfiguration 도 제외해야 합니다 .
3.1. 비활성화 vs. Security 자동 구성 능가
자동 구성을 비활성화하는 것과 이를 능가하는 것 사이에는 상당한 차이가 있습니다.
비활성화하는 것은 Spring Security 의존성과 전체 설정을 처음부터 추가하는 것과 같습니다. 이것은 여러 경우에 유용할 수 있습니다.
- 맞춤형 Security 공급자와 애플리케이션 Security 통합
- 이미 존재하는 Security 설정이 있는 레거시 Spring 애플리케이션을 Spring Boot로 마이그레이션
그러나 대부분의 경우 Security 자동 구성을 완전히 비활성화할 필요는 없습니다.
Spring Boot는 새로운/사용자 정의 구성 클래스를 추가하여 자동 구성 Security을 능가하도록 구성되어 있기 때문입니다. 이것은 우리의 요구를 충족시키기 위해 기존 Security 설정을 사용자 지정하기 때문에 일반적으로 더 쉽습니다.
4. 스프링 부트 Security 설정
Security 자동 구성을 비활성화하는 경로를 선택한 경우 자연스럽게 자체 구성을 제공해야 합니다.
이전에 논의한 바와 같이 이것이 기본 Security 구성입니다. 그런 다음 속성 파일을 수정하여 사용자 지정합니다.
예를 들어, 다음을 추가하여 기본 비밀번호를 무시할 수 있습니다.
spring.security.user.password=password
예를 들어 여러 사용자와 역할이 있는 보다 유연한 구성을 원하면 전체 @Configuration 클래스 를 사용해야 합니다 .
@Configuration
@EnableWebSecurity
public class BasicConfiguration {
@Bean
public InMemoryUserDetailsManager userDetailsService(PasswordEncoder passwordEncoder) {
UserDetails user = User.withUsername("user")
.password(passwordEncoder.encode("password"))
.roles("USER")
.build();
UserDetails admin = User.withUsername("admin")
.password(passwordEncoder.encode("admin"))
.roles("USER", "ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
return encoder;
}
}
@EnableWebSecurity 어노테이션은 기본 Security 구성을 비활성화하는 경우 중요합니다.
응용 프로그램이 없으면 시작되지 않습니다.
또한 Spring Boot 2 를 사용할 때 PasswordEncoder를 사용하여 암호 를 설정해야 합니다. 자세한 내용 은 Spring Security 5의 기본 암호 인코더에 대한 사용방법(예제)를 참조하세요 .
이제 몇 가지 빠른 라이브 테스트를 통해 Security 구성이 올바르게 적용되는지 확인해야 합니다.
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
public class BasicConfigurationIntegrationTest {
TestRestTemplate restTemplate;
URL base;
@LocalServerPort int port;
@Before
public void setUp() throws MalformedURLException {
restTemplate = new TestRestTemplate("user", "password");
base = new URL("http://localhost:" + port);
}
@Test
public void whenLoggedUserRequestsHomePage_ThenSuccess()
throws IllegalStateException, IOException {
ResponseEntity<String> response =
restTemplate.getForEntity(base.toString(), String.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertTrue(response.getBody().contains("Baeldung"));
}
@Test
public void whenUserWithWrongCredentials_thenUnauthorizedPage()
throws Exception {
restTemplate = new TestRestTemplate("user", "wrongpassword");
ResponseEntity<String> response =
restTemplate.getForEntity(base.toString(), String.class);
assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode());
assertTrue(response.getBody().contains("Unauthorized"));
}
}
Spring Security는 실제로 Spring Boot Security 뒤에 있으므로 이 Security 구성이나 이 Security 구성이 지원하는 통합으로 수행할 수 있는 모든 Security 구성도 Spring Boot에 구현할 수 있습니다.
5. Spring Boot OAuth2 자동 구성(레거시 스택 사용)
Spring Boot에는 OAuth2에 대한 전용 자동 구성 지원이 있습니다.
Spring Boot 1.x와 함께 제공 되는 Spring Security OAuth 지원은 Spring Security 5 와 함께 번들로 제공되는 일급 OAuth 지원 대신 이후 부트 버전에서 제거되었습니다 . 다음 섹션에서 이를 사용하는 방법을 살펴보겠습니다.
레거시 스택(Spring Security OAuth 사용)의 경우 먼저 Maven 의존성을 추가하여 애플리케이션 설정을 시작해야 합니다.
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
이 의존성은 OAuth2AutoConfiguration 클래스 에 정의된 자동 구성 메커니즘을 트리거할 수 있는 클래스 집합을 포함합니다 .
이제 응용 프로그램의 범위에 따라 계속할 수 있는 여러 선택 사항이 있습니다.
5.1. OAuth2 인증 서버 자동 구성
애플리케이션이 OAuth2 공급자가 되도록 하려면 @EnableAuthorizationServer 를 사용할 수 있습니다 .
시작 시 로그에서 자동 구성 클래스가 인증 서버에 대한 클라이언트 ID와 클라이언트 암호, 물론 기본 인증을 위한 랜덤의 암호를 생성한다는 것을 알 수 있습니다.
Using default security password: a81cb256-f243-40c0-a585-81ce1b952a98
security.oauth2.client.client-id = 39d2835b-1f87-4a77-9798-e2975f36972e
security.oauth2.client.client-secret = f1463f8b-0791-46fe-9269-521b86c55b71
다음 자격 증명을 사용하여 액세스 토큰을 얻을 수 있습니다.
curl -X POST -u 39d2835b-1f87-4a77-9798-e2975f36972e:f1463f8b-0791-46fe-9269-521b86c55b71 \
-d grant_type=client_credentials
-d username=user
-d password=a81cb256-f243-40c0-a585-81ce1b952a98 \
-d scope=write http://localhost:8080/oauth/token
우리의 다른 기사 는 주제에 대한 자세한 내용을 제공합니다.
5.2. 기타 Spring Boot OAuth2 자동 구성 설정
Spring Boot OAuth2에서 다루는 다른 사용 사례가 있습니다.
- 리소스 서버 – @EnableResourceServer
- 클라이언트 애플리케이션 – @EnableOAuth2Sso 또는 @EnableOAuth2Client
애플리케이션이 이러한 유형 중 하나가 되어야 하는 경우 링크에 자세히 설명된 대로 애플리케이션 속성에 일부 구성을 추가하기만 하면 됩니다.
모든 OAuth2 특정 속성은 Spring Boot Common Application Properties 에서 찾을 수 있습니다 .
6. Spring Boot OAuth2 자동 구성(새 스택 사용)
새 스택을 사용하려면 구성하려는 항목(권한 부여 서버, 리소스 서버 또는 클라이언트 응용 프로그램)에 따라 의존성을 추가해야 합니다.
하나씩 살펴보겠습니다.
6.1. OAuth2 인증 서버 지원
우리가 보았듯이 Spring Security OAuth 스택은 Authorization Server를 Spring 애플리케이션으로 설정할 수 있는 가능성을 제공했습니다. 그러나 프로젝트는 더 이상 사용되지 않으며 Spring은 현재 자체 인증 서버를 지원하지 않습니다. 대신 Okta, Keycloak 및 ForgeRock과 같은 기존의 잘 정립된 공급자를 사용하는 것이 좋습니다.
그러나 Spring Boot를 사용하면 이러한 공급자를 쉽게 구성할 수 있습니다. Keycloak 구성의 예는 A Quick Guide to Using Keycloak With Spring Boot 또는 Keycloak Embedded in a Spring Boot Application 을 참조할 수 있습니다 .
6.2. OAuth2 리소스 서버 지원
리소스 서버에 대한 지원을 포함하려면 다음 의존성을 추가해야 합니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
최신 버전 정보를 보려면 Maven Central 로 이동 하십시오.
또한 Security 구성에서 oauth2ResourceServer() DSL을 포함해야 합니다.
@Configuration
public class JWTSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
...
.oauth2ResourceServer(oauth2 -> oauth2.jwt());
...
}
}
Spring Security 5가 포함된 OAuth 2.0 리소스 서버 는 이 주제에 대한 심층적인 관점을 제공합니다.
6.3. OAuth2 클라이언트 지원
리소스 서버를 구성한 방법과 유사하게 클라이언트 애플리케이션에도 자체 의존성과 DSL이 필요합니다.
다음은 OAuth2 클라이언트 지원에 대한 특정 의존성입니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
최신 버전은 Maven Central 에서 찾을 수 있습니다 .
Spring Security 5는 또한 oath2Login() DSL 을 통해 일류 로그인 지원을 제공합니다 .
새 스택의 SSO 지원에 대한 자세한 내용은 Spring Security OAuth2를 사용한 Simple Single Sign-On 기사를 참조하세요 .
7. 결론
이 기사에서는 Spring Boot에서 제공하는 기본 Security 구성에 중점을 두었습니다. Security 자동 구성 메커니즘을 비활성화하거나 재정의할 수 있는 방법을 살펴보았습니다. 그런 다음 새로운 Security 구성을 적용하는 방법을 살펴보았습니다.
OAuth2의 소스 코드는 기존 및 새 스택 에 대한 OAuth2 GitHub 리포지토리에서 찾을 수 있습니다 . 나머지 코드는 GitHub 에서 찾을 수 있습니다 .