关闭

[置顶] 如何用Spring OAuth2.0 Client组件获取授权access_token

标签: Spring OAuth2 ClientOAuth2.0 ClientOAuth2 Access_TokenSpring OAuth2.0 Clie
4157人阅读 评论(0) 收藏 举报

使用背景 :公司有个开放平台,若要访问开放平台,必须先要获取授权访问令牌(也就是下面说的:access_token)。公司的授权系统是用spring oauth2.0实现的,今天就不讲这个项目,网上比较多。今天主要是讲下如何用spring OAuth2.0 Client 组件会去实现高效获取access_token。

以下是实现代码:


1.项目启动后,从oauth.properties获取相关的信息(如公钥、私钥等信息),然后实例化OAuth2RestTemplate,主要是通过OAuth2RestTemplate这个类去获取access_token,.

@EnableOAuth2Client
@Configuration
@Component
public class Oauth2Config{
	
	private final static Logger logger = Logger.getLogger(Oauth2Config.class);
	
	private static String location = "classpath:config/*/oauth.properties";
	
	private static Map<String,String> oauthInfo = new HashMap<String,String>();
	
	@Autowired
	private OAuth2ClientContext oauth2Context;
	
	/**
	 * 获取配置文件信息
	 */
	static{
		ResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
		Resource[] resources;
		try {
			resources = patternResolver.getResources(location);
			location = resources[0].getFile().getAbsolutePath();
			logger.info("location" + location);
			Properties props = new Properties();  
	        try {  
	        	if(location.contains("dev")){
	        		props = PropertiesLoaderUtils.loadAllProperties("config/dev/oauth.properties");
	        	}else if(location.contains("test")){
	        		props = PropertiesLoaderUtils.loadAllProperties("config/test/oauth.properties");
	        	}else if(location.contains("production")){
	        		props = PropertiesLoaderUtils.loadAllProperties("config/production/oauth.properties");
	        	}
	            for(Object key:props.keySet()){  
	            	logger.warn(key + " : " +  (String)props.get(key));
	            	oauthInfo.put((String) key, (String)props.get(key));
	            }  
	        } catch (IOException e) {  
	            System.out.println(e.getMessage());  
	        }  
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	} 
	
	
	@Bean
	public AccessTokenRequest accessTokenRequest(){
		AccessTokenRequest defaultAccessTokenRequest = new DefaultAccessTokenRequest();
		Map<String, List<String>> headers = new HashMap<String, List<String>>();
		List<String> headerList=new ArrayList<String>();
		headerList.add("Basic " + oauthInfo.get("public_key"));
        headers.put("Authorization", headerList);
        defaultAccessTokenRequest.setHeaders(headers);
        defaultAccessTokenRequest.setCurrentUri(oauthInfo.get("redirect_uri"));
	    return defaultAccessTokenRequest;
	}
	
	@Bean
	public AuthorizationCodeResourceDetails resourceDetails(){
		AuthorizationCodeResourceDetails resource = new AuthorizationCodeResourceDetails();
		resource.setAccessTokenUri(oauthInfo.get("oauth_url") + oauthInfo.get("request_and_refresh_token"));
		resource.setClientId(oauthInfo.get("client_id"));
        resource.setGrantType("authorization_code");
        resource.setUserAuthorizationUri(oauthInfo.get("oauth_url") + oauthInfo.get("request_code_url"));
        resource.setScope(Arrays.asList("app"));
        resource.setPreEstablishedRedirectUri(oauthInfo.get("redirect_uri"));
	    return resource;
	}
	
	@Bean
	public OAuth2RestTemplate oAuth2RestTemplate(){
        accessTokenRequest().setPreservedState(oauthInfo.get("redirect_uri"));
        accessTokenRequest().setStateKey(new DefaultStateKeyGenerator().generateKey(resourceDetails()));
        
        AuthorizationCodeAccessTokenProvider provider = new AuthorizationCodeAccessTokenProvider();
        provider.setAuthenticationHandler(new ClientAuthenticationHandler() {
			@Override
			public void authenticateTokenRequest(
					OAuth2ProtectedResourceDetails resource,
					MultiValueMap<String, String> form, HttpHeaders headers) {
				headers.set("Authorization", "Basic " + oauthInfo.get("private_key") );
			}
		});
        AccessTokenProviderChain providerChain = new AccessTokenProviderChain(Arrays.asList(provider));
        //oauth2Context.setPreservedState(accessTokenRequest().getStateKey(),accessTokenRequest().getPreservedState());
        OAuth2RestTemplate template=new OAuth2RestTemplate(resourceDetails(),oauth2Context);
        template.setAccessTokenProvider(providerChain);
        return template;
	}

	
}


2.通过OAuth2RestTemplate去获取access_token的值,之所以每次都情况授权code,是因为spring oauth2授权code只能用一次便废弃,然后起OAuth2ClientContext类又不主动清空code,这里我只能自己手动清除。

@Component
public class AccessTokenUtils {

	private final static Logger logger = Logger.getLogger(AccessTokenUtils.class);
	
	
	@Autowired
    private OAuth2RestTemplate restTemplate;
	
	@Autowired
	private Oauth2Config oauth2Config;
	
	
	/**
	 * 获取oauth2的授权令牌access_token
	 * @return
	 */
	public  String getAccessToken(){
		logger.info("获取oauth2的授权令牌access_token start ...");
		OAuth2ClientContext oAuth2ClientContext = restTemplate.getOAuth2ClientContext();
		oAuth2ClientContext.getAccessTokenRequest().setAuthorizationCode(null);//清空授权code
		String stateKey = oAuth2ClientContext.getAccessTokenRequest().getStateKey();
		Object preservedState = oAuth2ClientContext.getAccessTokenRequest().getPreservedState();
		if(StringUtils.isEmpty(stateKey))
			stateKey = new DefaultStateKeyGenerator().generateKey(oauth2Config.resourceDetails());
		if(preservedState == null )
			preservedState = VipConstant.redirtUrl;
		
		logger.info("statekey:" + stateKey + " ; preservedState : " + preservedState);
		oAuth2ClientContext.setPreservedState(oAuth2ClientContext.getAccessTokenRequest().getStateKey(), oAuth2ClientContext.getAccessTokenRequest().getPreservedState());
		OAuth2AccessToken oAuth2AccessToken = this.restTemplate.getAccessToken();
		String access_token = oAuth2AccessToken.getValue();
		logger.info("获取oauth2的授权令牌access_token end ;access_token = " +  access_token + ";失效时间 = " + oAuth2AccessToken.getExpiration() + " ;剩余失效时间:" + oAuth2AccessToken.getExpiresIn() );
		return access_token;
	}
	
}


3.以下配置是授权服务给配置的

#==================spring oauth2.0=====================================
#客户端ID
client_id=xxx
#公钥(BASE64(xx))
public_key=xxx
#私钥(BASE64(xx))
private_key=xx
#spring oauth2.0服务url
oauth_url=xxx
#获取请求code URL
request_code_url=oauth/authorize
#获取请求token或刷新token URL
request_and_refresh_token=oauth/token
#回调地址
redirect_uri=http://www.baidu.com

Spring OAuth2.0 Client官网地址:http://projects.spring.io/spring-security-oauth/docs/oauth2.html



0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Spring Security 与 Oauth2 整合 步骤

为什么要写 1. spring-security-oauth2的demo 不容易让开发者理解, 配置的内容很多, 没有分解的步骤; 我曾经试着按照文档(https://github.com/spring-projects/spring-security-oauth/blob/master/docs/...
  • monkeyking1987
  • monkeyking1987
  • 2013-11-19 22:31
  • 112232

Spring cloud oauth2.0的源码解析与实践Demo

一、源码代码介绍 上一篇已经大致介绍了一下Spring cloud oauth2.0,点此查看上一篇,现在再来大致分析一下它的源码结构,Spring cloud oauth2.0的代码结构图如下: 可以看到Spring oauth2.0的代码结构分为了五层,client层负责应用客户端的管理。...
  • j754379117
  • j754379117
  • 2017-04-14 23:49
  • 11786

springsecurity+oauth2.0+服务端和客户端代码

  • 2015-01-27 10:43
  • 16.78MB
  • 下载

Oauth2.0 用Spring-security-oauth2 非常简单

上周,我想开发OAuth 2.0的一个实例。我检查了Spring-security-Oauth2.0的样例,OAuth 2提供商sparklr2和OAuth 2客户端TONR 。我探索在互联网上了一下,整理相关文档。编译并运行了OAuth 2提供商sparklr2和OAuth 2客户端TON...
  • u011537073
  • u011537073
  • 2016-08-03 22:45
  • 20795

spring oauth2.0入门(实战)

1.首先spring security基本配置 public class ServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { ...... @Override public vo...
  • buyaore_wo
  • buyaore_wo
  • 2015-09-23 15:42
  • 11971

【OAuth2.0】Spring Security OAuth2.0篇之初识

不吐不快      因为项目需求开始接触OAuth2.0授权协议。断断续续接触了有两周左右的时间。不得不吐槽的,依然是自己的学习习惯问题,总是着急想了解一切,习惯性地钻牛角尖去理解小的细节,而不是从宏观上去掌握,或者说先用起来(少年,一辈子辣么长,你这么着急合适吗?)。好在前人们...
  • u010880345
  • u010880345
  • 2015-12-20 15:43
  • 1663

SpringBoot+SpringSecurityOAuth2.0 实现SSO单点登录(一)--服务端

SSO Server 前期准备: 使用maven构建项目,导入1.5.4SpringBoot父jar包 parent> groupId>org.springframework.bootgroupId> artifactId>spring-boot-starter-p...
  • u013783079
  • u013783079
  • 2017-07-18 15:57
  • 10831

Spring boot --Oauth2.0 + 单点登录

单点登录什么是单点登录。可以参考这篇文章http://www.cnblogs.com/ywlaker/p/6113927.html,简单了来说,当用户登录了一个子系统后,再访问其他系统的时候,就不用再登录了。实现原理的时序图如下: 可以看出来,用户的登录状态是由SSO认证中心来保存的,...
  • Mr_Fogg
  • Mr_Fogg
  • 2017-06-08 19:56
  • 8066

spring oauth2.0 demo入门分析

这里不对如何实现oauth2.0分析,也不对security做分析,读者可以google下security相关的知识,这里主要列出看oauth2.0demo时流程流转存在的疑惑。 1.oauth 2.0中的四个角色,资源拥有者,资源服务器,授权服务器,客户端。 2.spring secu...
  • HMC20071120015
  • HMC20071120015
  • 2012-11-20 17:57
  • 8241

使用OAuth2的SSO分析

参考:https://github.com/spring-guides/tut-spring-security-and-angular-js/blob/master/oauth2-vanilla/README.adoc 1.浏览器向UI服务器点击触发要求安全认证 2.跳转到授权服务器获取授权...
  • xiejx618
  • xiejx618
  • 2016-04-01 21:37
  • 26217
    个人资料
    • 访问:7966次
    • 积分:157
    • 等级:
    • 排名:千里之外
    • 原创:6篇
    • 转载:6篇
    • 译文:0篇
    • 评论:2条
    文章分类
  • 3(1)
    最新评论