spring security實戰 5-使用密碼模式(password grant type)保護資源

寫在開篇

本改編課程基於《OAuth 2.0 Cookbook_Protect Your Web Applications using Spring Security-Packt Publishing(2017)》。這本書側重經過一個個精簡的小例子來學習,如何使用spring security和oauth2.0來保護你的資源。java

課程從第二章開始,在Chaptor2,咱們將學習如下內容:git

  1. 使用受權碼模式(Authorization Code grant)保護資源github

  2. 支持隱式受權模式(Implicit grant)
  3. 使用密碼模式(Resource Owner Password Credentials grant type )
  4. 配置客戶端證書受權模式(Client Credentials grant)
  5. 支持refresh tokens
  6. 使用一個關係數據庫來保存tokens和客戶信息
  7. 使用redis保存token
  8. 實現客戶端註冊過程
  9. 中途破壞Oauth 2.0 Provider
  10. 使用Gatling,經過共享數據庫測試token的驗證過程

​ 本例咱們將學習如何配置密碼模式,在實踐中應該避免使用這種模式,由於這種模式客戶端將拿到用戶憑證,而這正是應該由Oauth 2.0經過access 代理來解決的事情。從用戶憑證共享模式遷移到Oauth 2.0模式時,咱們能夠選擇這種策略。當客戶端與Oauth 2.0受權中心在同一solution下(充分信任客戶端的狀況下)時使用會較爲安全。web

Getting ready

Java8+maven
能夠從https://github.com/PacktPubli... 下載項目源碼,這個是書籍官方例子,親自作過跑過,因此能夠放心下載使用。redis

How to do it…

如下步驟將指導你,使用Spring Security OAuth2 配置一個受權中心和一個資源服務器:spring

1.使用Spring Initializr 新建一個Springboot工程,加入web,security依賴。
2.打開pom.xml,加入如下依賴:數據庫

<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId> 
</dependency>

3.打開application.properties文件,輸入:json

security.user.name = adolfo

security.user.password = 123segmentfault

4.新建UserProfile類與UserController類,內容與《學習3》中一致
5.新建OAuth2ResourceServer類,內容與《學習3》中一致
6.新建OAuth2AuthorizationServer類:api

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter {
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
            .withClient("clientapp")
            .secret("123456") 
            .redirectUris("http://localhost:9000/callback")
            .authorizedGrantTypes("password") 
            .scopes("read_profile", "read_contacts"); 
    }
}

7.與《學習3》惟一不一樣的就是authorizedGrantType的設置,看上去和前兩種模式的設置差很少,可是當你直接運行應用時就會報錯:

{ 
    "error": "unsupported_grant_type",
     "error_description": "Unsupported grant type: password"
}

8.那是由於,密碼模式須要在OAuth2AuthorizationServer 中配置AuthenticationManager

這是完整的OAuth2AuthorizationServer 類:

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServer extends
        AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints)
            throws Exception {
        endpoints.authenticationManager(authenticationManager);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients)
            throws Exception {
        clients.inMemory()
            .withClient("clientapp")
            .secret("123456")
            .authorizedGrantTypes("password")
            .scopes("read_profile", "read_contacts");
    }

}

如今,咱們能夠啓動項目了

How it works…

當咱們使用@EnableAuthorizationServer@EnableResourceServer這兩個註解時,已經經過spring security配置上oauth2.0的全部支持,正如前幾個課程所示。最大的不一樣,是咱們在OAuth2AuthorizationServer中注入了authenticationManager 實例。咱們之因此要使用這個實例是由於,受權中心在對第三方,攜帶access token的請求作出迴應時,須要驗證資源全部者的證書。

處理配置上的不一樣,在驗證流程上也有所不一樣。在使用密碼模式時,用戶(或者稱爲資源全部者)必須發送憑證(用戶名,密碼),而這些操做將會在客戶端的掌控下。所以,在使用這種模式與客戶端和服務端交互時,須要資源全部者必須十分信任客戶端。例如,你做爲資源全部者與facebook的官方客戶端交互,以後有轉爲與facebook的服務端作交互。

如今,咱們來看看,如何使用密碼模式來獲取資源:

1.首先發送如下請求:

curl -X POST --user clientapp:123456 <http://localhost:8080/oauth/token> -H "accept: application/json" -H "content-type: application/x-www-formurlencoded" -d "grant_type=password&username=adolfo&password=123&scope=read_profile"

或者使用postman:
圖片描述

圖片描述

圖片描述

2.在上一步,咱們拿到了access token,如今咱們就可使用這個token來獲取資源了,注意,咱們在以前沒有設置token的過時時間,Spring Security OAuth2默認是43200s。咱們應該根據受權模式的不一樣,設置不一樣的過時時間,例如隱式模式就應該使用短一些的過時時間。好了,如今咱們來請求資源:
圖片描述

curl -X GET <http://localhost:8080/api/profile> -H "authorization: Bearer 28405009-b53d-4e52-bfc3-c8889a477675"

There's more…

​ 儘管咱們建議儘可能不要使用密碼模式,可是若是當你交互的客戶端與服務端(驗證中心)都在一個範圍內(公司/部門/名下)的時候,能夠大膽使用。須要注意的是,客戶端不該保留用戶的用戶名和密碼。

相關文章
相關標籤/搜索