亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

使用Java開(kāi)發(fā)實(shí)現(xiàn)OAuth安全認(rèn)證的應(yīng)用

 更新時(shí)間:2015年11月27日 15:08:29   作者:李三紅  
這篇文章主要介紹了使用Java開(kāi)發(fā)實(shí)現(xiàn)OAuth安全認(rèn)證的應(yīng)用的方法,OAuth安全認(rèn)證經(jīng)常出現(xiàn)于社交網(wǎng)絡(luò)API應(yīng)用的相關(guān)開(kāi)發(fā)中,需要的朋友可以參考下

OAuth 簡(jiǎn)介
OAuth 是由 Blaine Cook、Chris Messina、Larry Halff 及 David Recordon 共同發(fā)起的,目的在于為 API 訪(fǎng)問(wèn)授權(quán)提供一個(gè)安全、開(kāi)放的標(biāo)準(zhǔn)。
基于 OAuth 認(rèn)證授權(quán)具有以下特點(diǎn):
安全。OAuth 與別的授權(quán)方式不同之處在于:OAuth 的授權(quán)不會(huì)使消費(fèi)方(Consumer)觸及到用戶(hù)的帳號(hào)信息(如用戶(hù)名與密碼),也是是說(shuō),消費(fèi)方無(wú)需使用用戶(hù)的用戶(hù)名與密碼就可以申請(qǐng)獲得該用戶(hù)資源的授權(quán)。
開(kāi)放。任何消費(fèi)方都可以使用 OAuth 認(rèn)證服務(wù),任何服務(wù)提供方 (Service Provider) 都可以實(shí)現(xiàn)自身的 OAuth 認(rèn)證服務(wù)。
簡(jiǎn)單。不管是消費(fèi)方還是服務(wù)提供方,都很容易于理解與使用。
OAuth 的解決方案如下圖所示。
圖 1. OAuth Solution

20151127150505476.png (528×233)

如圖 1 所示 OAuth 解決方案中用戶(hù)、消費(fèi)方及其服務(wù)提供方之間的三角關(guān)系:當(dāng)用戶(hù)需要 Consumer 為其提供某種服務(wù)時(shí),該服務(wù)涉及到需要從服務(wù)提供方那里獲取該用戶(hù)的保護(hù)資源。OAuth 保證:只有在用戶(hù)顯式授權(quán)的情況下(步驟 4),消費(fèi)方才可以獲取該用戶(hù)的資源,并用來(lái)服務(wù)于該用戶(hù)。
從宏觀層次來(lái)看,OAuth 按以下方式工作:
消費(fèi)方與不同的服務(wù)提供方建立了關(guān)系。
消費(fèi)方共享一個(gè)密碼短語(yǔ)或者是公鑰給服務(wù)提供方,服務(wù)提供方使用該公鑰來(lái)確認(rèn)消費(fèi)方的身份。
消費(fèi)方根據(jù)服務(wù)提供方將用戶(hù)重定向到登錄頁(yè)面。
該用戶(hù)登錄后告訴服務(wù)提供方該消費(fèi)方訪(fǎng)問(wèn)他的保護(hù)資源是沒(méi)問(wèn)題的。
回頁(yè)首
OAuth 認(rèn)證授權(quán)流程
在了解 OAuth 認(rèn)證流程之前,我們先來(lái)了解一下 OAuth 協(xié)議的一些基本術(shù)語(yǔ)定義:

  • Consumer Key:消費(fèi)方對(duì)于服務(wù)提供方的身份唯一標(biāo)識(shí)。
  • Consumer Secret:用來(lái)確認(rèn)消費(fèi)方對(duì)于 Consumer Key 的擁有關(guān)系。
  • Request Token:獲得用戶(hù)授權(quán)的請(qǐng)求令牌,用于交換 Access Token。
  • Access Token:用于獲得用戶(hù)在服務(wù)提供方的受保護(hù)資源。
  • Token Secret:用來(lái)確認(rèn)消費(fèi)方對(duì)于令牌(Request Token 和 Access Token)的擁有關(guān)系。

圖 2. OAuth 授權(quán)流程(摘自 OAuth 規(guī)范)

20151127150611457.gif (572×429)

對(duì)于圖 2 具體每一執(zhí)行步驟,解釋如下:
消費(fèi)方向 OAuth 服務(wù)提供方請(qǐng)求未授權(quán)的 Request Token。
OAuth 服務(wù)提供方在驗(yàn)證了消費(fèi)方的合法請(qǐng)求后,向其頒發(fā)未經(jīng)用戶(hù)授權(quán)的 Request Token 及其相對(duì)應(yīng)的 Token Secret。
消費(fèi)方使用得到的 Request Token,通過(guò) URL 引導(dǎo)用戶(hù)到服務(wù)提供方那里,這一步應(yīng)該是瀏覽器的行為。接下來(lái),用戶(hù)可以通過(guò)輸入在服務(wù)提供方的用戶(hù)名 / 密碼信息,授權(quán)該請(qǐng)求。一旦授權(quán)成功,轉(zhuǎn)到下一步。
服務(wù)提供方通過(guò) URL 引導(dǎo)用戶(hù)重新回到消費(fèi)方那里,這一步也是瀏覽器的行為。
在獲得授權(quán)的 Request Token 后,消費(fèi)方使用授權(quán)的 Request Token 從服務(wù)提供方那里換取 Access Token。
OAuth 服務(wù)提供方同意消費(fèi)方的請(qǐng)求,并向其頒發(fā) Access Token 及其對(duì)應(yīng)的 Token Secret。
消費(fèi)方使用上一步返回的 Access Token 訪(fǎng)問(wèn)用戶(hù)授權(quán)的資源。
總的來(lái)講,在 OAuth 的技術(shù)體系里,服務(wù)提供方需要提供如下基本的功能:
第 1、實(shí)現(xiàn)三個(gè) Service endpoints,即:提供用于獲取未授權(quán)的 Request Token 服務(wù)地址,獲取用戶(hù)授權(quán)的 Request Token 服務(wù)地址,以及使用授權(quán)的 Request Token 換取 Access Token 的服務(wù)地址。
第 2、提供基于 Form 的用戶(hù)認(rèn)證,以便于用戶(hù)可以登錄服務(wù)提供方做出授權(quán)。
第 3、授權(quán)的管理,比如用戶(hù)可以在任何時(shí)候撤銷(xiāo)已經(jīng)做出的授權(quán)。
而對(duì)于消費(fèi)方而言,需要如下的基本功能:
第 1、從服務(wù)提供方獲取 Customer Key/Customer Secret。
第 2、提供與服務(wù)提供方之間基于 HTTP 的通信機(jī)制,以換取相關(guān)的令牌。

OAuth的授權(quán)流程

你所開(kāi)發(fā)的應(yīng)用需要流程如下:

  • 向應(yīng)用服務(wù)商(新浪、搜狐等微博)請(qǐng)求request_token。
  • 得到request_token后重定向用戶(hù)到服務(wù)商的授權(quán)頁(yè)面。
  • 如果用戶(hù)選擇授權(quán)你得應(yīng)用,用request_token向服務(wù)商請(qǐng)求換取access_token。
  • 得到access_token等信息訪(fǎng)問(wèn)受限資源。

而服務(wù)商相應(yīng)的響應(yīng)如下:

  • 創(chuàng)建request_token返回給應(yīng)用。
  • 詢(xún)問(wèn)用戶(hù)是否授權(quán)此應(yīng)用。如果用戶(hù)授權(quán)重定向用戶(hù)至應(yīng)用頁(yè)面。
  • 創(chuàng)建access_token并返回給應(yīng)用。
  • 響應(yīng)受限資源請(qǐng)求并返回相關(guān)信息。
  • 通俗點(diǎn)的說(shuō)法就是“你拿著你得身份證明(request_token)向服務(wù)商申請(qǐng)進(jìn)入用戶(hù)家的門(mén)鑰匙(access_token),服務(wù)商詢(xún)問(wèn)用戶(hù)同不同意,如果用戶(hù)同意服務(wù)商就給你進(jìn)入用戶(hù)家門(mén)的鑰匙(access_token),拿到鑰匙后你就可以進(jìn)到用戶(hù)家里”。

OAuth授權(quán)的Java實(shí)現(xiàn)

作為一個(gè)開(kāi)放協(xié)議目前有很多現(xiàn)成的Oauth庫(kù)可供開(kāi)發(fā)者使用,可以點(diǎn)擊這里下載。不過(guò)有精力有時(shí)間的話(huà)還是自己去實(shí)現(xiàn)一下OAuth授權(quán)的流程,可以很好的體會(huì)OAuth認(rèn)證協(xié)議的原理。以下就是我使用Java實(shí)現(xiàn)Oauth的具體步驟,代碼很簡(jiǎn)單,如果有畫(huà)蛇添足的地方還望高手一笑而過(guò)。

一、獲取Request_token

首先得準(zhǔn)備一下參數(shù)及其來(lái)源:

  • oauth_consumer_key —— 注冊(cè)應(yīng)用后由應(yīng)用服務(wù)商提供
  • consumer_secret —— 注冊(cè)應(yīng)用后由應(yīng)用服務(wù)商提供
  • oauth_callback —— 用戶(hù)授權(quán)后的返回地址
  • oauth_nonce —— 隨機(jī)字符串,須保證每次都不同
  • oauth_timestamp —— 時(shí)間戳
  • oauth_signature_method —— 簽名base string 的方法,目前支持 HMAC-SHA1
  • oauth_version —— Oauth協(xié)議版本

還需要下面三個(gè)請(qǐng)求地址(這些地址任何一個(gè)提供OAuth的服務(wù)商都會(huì)提供給你,看下API文檔就會(huì)找到):

  1. requst_token_url —— 上面第1步中的請(qǐng)求地址
  2. authorize_url —— 上面第2步的請(qǐng)求地址
  3. access_token_url —— 上面第3步的請(qǐng)求地址

至于如何注冊(cè)應(yīng)用,新浪微博、騰訊微博等等的網(wǎng)站上都有,這里就不再詳細(xì)說(shuō)明了。注冊(cè)成功后就會(huì)獲得oauth_consumer_key 和 consumer_secret 兩個(gè)參數(shù)。

oauth_callback 起的作用是當(dāng)用戶(hù)授權(quán)成功后服務(wù)商會(huì)把用戶(hù)重定向到這個(gè)網(wǎng)址。

oauth_nonce 是一個(gè)隨機(jī)字符串下面是我的生成代碼:

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 是請(qǐng)求的時(shí)間戳,我的代碼如下:

public String set_timestamp() {

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

需要說(shuō)明一下的是這里的時(shí)間戳為10位而不是13位,因此截取0-10位置。

其他參數(shù)直接指定就行了。

接下來(lái),有了這些參數(shù)就可以組裝base string了。準(zhǔn)備base string的目的就是為了得到 oauth_signature 這個(gè)參數(shù),這個(gè)參數(shù)向服務(wù)商發(fā)送請(qǐng)求的時(shí)候需要用到。

組裝的方法是用下面8部分

POST(也可以是GET,取決于你應(yīng)用服務(wù)商支持哪個(gè))。

  • Urlencode之后的requst_token_url 。
  • oauth_callback=Urlencode之后你的oauth_callback(Urlencode的參數(shù)為“utf-8”)。
  • oauth_consumer_key = 你的oauth_consumer_key
  • oauth_nonce = 你的oauth_nonce
  • oauth_signature_method = 你的 oauth_signature_method
  • oauth_timestamp = 你的oauth_timestamp
  • oauth_version = “1.0”——目前大多數(shù)OAuth都采用的是1.0或1.0a版本。

需要注意的是上面除了1跟2外其他參數(shù)的格數(shù)形如: abc=“abc” ,然后先將上面1和2部分用&號(hào)相連得到串A、3-8部分用&相連得到串B,下面需要將串B再進(jìn)行一次Urlencode得到串C,最后將A跟C以&號(hào)相連就得到了base string。這個(gè)過(guò)程中 oauth_callback 實(shí)質(zhì)上經(jīng)過(guò)了兩次 Urlencode ,組裝base string是非常容易出錯(cuò)的,一不小心丟一個(gè)引號(hào)或者格式稍有不對(duì)就會(huì)出錯(cuò)。

下面是我的Java實(shí)現(xiàn)代碼:

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這個(gè)參數(shù),oauth_signature會(huì)在請(qǐng)求request_token的時(shí)候用到。簽名算法是HMAC-SHA1,簽名的key就是最開(kāi)始的consumer_secret后加一個(gè)&號(hào),簽名算法代碼如下:

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這個(gè)類(lèi)可以Google一個(gè)。

得到oauth_signature后就要開(kāi)始向 requst_token_url 發(fā)送請(qǐng)求了,OAuth規(guī)范定義了三種傳遞OAuth參數(shù)方式:

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

國(guó)內(nèi)各大微博的支持情況是:新浪Httpheader可用,網(wǎng)易Httpheader可用,騰訊只支持在url,搜狐由于沒(méi)有appkey所以還沒(méi)去嘗試。

如果使用Httpheader傳遞參數(shù)頭名為“Authorization”,值為下面的格式,將值改為自己應(yīng)用的。

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兩種方式的參數(shù)名和參數(shù)值也即上面的,完全一樣。

請(qǐng)求發(fā)送成功后就會(huì)得到的響應(yīng)如下:

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

可以看到響應(yīng)里面已經(jīng)包含oauth_token和oauth_token_secret了,存貯之以備后面使用。

二、用戶(hù)認(rèn)證

拿到了oauth_token之后就需要用戶(hù)對(duì)此oauth_token授權(quán),也即對(duì)你的應(yīng)用授權(quán),具體做法就是發(fā)送oauth_token到服務(wù)商并請(qǐng)求用戶(hù)對(duì)此oauth_token授權(quán):實(shí)現(xiàn)方法為以oauth_token和oauth_callback為參數(shù)請(qǐng)求oauthorize_url,Servlet中的代碼如下:

resp.sendRedirect(oauthorize_url+"?oauth_token="+oauth_token+"&oauth_callback="+oauth_callback);

 這是用戶(hù)就被帶到了應(yīng)用授權(quán)頁(yè)面,并可以選擇是否對(duì)該應(yīng)用授權(quán)。如果用戶(hù)授權(quán)之后就會(huì)被帶到oauth_callback 地址。同時(shí)如果需要服務(wù)商會(huì)給oauth_callback返會(huì)一個(gè)名為oauth_verifier的參數(shù)(此參數(shù)用于無(wú)法跳轉(zhuǎn)的桌面應(yīng)用,不一定每個(gè)微博平臺(tái)都會(huì)返回),這時(shí)候我們的oauth_token已經(jīng)獲得用戶(hù)的授權(quán)了。

三、用oauth_token換取access_token

這一步跟第一步“獲取Request_token”基本相同,也是需要準(zhǔn)備 base string 對(duì)其簽名,然后發(fā)送請(qǐng)求,可以參考第一步的代碼實(shí)現(xiàn):但是相應(yīng)的參數(shù)有所不用,具體來(lái)講就是第一步組裝base string 時(shí)候8個(gè)部分中第二個(gè)部分中的url換為access_token_url 并去掉oauth_callback加上oauth_token(如果有oauth_verifier的話(huà)也需要一并加上),組裝好之后需要簽名以得到oauth_signature,本次簽名的方法跟上次一樣,但是key變?yōu)閏onsumer_secret和oauth_token_secret以&連接的串。

下來(lái)需要向access_token_url發(fā)送請(qǐng)求,請(qǐng)求參數(shù)包括base string 里的除了請(qǐng)求方法(POST或GET)和請(qǐng)求地址外的所有參數(shù)及其值和簽名后生成的oauth_signature。例子如下:

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""

請(qǐng)求成功會(huì)服務(wù)商就會(huì)返回oauth_token和oaut_token_secret,這里的oauth_token和oaut_token_secret就是真正訪(fǎng)問(wèn)資源要用的access_token。

還需要說(shuō)明的是以上過(guò)程只需要經(jīng)行一次,就是說(shuō)你拿到的access_token是不會(huì)過(guò)期的,除非用戶(hù)手動(dòng)將授權(quán)收回,因此作為access_token的oauth_token和oaut_token_secret要保存起來(lái),以后訪(fǎng)問(wèn)受限資源的時(shí)候可以直接使用。至于如何訪(fǎng)問(wèn)受限資源,等以后有時(shí)間了再補(bǔ)上。

相關(guān)文章

  • Spring Boot如何優(yōu)雅的使用多線(xiàn)程實(shí)例詳解

    Spring Boot如何優(yōu)雅的使用多線(xiàn)程實(shí)例詳解

    這篇文章主要給大家介紹了關(guān)于Spring Boot如何優(yōu)雅的使用多線(xiàn)程的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Java 同步鎖(synchronized)詳解及實(shí)例

    Java 同步鎖(synchronized)詳解及實(shí)例

    這篇文章主要介紹了Java 同步鎖(synchronized)詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • mybatis-plus雪花算法增強(qiáng)idworker的實(shí)現(xiàn)

    mybatis-plus雪花算法增強(qiáng)idworker的實(shí)現(xiàn)

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,進(jìn)一步增強(qiáng)實(shí)現(xiàn)生成分布式唯一ID,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • @RequestParam注解加與不加有什么區(qū)別

    @RequestParam注解加與不加有什么區(qū)別

    這篇文章主要介紹了@RequestParam注解加與不加有什么區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Java實(shí)現(xiàn)excel大數(shù)據(jù)量導(dǎo)入

    Java實(shí)現(xiàn)excel大數(shù)據(jù)量導(dǎo)入

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)excel大數(shù)據(jù)量導(dǎo)入,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • 迅速掌握J(rèn)ava容器中常用的ArrayList類(lèi)與Vector類(lèi)用法

    迅速掌握J(rèn)ava容器中常用的ArrayList類(lèi)與Vector類(lèi)用法

    這篇文章主要介紹了Java容器中常用的ArrayList類(lèi)與Vector類(lèi)用法,文中只對(duì)其最基本的功能給出了示例代碼,需要的朋友可以參考下
    2015-11-11
  • 手把手教你搭建第一個(gè)Spring Batch項(xiàng)目的步驟

    手把手教你搭建第一個(gè)Spring Batch項(xiàng)目的步驟

    這篇文章主要介紹了手把手教你搭建第一個(gè)Spring Batch項(xiàng)目的步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Java之SpringBoot-Thymeleaf詳情

    Java之SpringBoot-Thymeleaf詳情

    聊Thymeleaf,需要知道為什么到了SpringBoot中就不用JSP了?這跟SpringBoot打包方式有點(diǎn)關(guān)系,SpringBoot項(xiàng)目打包是jar包,下面文章小編就對(duì)此做一個(gè)詳細(xì)介紹,需要的朋友可以參考一下
    2021-09-09
  • Java使用Junit4.jar進(jìn)行單元測(cè)試的方法

    Java使用Junit4.jar進(jìn)行單元測(cè)試的方法

    今天通過(guò)本文給大家介紹Java使用Junit4.jar進(jìn)行單元測(cè)試的方法,本文通過(guò)圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2021-11-11
  • Java矢量隊(duì)列Vector使用示例

    Java矢量隊(duì)列Vector使用示例

    Vector類(lèi)實(shí)現(xiàn)了一個(gè)動(dòng)態(tài)數(shù)組。和ArrayList很相似,但是兩者是不同的Vector是同步訪(fǎng)問(wèn)的;Vector包含了許多傳統(tǒng)的方法,這些方法不屬于集合框架
    2023-01-01

最新評(píng)論