스프링 부트 보안 자동 구성

1. 소개

이 기사에서는 보안에 대한 Spring Boot의 독단적 인 접근 방식을 살펴 보겠습니다.

간단히 말해, 기본 보안 구성과 필요한 경우이를 비활성화하거나 사용자 지정할 수있는 방법에 초점을 맞출 것입니다.

2. 기본 보안 설정

Spring Boot 애플리케이션에 보안 을 추가하려면 보안 스타터 종속성 을 추가해야합니다 .

 org.springframework.boot spring-boot-starter-security 

여기에는 초기 / 기본 보안 구성 을 포함하는 SecurityAutoConfiguration 클래스 가 포함됩니다 .

프로젝트가 이미 Boot를 부모로 사용하고 있다는 가정하에 여기에서 버전을 지정하지 않았는지 확인하십시오.

간단히 말해서 기본적으로 인증은 애플리케이션에 대해 활성화됩니다. 또한 컨텐츠 협상은 기본 또는 formLogin을 사용해야하는지 결정하는 데 사용됩니다.

다음과 같은 몇 가지 미리 정의 된 속성이 있습니다.

spring.security.user.name spring.security.user.password

미리 정의 된 속성 spring.security.user.password를 사용하여 암호를 구성하지 않고 애플리케이션을 시작하면 기본 암호가 무작위로 생성되어 콘솔 로그에 인쇄되는 것을 알 수 있습니다.

Using default security password: c8be15de-4488-4490-9dc6-fab3f91435c6

더 많은 기본값은 Spring Boot 공통 애플리케이션 속성 참조 페이지의 보안 속성 섹션을 참조하세요.

3. 자동 구성 비활성화

보안 자동 구성을 삭제하고 자체 구성을 추가하려면 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로 시작됩니다. 다른 자동 구성 클래스에 방금 제외 된 클래스가 필요하기 때문에 문제가 발생 하여 응용 프로그램이 시작되지 않습니다.

이 문제를 해결하려면 해당 클래스를 제외해야합니다. 액추에이터 상황에 따라 ManagementWebSecurityAutoConfiguration 을 제외해야합니다 .

3.1. 보안 자동 구성 비활성화 및 능가

자동 구성을 비활성화하는 것과이를 능가하는 것에는 상당한 차이가 있습니다.

비활성화하면 Spring Security 종속성과 전체 설정을 처음부터 추가하는 것과 같습니다. 이는 여러 경우에 유용 할 수 있습니다.

  1. 애플리케이션 보안을 사용자 정의 보안 제공자와 통합
  2. 기존 보안 설정이있는 레거시 Spring 애플리케이션을 Spring Boot로 마이그레이션

그러나 대부분의 경우 보안 자동 구성을 완전히 비활성화 할 필요는 없습니다.

Spring Boot가 구성되는 방식은 새로운 / 사용자 지정 구성 클래스를 추가하여 자동 구성 보안을 능가 할 수 있습니다. 이는 일반적으로 우리의 요구 사항을 충족하기 위해 기존 보안 설정을 사용자 지정하기 때문에 더 쉽습니다.

4. 스프링 부트 보안 설정

보안 자동 구성을 비활성화하는 경로를 선택한 경우 당연히 자체 구성을 제공해야합니다.

이전에 논의했듯이 이것이 기본 보안 구성입니다. 속성 파일을 수정하여 사용자 정의 할 수 있습니다.

예를 들어 다음을 추가하여 기본 비밀번호를 재정의 할 수 있습니다.

spring.security.user.password=password

예를 들어 여러 사용자 및 역할이있는보다 유연한 구성을 원하면 전체 @Configuration 클래스를 사용해야합니다 .

@Configuration @EnableWebSecurity public class BasicConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); auth .inMemoryAuthentication() .withUser("user") .password(encoder.encode("password")) .roles("USER") .and() .withUser("admin") .password(encoder.encode("admin")) .roles("USER", "ADMIN"); } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest() .authenticated() .and() .httpBasic(); } }

@EnableWebSecurity의 우리가 기본 보안 설정을 사용하지 않으면 주석이 매우 중요합니다.

누락 된 경우 응용 프로그램이 시작되지 않습니다. 주석은 WebSecurityConfigurerAdapter를 사용하여 기본 동작을 재정의하는 경우에만 선택 사항 입니다.

또한 Spring Boot 2 를 사용할 때 PasswordEncoder 를 사용하여 비밀번호 를 설정해야합니다 . 자세한 내용은 Spring Security 5의 기본 비밀번호 인코더 가이드를 참조하세요.

이제 몇 가지 빠른 라이브 테스트를 통해 보안 구성이 올바르게 적용되는지 확인해야합니다.

@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("//localhost:" + port); } @Test public void whenLoggedUserRequestsHomePage_ThenSuccess() throws IllegalStateException, IOException { ResponseEntity 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 response = restTemplate.getForEntity(base.toString(), String.class); assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); assertTrue(response.getBody().contains("Unauthorized")); } }

아이디어는 Spring Boot Security 뒤에 실제로 Spring Security가 있으므로이 구성으로 수행 할 수있는 모든 보안 구성 또는이 구성이 지원하는 모든 통합을 Spring Boot로 구현할 수도 있습니다.

5. Spring Boot OAuth2 자동 구성 (레거시 스택 사용)

Spring Boot에는 OAuth2에 대한 전용 자동 구성 지원이 있습니다.

Spring Security OAuth support that came with Spring Boot 1.x was removed in later boot versions in lieu of first class OAuth support that comes bundled with Spring Security 5. We'll see how to use that in the next section.

For the legacy stack (using Spring Security OAuth), first we'll need to add a Maven dependency to start setting up our application:

 org.springframework.security.oauth spring-security-oauth2 

This dependency includes a set of classes that are capable of triggering the auto-configuration mechanism defined in OAuth2AutoConfiguration class.

Now, we have multiple choices to continue, depending on the scope of our application.

5.1. OAuth2 Authorization Server Auto-Configuration

If we want our application to be an OAuth2 provider, we can use @EnableAuthorizationServer.

On startup, we'll notice in the logs that the auto-configuration classes will generate a client id and a client-secret for our authorization server and of course a random password for basic authentication.

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

These credentials can be used to obtain an access token:

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 //localhost:8080/oauth/token

Our another article provides further details on the subject.

5.2. Other Spring Boot OAuth2 Auto-Configuration Settings

There are some other use cases covered by Spring Boot OAuth2 like:

  1. Resource Server – @EnableResourceServer
  2. Client Application – @EnableOAuth2Sso or @EnableOAuth2Client

If we need our application to be one of the types above we just have to add some configuration to application properties, as detailed by the links referenced above.

All OAuth2 specific properties can be found at Spring Boot Common Application Properties.

6. Spring Boot OAuth2 Auto-Configuration (using new stack)

To use the new stack, we need to add dependencies based on what we want to configure – an authorization server, a resource server or a client application.

Let's look at them one by one.

6.1. OAuth2 Authorization Server Support

As we saw in the previous section, the Spring Security OAuth stack offered the possibility of setting up an Authorization Server as a Spring Application. But the project has been deprecated and Spring does not support its own authorization server as of now. Instead, it's recommended to use existing well-established providers such as Okta, Keycloak, and Forgerock.

However, Spring Boot does make it easy for us to configure such providers. For an example Keycloak configuration, we can refer to either A Quick Guide to Using Keycloak with Spring Boot or Keycloak Embedded in a Spring Boot Application.

6.2. OAuth2 Resource Server Support

To include support for a resource server, we need to add this dependency:

 org.springframework.boot spring-boot-starter-oauth2-resource-server 

For the latest version information, head over to Maven Central.

Additionally, in our security configuration, we need to include the oauth2ResourceServer() DSL:

@Configuration public class JWTSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http ... .oauth2ResourceServer(oauth2 -> oauth2.jwt()); ... } }

Our OAuth 2.0 Resource Server With Spring Security 5 gives an in-depth view of this topic.

6.3. OAuth2 Client Support

Similar to how we configured a resource server, a client application also needs its own dependencies and DSLs.

Here's the specific dependency for OAuth2 client support:

 org.springframework.boot spring-boot-starter-oauth2-client  

The latest version can be found at Maven Central.

Spring Security 5 also provides first-class login support via its oath2Login() DSL.

For details on SSO support in the new stack, please refer to our Simple Single Sign-On with Spring Security OAuth2.

7. Spring Boot 2 Security vs Spring Boot 1 Security

Compared to Spring Boot 1, Spring Boot 2 has greatly simplified the auto-configuration.

In Spring Boot 2, if we want our own security configuration, we can simply add a custom WebSecurityConfigurerAdapter. This will disable the default auto-configuration and enable our custom security configuration.

Spring Boot 2 uses most of Spring Security’s defaults. Because of this, some of the endpoints that were unsecured by default in Spring Boot 1 are now secured by default.

These endpoints include static resources such as /css/**, /js/**, /images/**, /webjars/**, /**/favicon.ico, and the error endpoint. If we need to allow unauthenticated access to these endpoints, we can explicitly configure that.

To simplify the security-related configuration, Spring Boot 2 has removed the following Spring Boot 1 properties:

security.basic.authorize-mode security.basic.enabled security.basic.path security.basic.realm security.enable-csrf security.headers.cache security.headers.content-security-policy security.headers.content-security-policy-mode security.headers.content-type security.headers.frame security.headers.hsts security.headers.xss security.ignored security.require-ssl security.sessions

8. Conclusion

In this article, we focused on the default security configuration provided by Spring Boot. We saw how the security auto-configuration mechanism can be disabled or overridden and how a new security configuration can be applied.

OAuth2의 소스 코드는 기존 및 새 스택에 대한 OAuth2 GitHub 저장소에서 찾을 수 있습니다. 나머지 코드는 튜토리얼 GitHub에서 찾을 수 있습니다.