spring-oauth

1:項目入門DEMO

1:POM文件

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">

   <modelVersion>4.0.0</modelVersion>

 

   <groupId>com.hujiang.boot</groupId>

   <artifactId>auth-service</artifactId>

   <version>0.0.1-SNAPSHOT</version>

   <packaging>jar</packaging>

 

   <name>auth-service</name>

   <url>http://maven.apache.org</url>

 

   <parent>

      <groupId>org.springframework.boot</groupId>

      <artifactId>spring-boot-starter-parent</artifactId>

      <version>1.2.3.RELEASE</version>

      <relativePath />

   </parent>

 

   <dependencies>

      <dependency>

         <groupId>org.springframework.boot</groupId>

         <artifactId>spring-boot-starter-security</artifactId>

      </dependency>

      <dependency>

         <groupId>org.springframework.security.oauth</groupId>

         <artifactId>spring-security-oauth2</artifactId>

         <version>2.0.7.RELEASE</version>

      </dependency>

      <dependency>

         <groupId>org.springframework.boot</groupId>

         <artifactId>spring-boot-starter-web</artifactId>

      </dependency>

   </dependencies>

</project>

 

 

 

 

 

 

 

2:Main方法

@Configuration

@ComponentScan

@EnableAutoConfiguration

@RestController

@SessionAttributes("authorizationRequest")

@EnableResourceServer

public class AuthserverApplication extends WebMvcConfigurerAdapter {

 

   public static void main(String[] args) {

      SpringApplication.run(AuthserverApplication.class, args);

   }

 

   @RequestMapping("/hello")

   public String hello() {

      return "hello";

   }

 

  

   @Configuration

   @EnableAuthorizationServer

   protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {

 

      @Autowired

      private AuthenticationManager authenticationManager;

     

      @Override

      public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

         clients.inMemory().withClient("acme").secret("acmesecret")

            .authorizedGrantTypes("client_credentials").scopes("openid");

      }

 

      @Override

      public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

         endpoints.authenticationManager(authenticationManager);

      }

 

      @Override

      public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {

      oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");

      }

 

   }

}

 

3:測試:

通過curl http://localhost:8080/hello訪問,返回認證失敗

{"error":"unauthorized","error_description":"Fullauthentication is required to access this resource"}

 

先拿到訪問TOKEN

curl -v -X POST"acme:acmesecret@localhost:8080/oauth/token?grant_type=client_credentials"

{"access_token":"b92fd988-d95b-427c-84bf-65da969e45f0","token_type":"bearer","expires_in":42933,"scope":"openid"}

 

請求接口:

curl -H "Authorization:Bearerb92fd988-d95b-427c-84bf-65da969e45f0" http://localhost:8080/hello

或者curl http://localhost:8080/hello?access_token=b92fd988-d95b-427c-84bf-65da969e45f0

返回hello

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2:通過http請求,驗證TOKEN的有效性

1:默認配置

驗證token

正確:

失敗:


總結:這種方式不適合我們項目,A調用B時,不能把A的client_id和secret也傳遞給B。

如果不傳遞,默認情況下/oauth/check_token是受保護的接口;如果B不需要調用其他的服務,是不需要註冊的,所以直接調用該接口,會提示未認證。

 

2:修改配置,/oauth/check_token暴露出去,不受oauth保護

applicationContext.properties添加如下配置

security.ignored=/welcome,/oauth/check_token


正確:


失敗:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3:如何配置JDBC數據庫

http://andaily.com/spring-oauth-server/db_table_description.html

1:代碼修改

2:創建數據庫表

-- used in tests that use HSQL

create table oauth_client_details (

 client_id VARCHAR(256) PRIMARY KEY,

 resource_ids VARCHAR(256),

 client_secret VARCHAR(256),

 scope VARCHAR(256),

 authorized_grant_types VARCHAR(256),

 web_server_redirect_uri VARCHAR(256),

 authorities VARCHAR(256),

 access_token_validity INTEGER,

 refresh_token_validity INTEGER,

 additional_information VARCHAR(4096),

 autoapprove VARCHAR(256)

);

 

create table oauth_client_token (

 token_id VARCHAR(256),

 token LONGVARBINARY,

 authentication_id VARCHAR(256) PRIMARY KEY,

 user_name VARCHAR(256),

 client_id VARCHAR(256)

);

 

create table oauth_access_token (

 token_id VARCHAR(256),

 token LONGVARBINARY,

 authentication_id VARCHAR(256) PRIMARY KEY,

 user_name VARCHAR(256),

 client_id VARCHAR(256),

 authentication LONGVARBINARY,

 refresh_token VARCHAR(256)

);

 

create table oauth_refresh_token (

 token_id VARCHAR(256),

 token LONGVARBINARY,

 authentication LONGVARBINARY

);

 

create table oauth_code (

 code VARCHAR(256), authentication LONGVARBINARY

);

 

create table oauth_approvals (

         userIdVARCHAR(256),

         clientIdVARCHAR(256),

         scopeVARCHAR(256),

         statusVARCHAR(10),

         expiresAtTIMESTAMP,

         lastModifiedAtTIMESTAMP

);

 

 

-- customized oauth_client_details table

create table ClientDetails (

 appId VARCHAR(256) PRIMARY KEY,

 resourceIds VARCHAR(256),

 appSecret VARCHAR(256),

 scope VARCHAR(256),

 grantTypes VARCHAR(256),

  redirectUrlVARCHAR(256),

 authorities VARCHAR(256),

 access_token_validity INTEGER,

 refresh_token_validity INTEGER,

 additionalInformation VARCHAR(4096),

 autoApproveScopes VARCHAR(256)

);

 

3:測試

沒有數據時:

 

執行SQL插入一條記錄:

insert oauth_client_details(client_id,client_secret,authorized_grant_types,scope)

values("acme","acmesecret","client_credentials","openid");

 

 

再次執行:

 

 

 

 

 

4:如何在運行時動態的修改客戶端

http://projects.spring.io/spring-security-oauth/docs/oauth2.html   (Configuring ClientDetails)

 

 

 

 

 

 

 

5:如何將TOKEN存庫

http://projects.spring.io/spring-security-oauth/docs/oauth2.html(Managing Tokens)

 

@Configuration

@EnableResourceServer

protected static class ResourceServer extendsResourceServerConfigurerAdapter {

 

   @Autowired

   private TokenStore tokenStore;

 

   @Override

   public voidconfigure(ResourceServerSecurityConfigurer resources) throws Exception {

      resources.tokenStore(tokenStore);

   }

 

   @Override

   public void configure(HttpSecurity http) throws Exception {

      http.authorizeRequests().anyRequest().authenticated();

   }

}

 

 

@Bean

publicJdbcTokenStore tokenStore() {

   return new JdbcTokenStore(dataSource);

}

 

@Override

public voidconfigure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

   endpoints.tokenStore(tokenStore());

}

 

 

 

6:如何把請求放到URL中訪問

在前面的demo中,獲取TOKEN,都是通過curl -v -X POST"acme:acmesecret@localhost:8080/oauth/token?grant_type=client_credentials"拿到的,如果使用我們熟悉的get方式 curl http://localhost:8080/uaa/oauth/token?grant_type=client_credentials&client_id=acme&client_secret=acmesecret或者post方式curl -d"grant_type=client_credentials&client_id=acme&client_secret=acmesecret"http://localhost:8080/uaa/oauth/token。會拋出一樣的錯誤提示。

 

修改我們上面的Oauth2Config類

重啓服務器,再次通過get,或者post提交試試.

POST請求

GET請求依然不支持

 

 

 

 

 

 

 

 

 

 

 

 

7:SCOPE的使用

我們知道,Oauth2.0中,生成TOKEN之後,就可以拿着TOKEN來訪問我受保護的resource了。但如果有個url,比如/A/B地址,我只希望指定的客戶端才能訪問,要如何操作呢。

 

1:數據庫對應的client

2:修改ResourceServer配置

 

測試:

1:使用ADMIN對應的客戶端acme進行測試

請求/uaa/oauth/token地址,獲取TOKEN


用生成的TOKEN,訪問hello

 

 

 

2:使用CLIENT對應的客戶端acme2進行測試

請求/uaa/oauth/token地址,獲取TOKEN

用生成的TOKEN,訪問hello

 

 

 

 

8:如何重寫ClientDetailsService

 

從源碼可以看到,ClientDetailsService的實現,來自於ClientDetailsServiceConfigurer的配置,而ClientDetailsServiceConfigurer只提供了inMemory和jdbc兩種方法。比如,要從遠程的restapi獲取client信息,我們可以自己實現一個ClientDetailsService,不用默認的。

 

 

 

 

 

 

 

 

 

9:擴展TOKEN內容

在例子8中,我們向Client中,添加了自定義的group和client。跟蹤TokenEndpoint源碼會發現,雖然OAuth2AccessToken提供了getAdditionalInformation方法,用來對Token進行擴展,但是源碼中並沒有將Client的擴展信息放入Token中,所以最終/oauth/token返回的json中,是沒有group和role信息的。跟蹤源碼,會發現生成Token是,提供了對token的擴展。


 

 

下面是接口實現


 

 

 

10:如何修改Header信息

默認情況,通過curl -H "Authorization:Bearer8bc6275d-ed2d-442e-b7b4-aa2fab536c4e" http://localhost:9003/uaa/v1/hello方式訪問資源

 

 

 

 

1:把/oauth/token配置到了security.ignored=/oauth/check_token,/oauth/token


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章