OAuth2 授权的流程/原理

OAuth是什么


先来简单介绍一下OAuth授权协议:OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。同时,任何第三方都可以使用OAuth认证服务,任何服务提供商都可以实现自身的OAuth认证服务,因而OAUTH是开放的。业界提供了OAuth的多种实现如 PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间,因而OAuth是简易的。目前互联网很多服务如Open API,很多大头公司如Google,Yahoo,Microsoft等都提供了OAuth认证服务,这些都足以说明OAUTH标准逐渐成为开放资源授权 的标准。 


OAuth的授权流程 


你所开发的应用需要流程如下: 
   1. 向应用服务商也就是服务提供商(QQ、新浪、搜狐等微博)请求request_token。 
   2. 得到request_token后重定向用户到服务商的授权页面。 
   3. 如果用户选择授权你的应用,用request_token向服务商请求换取access_token。 
   4. 得到access_token等信息访问受限资源。 

而服务商相应的响应如下: 

   1. 创建request_token返回给应用。 
   2. 询问用户是否授权此应用。如果用户授权重定向用户至应用页面。 
   3. 创建access_token并返回给应用。 
   4. 响应受限资源请求并返回相关信息。 

通俗点的说法就是“你拿着你得身份证明(request_token)向服务商申请进入用户家的门钥匙(access_token),服务商询问用户同不同意,如果用户同意服务商就给你进入用户家门的钥匙(access_token),拿到钥匙后你就可以进到用户家里”。 


OAuth授权的Java实现 


作为一个开放协议目前有很多现成的Oauth库可供开发者使用,可以点击这里下载。不过有精力有时间的话还是自己去实现一下OAuth授权的流程,可以很好的体会OAuth认证协议的原理。 

下面就是我使用Java实现Oauth的具体步骤: 
一、获取Request_token 

首先得准备一下参数及其来源: 

   1. oauth_consumer_key —— 注册应用后由应用服务商提供 
   2. consumer_secret —— 注册应用后由应用服务商提供 
   3. oauth_callback —— 用户授权后的返回地址 
   4. oauth_nonce —— 随机字符串,须保证每次都不同 
   5. oauth_timestamp —— 时间戳 
   6. oauth_signature_method —— 签名base string 的方法,目前支持 HMAC-SHA1 
   7. oauth_version —— Oauth协议版本 

还需要下面三个请求地址(这些地址任何一个提供OAuth的服务商都会提供给你,看下API文档就会找到): 

   1. requst_token_url —— 上面第1步中的请求地址 
   2. authorize_url —— 上面第2步的请求地址 
   3. access_token_url —— 上面第3步的请求地址 

至于如何注册应用,新浪微博点此,网易微博点此,腾讯微博点此,搜狐微博需要你发邮件索取,具体看这里。注册成功后就会获得oauth_consumer_key 和 consumer_secret 两个参数。 

oauth_callback 起的作用是当用户授权成功后服务商会把用户重定向到这个网址。 

oauth_nonce 是一个随机字符串下面是我的生成代码: 
 

public String set_nonce() { 
    String base = "abcdefghijklmnopqrstuvwxyz0123456789"; 
    Random random = new Random(); 
    StringBuffer sb = new StringBuffer(); 
    for (int i = 0; i < 18; i++) { 
    int number = random.nextInt(base.length()); 
    sb.append(base.charAt(number)); 
    } 
    return sb.toString(); 
} 



oauth_timestamp 是请求的时间戳,我的代码如下: 
 

public String set_timestamp() { 
    Date date = new Date(); 
    long time = date.getTime(); 
    return (time + "").substring(0, 10); 
} 



需要说明一下的是这里的时间戳为10位而不是13位,因此截取0-10位置。 

其他参数直接指定就行了。 

接下来,有了这些参数就可以组装base string了。贮备base string的目的就是为了得到 oauth_signature 这个参数,这个参数向服务商发送请求的时候需要用到。 

组装的方法是用下面8部分 

   1. POST(也可以是GET,取决于你应用服务商支持哪个)。 
   2. Urlencode之后的requst_token_url 。 
   3. oauth_callback=Urlencode之后你的oauth_callback(Urlencode的参数为“utf-8”)。 
   4. oauth_consumer_key = 你的oauth_consumer_key 
   5. oauth_nonce = 你的oauth_nonce 
   6. oauth_signature_method = 你的 oauth_signature_method 
   7. oauth_timestamp = 你的oauth_timestamp 
   8. oauth_version = “1.0”——目前大多数OAuth都采用的是1.0或1.0a版本。 

需 要注意的是上面除了1跟2外其他参数的格数形如: abc=“abc” ,然后先将上面1和2部分用&号相连得到串A、3-8部分用&相连得到串B,下面需要将串B再进行一次Urlencode得到串C,最后 将A跟C以&号相连就得到了base string。这个过程中 oauth_callback 实质上经过了两次 Urlencode ,组装base string是非常容易出错的,一不小心丢一个引号或者格式稍有不对就会出错。 

下面是我的Java实现代码: 
 

public String set_basestring() throws UnsupportedEncodingException { 
		    String bss; 
		    bss = oauth_request_method + "&" 
		    + URLEncoder.encode(requst_token_url, "utf-8") + "&"; 
		    String bsss = "oauth_callback=" 
		    + URLEncoder.encode(oauth_callback, "utf-8") 
		    + "&oauth_consumer_key=" + oauth_consumer_key + "&oauth_nonce=" 
		    + oauth_nonce + "&oauth_signature_method=" 
		    + oauth_signature_method + "&oauth_timestamp=" 
		    + oauth_timestamp + "&oauth_version=" + oauth_version; 
		    bsss = URLEncoder.encode(bsss, "utf-8"); 
		return bss + bsss; 
} 



有 了base string就可以签名生成oauth_signature这个参数,oauth_signature会在请求request_token的时候用到。签 名算法是HMAC-SHA1,签名的key就是最开始的consumer_secret后加一个&号,签名算法代码如下: 
 

public String hmacsha1(String data, String key) { 
		    byte[] byteHMAC = null; 
		    try { 
		    Mac mac = Mac.getInstance("HmacSHA1"); 
		    SecretKeySpec spec = new SecretKeySpec(key.getBytes(), "HmacSHA1"); 
		    mac.init(spec); 
		    byteHMAC = mac.doFinal(data.getBytes()); 
		    } catch (InvalidKeyException e) { 
		    e.printStackTrace(); 
		    } catch (NoSuchAlgorithmException ignore) { 
		    } 
		    String oauth = new BASE64Encoder().encode(byteHMAC); 
		    return oauth; 
	} 



里面用的的BASE64Encoder这个类可以Google一个。 

得到oauth_signature后就要开始向 requst_token_url 发送请求了,OAuth规范定义了三种传递OAuth参数方式: 

   1. httpheader中 
   2. url中 
   3. post form中 

国内各大微博的支持情况是:新浪Httpheader可用,网易Httpheader可用,腾讯只支持在url,搜狐由于没有appkey所以还没去尝试。 

如果使用Httpheader传递参数头名为“Authorization”,值为下面的格式,将值改为自己应用的。 

OAuth oauth_nonce="9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8", oauth_signature_method="HMAC-SHA1", 

oauth_timestamp="1272323047", oauth_consumer_key="GDdmIQH6jhtmLUypg82g", 

oauth_token="8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc", 

oauth_verifier="pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY", 

oauth_signature="PUw%2FdHA4fnlJYM6RhXk5IU%2F0fCc%3D", oauth_version="1.0" 



url和post form两种方式的参数名和参数值也即上面的,完全一样。 

请求发送成功后就会得到的响应如下: 
 

oauth_token=8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc&
oauth_token_secret=x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA&
oauth_callback_confirmed=true



可以看到响应里面已经包含oauth_token和oauth_token_secret了。

转载于:https://my.oschina.net/u/2433960/blog/896605

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于引用内容和,可以解释shiro oauth2的工作原理。shiro oauth2是一种基于OAuth2协议的认证和授权框架。在shiro oauth2中,客户端应用首先向认证服务器申请令牌,包括第三方用户信息和用户请求信息。认证服务器会根据客户端应用的信息以及存储的第三方应用信息,生成Oauth2Authentication并创建Oatuth2AccessToken令牌。然后,TokenStore将令牌存储到指定的存储器中。 在资源服务器端,客户端携带令牌发送请求到达Oauth2AuthenticationProcessFilter。这个过程中,tokenExtractor会从请求中获取Authentication信息。OAuth2AuthenticationManager会通过tokenService查询token对应的OAuth2Authentication。如果登陆成功,Authentication会被放到SpringSecurityConetxt中。 基于引用内容,shiro oauth2还需要在配置文件中配置客户端的信息。这些信息包括clientId、clientSecret、accessTokenUri、userAuthorizationUri和userInfoUri等。 总结起来,shiro oauth2是通过OAuth2协议实现的一种认证和授权框架,它包括申请令牌的流程和验证令牌的流程。在使用shiro oauth2时,需要配置客户端的信息,并且可以使用TokenStore将令牌存储到指定的存储器中。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [SpringSecurity、Shiro、Oauth2.0、Cas](https://blog.csdn.net/m0_37695902/article/details/117596437)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [【开发技术】2万字分析shiro、spring security两大安全框架,spring session,OAuth2 入门级教程](https://blog.csdn.net/a23452/article/details/125967279)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值