Spring Boot Security配置教程

程式猿Knight發表於2019-05-26

1.簡介

在本文中,我們將瞭解Spring Boot對spring Security的支援。

簡而言之,我們將專注於預設Security配置以及如何在需要時禁用或自定義它

2.預設Security設定

為了增加Spring Boot應用程式的安全性,我們需要新增安全啟動器依賴項:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

這將包括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

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啟動。
這會導致問題,因為另一個自動配置類需要我們剛剛排除的那個,因此應用程式將無法啟動

為了解決這個問題,我們需要排除該類;並且,特定於Actuator情況,我們需要排除ManagementWebSecurityAutoConfiguration

3.1. 禁用和超越 Security Auto-Configuration

禁用自動配置和超越它之間存在顯著差異

通過禁用它,就像從頭開始新增Spring Security依賴項和整個設定一樣。這在以下幾種情況下很有用:

  • 將應用程式security與自定義security提供程式整合
  • 將已有security設定的舊Spring應用程式遷移到Spring Boot

但是,大多數情況下我們不需要完全禁用安全自動配置

Spring Boot的配置方式允許通過新增我們的新/自定義配置類來超越自動配置的安全性。這通常更容易,因為我們只是定製現有的安全設定以滿足我們的需求。

4.配置Spring Boot Security

如果我們選擇了禁用Security自動配置的路徑,我們自然需要提供自己的配置。

正如我們之前討論過的,這是預設的安全配置;我們可以通過修改屬性檔案來自定義它。

例如,我們可以通過新增我們自己的密碼來覆蓋預設密碼:

security.user.password=password

如果我們想要一個更靈活的配置,例如多個使用者和角色 - 您現在需要使用完整的@Configuration類

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

如果我們禁用預設安全配置,則@EnableWebSecurity註釋至關重要

如果丟失,應用程式將無法啟動。只有在我們使用WebSecurityConfigurerAdapter覆蓋預設行為時,註釋才是可選的。

現在,我們應該通過幾個快速實時測試驗證我們的安全配置是否正確應用:

@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 Boot Security的背後是Spring Security,所以任何可以用這個完成的安全配置,或者這個支援的任何整合都可以實現到Spring Boot中

5. Spring Boot OAuth2自動配置

Spring Boot為OAuth2提供專用的自動配置支援

在我們開始之前,讓我們新增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

如果我們需要將我們的應用程式作為上述型別之一,我們只需要為應用程式屬性新增一些配置

6. Spring Boot 2 security與Spring Boot 1 security

與Spring Boot 1相比,Spring Boot 2大大簡化了自動配置。

在Spring Boot 2中,如果我們想要自己的安全配置,我們可以簡單地新增一個自定義的WebSecurityConfigurerAdapter。這將禁用預設自動配置並啟用我們的自定義安全配置

Spring Boot 2使用Spring Security的大部分預設值。因此,預設情況下,Spring Boot 1中預設不安全的某些端點現在是安全的

這些端點包括靜態資源,如/ css / ,/ js / ,/ images / ,/ webjars / ,//favicon.ico和錯誤端點。如果我們需要允許對這些端點進行未經身份驗證的訪問,我們可以明確地配置它**。

為了簡化與安全相關的配置,Spring Boot 2刪除了以下Spring Boot 1屬性

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

7.結論

在本文中,我們重點介紹Spring Boot提供的預設安全配置。我們瞭解瞭如何禁用或覆蓋安全性自動配置機制以及如何應用新的安全性配置。

程式碼可以在Github上找

相關文章