1.搭建Oauth2.0協議的實現demo,最好要先學習一下Shiro的環境搭建。
在Shiro安全控制框架的基礎上實現oauth2.0 較為容易。
學習Oauth2.0 正式開始:
案例 我用的是:張開濤的oauth和shiro集成的栗子。
當然理解了Oauth2.0的原理之后,自己簡單的實現oauth協議原理,也是可以的。這個demo 我日后會補上。日后。。。
代碼地址。https://github.com/fangjiaxiaobai/oauth2.0/
授權碼方式:
oauth2.0的過程:
1.首先訪問目標地址(http://localhost:8086/),就跳轉到了oauth的server上,進行登錄(保證了第三方不會得到你的用戶名密碼)。
2. 輸入用戶名和密碼,並且授權和登錄。
3.如果登錄成功,server端就會生成授權碼,並重定向到客戶端,即之前提供的客戶端地址(),
4.客戶端的Oauth2AuthenticationFilter會收集此授權碼,並創建Oauth2Token提交給Subject進行客戶端登錄。
5.客戶端的Subject會委托Oauth2Realm進行身份驗證,此時Oauth2Realm會根據授權碼(auth code)換取access Token,
再根據accessToken 獲取受保護的用戶信息,然后進行客戶端登錄。
搭建過程:
使用spring+mybaits,
1.數據庫:
user,client。
oauth2_user:id,usename,password,salt
oauth2_client:id,client_name,client_id,client_secret
3.xml配置:
見代碼
4.代碼實現:
客戶端地址:127.0.0.1:8086
服務端地址:127.0.0.1:8080
1.在客戶端:用戶訪問登錄地址127.0.0.1:8086,就會跳轉到127.0.0.1:8080進行登錄和授權,
在客戶端的配置中如下代碼:
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="http://localhost:8080/server/authorize?client_id=0cb8d73d-6ee6-4b96-8815-267db2803901&response_type=code&redirect_uri=http://localhost:8086/oauth2-login";/>
<property name="successUrl" value="/" />
<property name="filters">
<util:map>
<entry key="oauth2Authc" value-ref="oAuth2AuthenticationFilter" />
</util:map>
</property>
<property name="filterChainDefinitions">
<value>
/ = anon
/oauth2Failure.jsp = anon
/oauth2-login = oauth2Authc
/logout = logout
/** = user
</value>
</property>
</bean>
|
標紅處代碼表示shiro會重定向到http://localhost:8080/server/authorize?client_id=0cb8d73d-6ee6-4b96-8815-267db2803901&response_type=code&redirect_uri=http://localhost:8086/oauth2-login"攜帶的數據有client_id,response_type,redirect_uri.
2.接下來就是server的登錄代碼了:見源碼中com.fxb.oauth2.controller.AuthorizeController
它主要做的就是:在server端登錄。
實現構建Oauth請求,然后判斷cliend_id是否存在(安全檢查一),不存在就返回錯誤,判斷用戶是否登錄(安全檢查二),沒登錄就跳轉到登錄界面。然后再生成授權碼(由於response_type=code)。構建Oauth響應,設置授權碼,根據攜帶的redirect_uri,重定向會client端,即http://localhost:8086/oauth2-login?code=xxxxxxxxxxxxxx
3.跳回client后: 如上面的標綠色的代碼,會通過oAuth2AuthenticationFilter身份驗證。又進行了下面的配置:
<!--Oauth2身份驗證過濾器-->
<bean id="oAuth2AuthenticationFilter" class="com.fxb.client.filter.OAuth2AuthenticationFilter">
<property name="authCodeParam" value="code"/>
<property name="failureUrl" value="/oauth2Failure.jsp"/>
</bean>
|
java實現還是看com.fxb.client.filter.OAuth2AuthenticationFilter這個類吧。這個時候,client會攜帶着code跳回server端請求token。它是怎么知道訪問server端地址的呢?當然是shiro配置了(標紅處Z):
<bean id="oAuth2Realm" class="com.fxb.client.realm.OAuth2Realm">
<property name="cachingEnabled" value="true" />
<property name="authenticationCachingEnabled" value="true" />
<property name="authenticationCacheName" value="authenticationCache" />
<property name="authorizationCacheName" value="authorizationCache" />
<property name="clientId" value="0cb8d73d-6ee6-4b96-8815-267db2803901" />
<property name="clientSecret" value="9880a122-efde-40ef-ae54-ca336bd6f95f" />
<property name="accessTokenUrl" value="http://localhost:8080/accessToken";/>
<property name="userInfoUrl" value="http://localhost:8080/userInfo";/>
<property name="redirectUrl" value="http://localhost:8086/login"; />
</bean>
|
詳細看com.fxb.client.realm.OAuth2Realm類、
java代碼是Server端的com.fxb.oauth2.controller.AccessTokenController類。根據code生成token並返回client、
具體的思路是:構建Oauth請求,檢查客戶端Id是否存在。檢查客戶端安全key是否存在,檢查驗證類型,檢查code是否正確。生成Access Token。生成OAuth響應,之后返回到client。
而在Client的Oauth2Realm中,其獲取了accessToken 還會對服務端進行資源的請求。對應上述xml配置中userInfoUrl。此處演示的是資源為用戶信息。
在Server中的實現代碼在com.fxb.oauth2.controller.AccessTokenController.userInfo.
構建Oauth資源請求,驗證accessToken,將資源返回。返回到client的OAuth2Realm的認證中,至此Oauth2協議演示完成。
當然Oauth2還有其他的響應類型,比如簡易類型,密碼模式,客戶端模式。

