如何使用终端命令去调用测试Spring Boot2 Cloud OAuth2 JWT授权服务器接口生成Token值

范例项目目录结构图如下:

AuthorizationServerApplication.java

package com.contoso;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AuthorizationServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(AuthorizationServerApplication.class, args);
	}
}

OAuth2AuthorizationServerConfig1.java

package com.contoso.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig1 extends AuthorizationServerConfigurerAdapter {

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer
          .tokenKeyAccess("permitAll()")
          .checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
    	// @formatter:off
    	clients.inMemory()
          .withClient("sampleClientId")
          .authorizedGrantTypes("implicit")
          .scopes("read", "write", "foo", "bar")
          .autoApprove(false)
          .accessTokenValiditySeconds(3600)
          .redirectUris("http://localhost:8083/","http://www.baidu.com/")
          .and()
          .withClient("applicationClientId")
          .secret(passwordEncoder().encode("secret"))
          .authorizedGrantTypes("client_credentials")
          .scopes("read", "write", "foo", "bar")
          .and()
          .withClient("fooClientId")
          .secret(passwordEncoder().encode("secret"))
          .authorizedGrantTypes("password", "authorization_code", "refresh_token")
          .scopes("foo", "read", "write")
          .accessTokenValiditySeconds(3600) // 1 hour
          .refreshTokenValiditySeconds(2592000) // 30 days
          .redirectUris("http://localhost:8089/","http://www.baidu.com/")
          .and()
          .withClient("barClientId")
          .secret(passwordEncoder().encode("secret"))
          .authorizedGrantTypes("password", "authorization_code", "refresh_token")
          .scopes("bar", "read", "write")
          .accessTokenValiditySeconds(3600) // 1 hour 
          .refreshTokenValiditySeconds(2592000) // 30 days
          .redirectUris("http://localhost:8089/","http://www.baidu.com/")
	      .and()
	      .withClient("testImplicitClientId")
	      .authorizedGrantTypes("implicit")
	      .scopes("read", "write", "foo", "bar")
	      .autoApprove(true)
	      .redirectUris("xxx");
    }   // @formatter:on

    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        defaultTokenServices.setSupportRefreshToken(true);
        return defaultTokenServices;
    }

    @Override
    public void configure(final AuthorizationServerEndpointsConfigurer conf) { 
    	// @formatter:off
		conf.tokenStore(tokenStore())
		    .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
			.accessTokenConverter(accessTokenConverter())
			.authenticationManager(authenticationManager);
	} // @formatter:on

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        final JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("123");
        // final KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("mytest.jks"), "mypass".toCharArray());
        // converter.setKeyPair(keyStoreKeyFactory.getKeyPair("mytest"));
        return converter;
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

WebSecurityConfig.java

package com.contoso.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;
    
    @Autowired
    public void globalUserDetails(final AuthenticationManagerBuilder auth) throws Exception {
    	// @formatter:off
    	auth.inMemoryAuthentication()
  	  	  .withUser("john").password(passwordEncoder.encode("123")).roles("USER").and()
  	  	  .withUser("jack").password(passwordEncoder.encode("111")).roles("ADMIN");
	}   // @formatter:on

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        // @formatter:off
   		http.authorizeRequests().antMatchers("/login").permitAll()
   		.antMatchers("/oauth/token/revokeById/**").permitAll()
   		.antMatchers("/tokens/**").permitAll()
   		.anyRequest().authenticated()
   		.and().formLogin().permitAll()
   		.and().csrf().disable();
    }   // @formatter:on

}

application.yml

server:
  port: 8081
  servlet:
    context-path: /uaa

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.contoso</groupId>
	<artifactId>spring-boot-cloud-oauth2-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>spring-boot-cloud-oauth2-demo</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.4.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<spring-cloud.version>Finchley.SR1</spring-cloud.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-oauth2</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-security</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

README.md

在线BASE64编码&解码工具(注意:BASE64编码不是一种加密数据)
http://tool.oschina.net/encrypt?type=3

sampleClientId:secret 键-值对对应的BASE64编码 c2FtcGxlQ2xpZW50SWQ6c2VjcmV0
applicationClientId:secret 键-值对对应的BASE64编码 YXBwbGljYXRpb25DbGllbnRJZDpzZWNyZXQ=
fooClientId:secret 键-值对对应的BASE64编码 Zm9vQ2xpZW50SWQ6c2VjcmV0
barClientId:secret 键-值对对应的BASE64编码 YmFyQ2xpZW50SWQ6c2VjcmV0

如何使用终端命令去调用测试Spring Boot2 Cloud OAuth2 JWT授权服务器接口生成Token值
======================================================================================


客户端的授权模式
授权码模式(authorization code)

浏览器结合终端命令调用授权服务器范例1:

第1步:使用浏览器直接访问以下链接地址获得一个一次性临时code值
http://localhost:8081/uaa/oauth/authorize?response_type=code&scope=read write foo&client_id=fooClientId&redirect_uri=http://www.baidu.com/&state=x1y1

第2步:自动跳转到登录链接http://localhost:8081/uaa/login
在浏览器登录页面输入用户名称和用户密码
用户名称:john
用户密码:123

当我们登录成功后,自动跳转到如下链接地址
http://localhost:8081/uaa/oauth/authorize?response_type=code&scope=read%20write%20foo&client_id=fooClientId&redirect_uri=http://www.baidu.com/&state=x1y1
页面
Do you authorize 'fooClientId' to access your protected resources?
点击Authorize按钮
从浏览器地址栏中复制出回调返回的code参数值粘贴到终端命令中,例如:回调链接地址中code=VXB8gE

第3步:使用一次性临时code值与授权服务器交换获得一个token值

终端命令调用授权服务器范例1:
fooClientId:secret 键-值对对应的BASE64编码 Zm9vQ2xpZW50SWQ6c2VjcmV0

curl -i -X POST http://localhost:8081/uaa/oauth/token \
-H 'authorization: Basic Zm9vQ2xpZW50SWQ6c2VjcmV0' \
-H "Accept: application/json" \
-d "client_id=fooClientId&client_secret=secret&grant_type=authorization_code&code=VXB8gE&redirect_uri=http://www.baidu.com/"


浏览器结合终端命令调用授权服务器范例2:

第1步:使用浏览器直接访问以下链接地址获得一个一次性临时code值
http://localhost:8081/uaa/oauth/authorize?response_type=code&scope=read write bar&client_id=barClientId&redirect_uri=http://www.baidu.com/&state=x2y2

第2步:自动跳转到登录链接http://localhost:8081/uaa/login
在浏览器登录页面输入用户名称和用户密码
用户名称:john
用户密码:123

当我们登录成功后,自动跳转到如下链接地址
http://localhost:8081/uaa/oauth/authorize?response_type=code&scope=read%20write%20bar&client_id=barClientId&redirect_uri=http://www.baidu.com/&state=x2y2
页面
Do you authorize 'barClientId' to access your protected resources?
点击Authorize按钮

从浏览器地址栏中复制出回调返回的code参数值粘贴到终端命令中,例如:回调链接地址中code=VnESYV

第3步:使用一次性临时code值与授权服务器交换获得一个token值

终端命令调用授权服务器范例2:
barClientId:secret 键-值对对应的BASE64编码 YmFyQ2xpZW50SWQ6c2VjcmV0

curl -i -X POST http://localhost:8081/uaa/oauth/token \
-H 'authorization: Basic YmFyQ2xpZW50SWQ6c2VjcmV0' \
-H "Accept: application/json" \
-d "client_id=barClientId&client_secret=secret&grant_type=authorization_code&code=VnESYV&redirect_uri=http://www.baidu.com/"


======================================================================================


客户端的授权模式
简化模式(implicit):
response_type:表示授权类型,此处的值固定为"token",必选项。
直接在浏览器中向授权服务器申请令牌

第1步:直接在浏览器里输入以下链接地址
http://localhost:8081/uaa/oauth/authorize?response_type=token&client_id=sampleClientId&redirect_uri=http://www.baidu.com/&scope=read write foo bar&state=123

第2步:自动跳转到登录链接http://localhost:8081/uaa/login
在浏览器登录页面输入用户名称和用户密码
用户名称:john
用户密码:123

第3步:当我们登录成功后,自动跳转到以下链接地址页面
http://localhost:8081/uaa/oauth/authorize?response_type=token&client_id=sampleClientId&redirect_uri=http://www.baidu.com/&scope=read write foo bar&state=123

Do you authorize 'sampleClientId' to access your protected resources?
点击Authorize按钮
 
当授权操作成功后回调返回包含token值链接地址
https://www.baidu.com/#access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MzU5MDgzNzMsInVzZXJfbmFtZSI6ImpvaG4iLCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwianRpIjoiZDU5ZGNmYjAtNzU5Zi00MmRlLWI5MTctZDYwYjM4OTJmMTQ1IiwiY2xpZW50X2lkIjoic2FtcGxlQ2xpZW50SWQiLCJzY29wZSI6WyJiYXIiLCJmb28iLCJyZWFkIiwid3JpdGUiXX0.pgJBYvugTYMt_urDfhg5s6e7hletN6IFCji1XdEuC4s&token_type=bearer&state=123&expires_in=3599&jti=d59dcfb0-759f-42de-b917-d60b3892f145


======================================================================================


客户端的授权模式
密码模式(Resource Owner Password Credentials Grant)

终端命令调用授权服务器范例1:
fooClientId:secret 键-值对对应的BASE64编码 Zm9vQ2xpZW50SWQ6c2VjcmV0

curl -i -X POST http://localhost:8081/uaa/oauth/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Authorization: Basic Zm9vQ2xpZW50SWQ6c2VjcmV0' \
-d 'grant_type=password&username=john&password=123'


终端命令调用授权服务器范例2:
barClientId:secret 键-值对对应的BASE64编码 YmFyQ2xpZW50SWQ6c2VjcmV0

curl -i -X POST http://localhost:8081/uaa/oauth/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Authorization: Basic YmFyQ2xpZW50SWQ6c2VjcmV0' \
-d 'grant_type=password&username=john&password=123'


======================================================================================


客户端的授权模式
客户端模式(client credentials)

终端命令调用授权服务器范例1:
applicationClientId:secret 键-值对对应的BASE64编码 YXBwbGljYXRpb25DbGllbnRJZDpzZWNyZXQ=

curl -i -X POST http://localhost:8081/uaa/oauth/token \
-H 'authorization: Basic YXBwbGljYXRpb25DbGllbnRJZDpzZWNyZXQ=' \
-H 'cache-control: no-cache' \
-H 'content-type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials&client_id=applicationClientId&client_secret=secret'
  

  

使用在线JWT解码工具http://jwt.io解析JWT的默认结构包括那些字段,不同的客户端授权请求方式返回的Token值结

构稍微有点差别,我们可以很容易看出这个JWT Token值是采用简化模式(implicit)请求授权服务器生成的

你可能立刻会想,我怎么扩展定义JWT token的结构昵?

自定义一个扩展JWT Token字段的CustomTokenEnhancer类,该类继承TokenEnhancer接口,

其中organization是自定义扩展字段,我们可以按照此方法扩展很多个我们需要的字段键值对到JWT Token结构中:

package com.contoso.config;

import java.util.HashMap;
import java.util.Map;

import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;

public class CustomTokenEnhancer implements TokenEnhancer {

    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
        final Map<String, Object> additionalInfo = new HashMap<>();
        additionalInfo.put("organization", authentication.getName());
        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
        return accessToken;
    }
}

我们接着删除OAuth2AuthorizationServerConfig1.java文件代码中不需要的如下重写方法:

    @Override
    public void configure(final AuthorizationServerEndpointsConfigurer conf) { 
    	// @formatter:off
		conf.tokenStore(tokenStore())
		    .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
			.accessTokenConverter(accessTokenConverter())
			.authenticationManager(authenticationManager);
	} // @formatter:on

随即插入如下代码:

    @Override
    public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        final TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), accessTokenConverter()));
        endpoints
          .tokenStore(tokenStore())
          .tokenEnhancer(tokenEnhancerChain)
          .authenticationManager(authenticationManager);
    }
    
    @Bean
    public TokenEnhancer tokenEnhancer() {
        return new CustomTokenEnhancer();
    }

我们调整修改好的OAuth2AuthorizationServerConfig1.java文件代码如下:

package com.contoso.config;

import java.util.Arrays;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig1 extends AuthorizationServerConfigurerAdapter {

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer
          .tokenKeyAccess("permitAll()")
          .checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
    	// @formatter:off
    	clients.inMemory()
          .withClient("sampleClientId")
          .authorizedGrantTypes("implicit")
          .scopes("read", "write", "foo", "bar")
          .autoApprove(false)
          .accessTokenValiditySeconds(3600)
          .redirectUris("http://localhost:8083/","http://www.baidu.com/")
          .and()
          .withClient("applicationClientId")
          .secret(passwordEncoder().encode("secret"))
          .authorizedGrantTypes("client_credentials")
          .scopes("read", "write", "foo", "bar")
          .and()
          .withClient("fooClientId")
          .secret(passwordEncoder().encode("secret"))
          .authorizedGrantTypes("password", "authorization_code", "refresh_token")
          .scopes("foo", "read", "write")
          .accessTokenValiditySeconds(3600) // 1 hour
          .refreshTokenValiditySeconds(2592000) // 30 days
          .redirectUris("http://localhost:8089/","http://www.baidu.com/")
          .and()
          .withClient("barClientId")
          .secret(passwordEncoder().encode("secret"))
          .authorizedGrantTypes("password", "authorization_code", "refresh_token")
          .scopes("bar", "read", "write")
          .accessTokenValiditySeconds(3600) // 1 hour 
          .refreshTokenValiditySeconds(2592000) // 30 days
          .redirectUris("http://localhost:8089/","http://www.baidu.com/")
	      .and()
	      .withClient("testImplicitClientId")
	      .authorizedGrantTypes("implicit")
	      .scopes("read", "write", "foo", "bar")
	      .autoApprove(true)
	      .redirectUris("xxx");
    }   // @formatter:on

    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        defaultTokenServices.setSupportRefreshToken(true);
        return defaultTokenServices;
    }

    @Override
    public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        final TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), accessTokenConverter()));
        endpoints
          .tokenStore(tokenStore())
          .tokenEnhancer(tokenEnhancerChain)
          .authenticationManager(authenticationManager);
    }
    
    @Bean
    public TokenEnhancer tokenEnhancer() {
        return new CustomTokenEnhancer();
    }

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        final JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("123");
        // final KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("mytest.jks"), "mypass".toCharArray());
        // converter.setKeyPair(keyStoreKeyFactory.getKeyPair("mytest"));
        return converter;
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

客户端的授权模式
授权码模式(authorization code)

浏览器结合终端命令调用授权服务器范例1:

第1步:使用浏览器直接访问以下链接地址获得一个一次性临时code值

http://localhost:8081/uaa/oauth/authorize?response_type=code&scope=read write foo&client_id=fooClientId&redirect_uri=http://www.baidu.com/&state=x1y1

第2步:自动跳转到登录链接http://localhost:8081/uaa/login
在浏览器登录页面输入用户名称和用户密码
用户名称:john
用户密码:123

当我们登录成功后,自动跳转到如下链接地址
http://localhost:8081/uaa/oauth/authorize?response_type=code&scope=read%20write%20foo&client_id=fooClientId&redirect_uri=http://www.baidu.com/&state=x1y1
页面
Do you authorize 'fooClientId' to access your protected resources?
点击Authorize按钮
从浏览器地址栏中复制出回调返回的code参数值粘贴到终端命令中,例如:回调链接地址中code=5K9gyO

第3步:使用一次性临时code值与授权服务器交换获得一个token值

终端命令调用授权服务器范例1:
fooClientId:secret 键-值对对应的BASE64编码 Zm9vQ2xpZW50SWQ6c2VjcmV0

curl -i -X POST http://localhost:8081/uaa/oauth/token \
-H 'authorization: Basic Zm9vQ2xpZW50SWQ6c2VjcmV0' \
-H "Accept: application/json" \
-d "client_id=fooClientId&client_secret=secret&grant_type=authorization_code&code=5K9gyO&redirect_uri=http://www.baidu.com/"

HTTP/1.1 200 
Cache-Control: no-store
Pragma: no-cache
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Mon, 03 Sep 2018 02:01:20 GMT

{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJqb2huIiwic2NvcGUiOlsiZm9vIiwicmVhZCIsIndyaXRlIl0sIm9yZ2FuaXphdGlvbiI6ImpvaG4iLCJleHAiOjE1MzU5NDM2ODAsImF1dGhvcml0aWVzIjpbIlJPTEVfVVNFUiJdLCJqdGkiOiI5NDY3OTljNi02ZDZhLTRlOTktOGJjMS02M2U2YjU2ZGQ2MWYiLCJjbGllbnRfaWQiOiJmb29DbGllbnRJZCJ9.n-Elia5L9ZGzSncxNq7e4QoGE-vxFOjGgk_GvhS5MMA","token_type":"bearer","refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJqb2huIiwic2NvcGUiOlsiZm9vIiwicmVhZCIsIndyaXRlIl0sIm9yZ2FuaXphdGlvbiI6ImpvaG4iLCJhdGkiOiI5NDY3OTljNi02ZDZhLTRlOTktOGJjMS02M2U2YjU2ZGQ2MWYiLCJleHAiOjE1Mzg1MzIwODAsImF1dGhvcml0aWVzIjpbIlJPTEVfVVNFUiJdLCJqdGkiOiI2ZjVhYjNmNy03OTQ1LTQ2ZGQtYjNhZS0xMWYxYjE4MzA4MjkiLCJjbGllbnRfaWQiOiJmb29DbGllbnRJZCJ9.F3T-PB9QyTzytEHZm_plhyq3MlXu2Hl8bWbQR3tT_ZA","expires_in":3599,"scope":"foo read write","organization":"john","jti":"946799c6-6d6a-4e99-8bc1-63e6b56dd61f"}

猜你喜欢

转载自blog.csdn.net/zhengzizhi/article/details/82321074
今日推荐