# 28\. Security
如果Spring Security位于類路徑上,則默認情況下,Web應用程序將在所有HTTP端點上使用“basic”身份驗證。 要向Web應用程序添加方法級安全性,您還可以使用所需的設置添加@EnableGlobalMethodSecurity。 有關更多信息,請參見“[Spring Security Reference](http://docs.spring.io/spring-security/site/docs/4.2.2.RELEASE/reference/htmlsingle#jc-method)”。
默認的AuthenticationManager有一個用戶(用戶名'user'和隨機密碼,在應用程序啟動時以INFO級別打印)
```
Using default security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35
```
> 如果您調整日志記錄配置,請確保將org.springframework.boot.autoconfigure.security類別設置為記錄INFO消息,否則將不會打印默認密碼。
您可以通過提供security.user.password來更改密碼。 這個和其他有用的屬性通過?[SecurityProperties](https://github.com/spring-projects/spring-boot/tree/v1.5.2.RELEASE/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityProperties.java)(屬性前綴“security”)進行外部化。
默認的安全配置在SecurityAutoConfiguration和從那里導入的類中實現(用于Web安全的SpringBootWebSecurityConfiguration和用于認證配置的AuthenticationManagerConfiguration,這在非Web應用程序中也是相關的)。 要完全關閉默認的Web應用程序安全配置,您可以使用@EnableWebSecurity添加一個bean(這不會禁用身份驗證管理器配置或Actuator的安全性)。 要定制它,您通常使用WebSecurityConfigurerAdapter類型的外部屬性和bean(例如添加基于表單的登錄)。 要關閉身份驗證管理器配置,您可以添加AuthenticationManager類型的bean,或者通過將AuthenticationManagerBuilder自動連接到您的一個@Configuration類中的方法來配置全局AuthenticationManager。 Spring Boot示例中有幾個安全應用程序可以讓您開始使用常見的[用例](https://github.com/spring-projects/spring-boot/tree/v1.5.2.RELEASE/spring-boot-samples/)。
您在Web應用程序中獲得的基本功能包括:
* 具有內存存儲和單個用戶的AuthenticationManager Bean(請參閱用于用戶屬性的SecurityProperties.User)。
* 對于常見的靜態資源位置,忽略(不安全)路徑(/css/**, /js/**, /images/**, /webjars/** and **/favicon.ico)。
* HTTP所有其他端點的baseic security 。
* 安全事件發布到Spring的ApplicationEventPublisher(成功、不成功的身份驗證、拒絕訪問)。
* 默認情況下,Spring Security提供的常見的底層功能(HSTS,XSS,CSRF,緩存)都是打開的。
所有上述可以使用外部屬性(security.*)打開、關閉或修改。 要覆蓋訪問規則而不更改任何其他自動配置的功能,請添加一個帶有@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)的WebSecurityConfigurerAdapter類型的Bean,并配置它以滿足您的需要。
> 默認情況下,WebSecurityConfigurerAdapter將匹配任何路徑。 如果您不想完全覆蓋Spring Boot自動配置的訪問規則,您的適配器必須顯式配置您要覆蓋的路徑。
### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#281-oauth2)28.1 OAuth2
如果您的類路徑中有spring-security-oauth2,您可以利用一些自動配置來輕松設置授權或資源服務器。 有關完整的詳細信息,請參閱“[Spring Security OAuth 2開發人員指南](http://projects.spring.io/spring-security-oauth/docs/oauth2.html)”。
#### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#2811-授權服務器)28.1.1 授權服務器
要創建授權服務器并授予訪問令牌,您需要使用@EnableAuthorizationServer并提供security.oauth2.client.client-id和security.oauth2.client.client-secret]屬性。 客戶端將為您注冊在內存中。
```
$ curl client:secret@localhost:8080/oauth/token -d grant_type=password -d username=user -d password=pwd
```
/token 端點的基本身份驗證憑證是client-id和client-secret。 用戶憑據是普通的Spring Security用戶details (在Spring引導中默認為“user”和隨機密碼)。
要關閉自動配置并自行配置授權服務器功能,只需添加一個類型為AuthorizationServerConfigurer的@Bean。
#### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#2812-資源服務器)28.1.2 資源服務器
要使用訪問令牌(token),您需要一個資源服務器(可以與授權服務器相同)。 創建資源服務器很簡單,只需添加@EnableResourceServer并提供一些配置,以允許服務器解碼訪問令牌。 如果您的應用程序也是授權服務器,則它已經知道如何解碼令牌,無需做其他事情。 如果你的應用程序是一個獨立的服務,那么你需要給它一些更多的配置,以下選項之一:
* security.oauth2.resource.user-info-uri使用/me資源(例如PWS上的
* security.oauth2.resource.token-info-uri使用令牌解碼端點(例如,PWS上的
如果您同時指定user-info-uri和token-info-uri,那么您可以設置一個標志,表示優先于另一個(prefer-token-inf=true是默認值)。
或者(不是user-info-uri或token-info-uri的情況)如果令牌是JWT,您可以配置security.oauth2.resource.jwt.key-value來本地解碼(key是驗證密鑰verification key)。 驗證密鑰值是對稱秘密或PEM編碼的RSA公鑰。 如果您沒有密鑰,并且它是公開的,您可以提供一個可以使用security.oauth2.resource.jwt.key-uri下載的URI(具有“value”字段的JSON對象)。 例如在PWS上:
```
$ curl https://uaa.run.pivotal.io/token_key
{"alg":"SHA256withRSA","value":"-----BEGIN PUBLIC KEY-----\nMIIBI...\n-----END PUBLIC KEY-----\n"}
```
如果您使用security.oauth2.resource.jwt.key-uri,則應用程序啟動時需要運行授權服務器。 如果找不到密鑰,它將記錄一個警告,并告訴您如何解決該問題。
> 如果您使用security.oauth2.resource.jwt.key-uri,則應用程序啟動時需要運行授權服務器。 如果找不到密鑰,它將會在日志記錄一個警告,并告訴您如何解決該問題。
OAuth2資源由order security.oauth2.resource.filter-order的過濾器鏈保護,默認情況下保護執行器(actuator)端點的過濾器(所以執行器(actuator)端點將保留在HTTP Basic上,除非更改順序)。
### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#282-user-info中的令牌類型)28.2 User Info中的令牌類型
Google和某些其他第三方身份認證提供商對在header中發送到用戶信息端點的令牌類型名稱更為嚴格。 默認值為“Bearer”,適合大多數提供程序并匹配規范,但如果需要更改,可以設置security.oauth2.resource.token-type。
### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#283-自定義用戶信息resttemplate)28.3 自定義用戶信息RestTemplate
如果您有user-info-uri,則資源服務器功能在內部使用OAuth2RestTemplate來獲取用戶身份驗證信息。 這是以UserInfoRestTemplateFactory類型的@Bean提供的。 大多數提供程序的默認值應該是能滿足正常使用,但有時您可能需要添加其他攔截器,或者更改請求驗證器(例如:令牌如何附加到傳出請求)。 進行自定義,只需創建一個類型為UserInfoRestTemplateCustomizer的bean - 它具有一個方法,在bean創建之后但在初始化之前將被調用。 這里定制的rest模板只能在內部進行驗證。 或者,您可以定義自己的UserInfoRestTemplateFactory @Bean來完全控制。
要在YAML中設置RSA密鑰值,請使用“pipe”繼續標記將其分割成多行(“|”),并記住縮進鍵值(它是標準的 YAML 語言功能)。 例:
```
security:
oauth2:
resource:
jwt:
keyValue: |
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC...
-----END PUBLIC KEY-----
```
#### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#2831-client)28.3.1 Client
要使您的 web-app 進入OAuth2客戶端,您可以簡單地添加@ EnableOAuth2Client,Spring Boot將創建一個OAuth2ClientContext和OAuth2ProtectedResourceDetails,這些是創建OAuth2RestOperations所必需的。 Spring Boot不會自動創建這樣的bean,但是您可以輕松創建自己的bean:
```
@Bean
public OAuth2RestTemplate oauth2RestTemplate(OAuth2ClientContext oauth2ClientContext, OAuth2ProtectedResourceDetails details) {
return new OAuth2RestTemplate(details, oauth2ClientContext);
}
```
> 您可能需要添加限定符并查看您的配置,因為您的應用程序可能會定義多個RestTemplate。
此配置使用security.oauth2.client.*作為憑據(可能與授權服務器中使用的相同),但另外還需要知道授權服務器中的授權和令牌URI。 例如:
application.yml.
```
security:
oauth2:
client:
clientId: bd1c0a783ccdd1c9b9e4
clientSecret: 1a9030fbca47a5b2c28e92f19050bb77824b5ad1
accessTokenUri: https://github.com/login/oauth/access_token
userAuthorizationUri: https://github.com/login/oauth/authorize
clientAuthenticationScheme: form
```
當您嘗試使用OAuth2RestTemplate時,具有此配置的應用程序將重定向到Github進行授權。 如果您已經登錄Github,您甚至不會注意到它已經被認證。 如果您的應用程序在端口8080上運行(在Github或其他提供商注冊自己的客戶端應用程序以獲得更大的靈活性),這些特定的憑據才會起作用。
要限制客戶端在獲取訪問令牌時要求的范圍,您可以設置security.oauth2.client.scope(逗號分隔或YAML中的數組)。 默認情況下,scope是空的,由授權服務器決定其默認值,通常取決于客戶端注冊中的設置。
> 還有一個security.oauth2.client.client-authentication-scheme的設置,默認為“header”(但是如果像Github那樣,您可能需要將其設置為“form”,例如,您的OAuth2提供程序不喜歡header 認證)。 事實上,security.oauth2.client.*屬性綁定到AuthorizationCodeResourceDetails的一個實例,因此可以指定其所有的屬性。
> 在非Web應用程序中,您仍然可以創建一個OAuth2RestOperations,它仍然連接到security.oauth2.client.*配置中。 在這種情況下,它是一個“客戶端憑據令牌授予”,您如果使用它就請求它(并且不需要使用@EnableOAuth2Client或@EnableOAuth2Sso)。為了防止定義基礎設施,只需從配置中刪除security.oauth2.client.client-id(或使其成為空字符串)。
#### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#2832-單點登錄)28.3.2 單點登錄
OAuth2客戶端可用于從提供商獲取用戶詳細信息(如果此類功能可用),然后將其轉換為Spring Security的身份驗證令牌。 以上資源服務器通過user-info-uri屬性支持此功能這是基于OAuth2的單點登錄(SSO)協議的基礎,Spring Boot可以通過提供@ EnableOAuth2Sso注解來輕松加入。 上面的Github客戶端可以通過添加該注釋并聲明在何處查找端點(除了上面列出的security.oauth2.client.*配置)外,還可以保護所有資源并使用Github/user/endpoint進行身份驗證:
application.yml.
```
security:
oauth2:
...
resource:
userInfoUri: https://api.github.com/user
preferTokenInfo: false
```
由于默認情況下所有路徑都是安全的,所以沒有可以向未經身份驗證的用戶顯示“家”頁面,并邀請他們登錄(通過訪問/登錄路徑或由security.oauth2.sso.login-path指定的路徑) 。
由于默認情況下所有路徑都是要求安全的,所以沒有可以向未經身份驗證的用戶顯示“home”頁面,并邀請他們登錄(通過訪問/login 路徑或由security.oauth2.sso.login-path指定的路徑) 。
要自定義保護的訪問規則或路徑,因此您可以添加“home”頁面,例如,@EnableOAuth2Sso可以添加到WebSecurityConfigurerAdapter,并且注解將使其被修飾和增強,以使所需的/login路徑可以工作。 例如,這里我們簡單地允許未經身份驗證的訪問“/"下的主頁面,并保留其他所有內容的默認值:
```
@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void init(WebSecurity web) {
web.ignore("/");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**").authorizeRequests().anyRequest().authenticated();
}
}
```
### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#284-actuator-security)28.4 Actuator Security
如果Actuator也在使用中,您會發現:
* 即使應用程序端點不安全,管理端點也是安全的。
* Security 事件將轉換為AuditEvent實例,并發布到AuditEventRepository。
* 默認用戶將具有ACTUATOR角色以及USER角色。
Actuator的安全功能可以使用外部屬性(management.security.*)進行修改。要覆蓋應用程序訪問規則,請添加一個類型為WebSecurityConfigurerAdapter的@Bean,如果您不想覆蓋執行程序訪問規則,則使用@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)或@Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER)覆蓋執行器訪問規則。
- Part I. Spring Boot 文檔
- Part II. 入門指南
- 8. Spring Boot 介紹
- 9. 系統要求
- 10. 安裝 Spring Boot
- 11. 開發您的第一個Spring Boot應用程序
- 12. 接下來應該讀什么
- Part III. 使用 Spring Boot
- 13. 構建系統
- 14. 構建代碼
- 15. 配置類
- 16. 自動配置
- 17. Spring Beans 和 依賴注入
- 18. 使用@SpringBootApplication注解
- 19. 運行你的應用程序
- 20. 開發工具
- 21. 包裝您的應用程序到生產環境
- 22. 接下來應該讀什么
- Part IV. Spring Boot 功能
- 23. SpringApplication
- 24. 外部配置
- 25. 配置文件(Profiles)
- 26. 日志
- 27. 開發Web應用程序
- 28. Security
- 29. 使用SQL數據庫