关闭

如何用Spring OAuth2.0 Client组件获取授权access_token

标签: Spring OAuth2 ClientOAuth2.0 ClientOAuth2 Access_TokenSpring OAuth2.0 Clie
1906人阅读 评论(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网站的观点或立场
    个人资料
    • 访问:4212次
    • 积分:127
    • 等级:
    • 排名:千里之外
    • 原创:7篇
    • 转载:6篇
    • 译文:0篇
    • 评论:1条
    文章分类
  • 3(1)
    最新评论