1,受權碼模式java
2,簡化模式web
3,密碼模式spring
4,客戶端模式apache
四種受權模式中最完成,最嚴密的受權。服務器
(1)用戶訪問客戶端,後者將前者導入認證服務器app
(2)用戶選擇是否給予客戶端受權dom
(3)假設用戶給予受權,認證服務器將用戶導向客戶端事先指定的「重定向URL」(redirection URL),同時附上一個受權碼。學習
(4)客戶端收到受權碼,附上早先的「重定向URL」,向認證服務器中申請令牌(assess token)和更新令牌(refresh token)ui
接入QQ登陸的前置條件以及開放平臺帳號申請this
引入官方SDK
--SDK參數配置
--SDK核心方法解讀
package com.flash.dataU.oauth.controller2; import com.flash.dataU.oauth.entity.User; import org.apache.oltu.oauth2.as.issuer.MD5Generator; import org.apache.oltu.oauth2.as.issuer.OAuthIssuer; import org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl; import org.apache.oltu.oauth2.as.request.OAuthAuthzRequest; import org.apache.oltu.oauth2.as.request.OAuthTokenRequest; import org.apache.oltu.oauth2.as.response.OAuthASResponse; import org.apache.oltu.oauth2.common.OAuth; import org.apache.oltu.oauth2.common.exception.OAuthProblemException; import org.apache.oltu.oauth2.common.exception.OAuthSystemException; import org.apache.oltu.oauth2.common.message.OAuthResponse; import org.apache.oltu.oauth2.common.message.types.ParameterStyle; import org.apache.oltu.oauth2.common.utils.OAuthUtils; import org.apache.oltu.oauth2.rs.request.OAuthAccessResourceRequest; import org.apache.oltu.oauth2.rs.response.OAuthRSResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.net.URI; import static org.apache.oltu.oauth2.common.OAuth.*; @RequestMapping("/oauthserver") @Controller public class AuthorizeController { private Model model; private HttpServletRequest request; //向客戶端返回受權許可碼 code @RequestMapping("/responseCode") public Object toShowUser(Model model, HttpServletRequest request){ this.model = model; this.request = request; System.out.println("----------服務端/responseCode--------------------------------------------------------------"); try { //構建OAuth受權請求 OAuthAuthzRequest oauthRequest =new OAuthAuthzRequest(request); /*oauthRequest.getClientId(); oauthRequest.getResponseType(); oauthRequest.getRedirectURI(); System.out.println(oauthRequest.getClientId()); System.out.println(oauthRequest.getResponseType()); System.out.println(oauthRequest.getRedirectURI());*/ if(oauthRequest.getClientId()!=null&&oauthRequest.getClientId()!="") { //設置受權碼 String authorizationCode ="authorizationCode"; //利用oauth受權請求設置responseType,目前僅支持CODE,另外還有TOKEN String responseType =oauthRequest.getParam(OAuth.OAUTH_RESPONSE_TYPE); //進行OAuth響應構建 OAuthASResponse.OAuthAuthorizationResponseBuilder builder = OAuthASResponse.authorizationResponse(request, HttpServletResponse.SC_FOUND); //設置受權碼 builder.setCode(authorizationCode); //獲得到客戶端重定向地址 String redirectURI =oauthRequest.getParam(OAUTH_REDIRECT_URI); //構建響應 final OAuthResponse response =builder.location(redirectURI).buildQueryMessage(); System.out.println("服務端/responseCode內,返回的回調路徑:"+response.getLocationUri()); System.out.println("----------服務端/responseCode--------------------------------------------------------------"); String responceUri =response.getLocationUri(); //根據OAuthResponse返回ResponseEntity響應 HttpHeaders headers =new HttpHeaders(); try { headers.setLocation(new URI(response.getLocationUri())); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return"redirect:"+responceUri; } } catch (Exception e) { e.printStackTrace(); } System.out.println("----------服務端/responseCode--------------------------------------------------------------"); return null; } //獲取客戶端的code碼,向客戶端返回access token @RequestMapping(value="/responseAccessToken",method = RequestMethod.POST) public HttpEntity token(HttpServletRequest request){ System.out.println("--------服務端/responseAccessToken-----------------------------------------------------------"); OAuthIssuer oauthIssuerImpl=null; OAuthResponse response=null; //構建OAuth請求 try { OAuthTokenRequest oauthRequest =new OAuthTokenRequest(request); String authCode =oauthRequest.getParam(OAuth.OAUTH_CODE); String clientSecret = oauthRequest.getClientSecret(); if(clientSecret!=null||clientSecret!=""){ //生成Access Token oauthIssuerImpl =new OAuthIssuerImpl(new MD5Generator()); final String accessToken =oauthIssuerImpl.accessToken(); System.out.println(accessToken); System.out.println("--oooo---"); //生成OAuth響應 response = OAuthASResponse .tokenResponse(HttpServletResponse.SC_OK) .setAccessToken(accessToken) .buildJSONMessage(); } System.out.println("--------服務端/responseAccessToken-----------------------------------------------------------"); //根據OAuthResponse生成ResponseEntity return new ResponseEntity(response.getBody(), HttpStatus.valueOf(response.getResponseStatus())); } catch (OAuthSystemException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (OAuthProblemException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("--------服務端/responseAccessToken-----------------------------------------------------------"); return null; } // 向客戶端返回請求資源(username)的controller方法 @RequestMapping("/userInfo") public HttpEntity userInfo(HttpServletRequest request)throws OAuthSystemException{ System.out.println("-----------服務端/userInfo-------------------------------------------------------------"); try { //獲取客戶端傳來的OAuth資源請求 OAuthAccessResourceRequest oauthRequest =new OAuthAccessResourceRequest(request, ParameterStyle.QUERY); //獲取Access Token String accessToken =oauthRequest.getAccessToken(); System.out.println("accessToken"); //驗證Access Token /*if (accessToken==null||accessToken=="") { // 若是不存在/過時了,返回未驗證錯誤,需從新驗證 OAuthResponse oauthResponse = OAuthRSResponse .errorResponse(HttpServletResponse.SC_UNAUTHORIZED) .setError(OAuthError.ResourceResponse.INVALID_TOKEN) .buildHeaderMessage(); HttpHeaders headers = new HttpHeaders(); headers.add(OAuth.HeaderType.WWW_AUTHENTICATE, oauthResponse.getHeader(OAuth.HeaderType.WWW_AUTHENTICATE)); return new ResponseEntity(headers, HttpStatus.UNAUTHORIZED); } */ //返回用戶名 User user=new User("小明"); String username = accessToken+"---"+Math.random()+"----"+user.getUsername(); System.out.println(username); System.out.println("服務端/userInfo::::::ppp"); System.out.println("-----------服務端/userInfo----------------------------------------------------------"); return new ResponseEntity(username, HttpStatus.OK); } catch (OAuthProblemException e) { // TODO Auto-generated catch block e.printStackTrace(); //檢查是否設置了錯誤碼 String errorCode =e.getError(); if (OAuthUtils.isEmpty(errorCode)) { OAuthResponse oauthResponse = OAuthRSResponse .errorResponse(HttpServletResponse.SC_UNAUTHORIZED) .buildHeaderMessage(); HttpHeaders headers =new HttpHeaders(); headers.add(OAuth.HeaderType.WWW_AUTHENTICATE, oauthResponse.getHeader(OAuth.HeaderType.WWW_AUTHENTICATE)); return new ResponseEntity(headers, HttpStatus.UNAUTHORIZED); } OAuthResponse oauthResponse = OAuthRSResponse .errorResponse(HttpServletResponse.SC_UNAUTHORIZED) .setError(e.getError()) .setErrorDescription(e.getDescription()) .setErrorUri(e.getUri()) .buildHeaderMessage(); HttpHeaders headers =new HttpHeaders(); headers.add(OAuth.HeaderType.WWW_AUTHENTICATE, oauthResponse.getHeader(OAuth.HeaderType.WWW_AUTHENTICATE)); System.out.println("-----------服務端/userInfo------------------------------------------------------------------------------"); return new ResponseEntity(HttpStatus.BAD_REQUEST); } } }
package com.flash.dataU.oauth.controller2; import org.apache.oltu.oauth2.client.OAuthClient; import org.apache.oltu.oauth2.client.URLConnectionClient; import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest; import org.apache.oltu.oauth2.client.request.OAuthClientRequest; import org.apache.oltu.oauth2.client.response.OAuthAccessTokenResponse; import org.apache.oltu.oauth2.client.response.OAuthResourceResponse; import org.apache.oltu.oauth2.common.OAuth; import org.apache.oltu.oauth2.common.exception.OAuthProblemException; import org.apache.oltu.oauth2.common.exception.OAuthSystemException; import org.apache.oltu.oauth2.common.message.types.GrantType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; //接受客戶端返回的code,提交申請access token的請求 @RequestMapping("/server") @Controller public class ServerController { String clientId = null; String clientSecret = null; String accessTokenUrl = null; String userInfoUrl = null; String redirectUrl = null; String response_type = null; String code= null; //提交申請code的請求 @RequestMapping("/requestServerCode") public String requestServerFirst() { clientId = "clientId"; clientSecret = "clientSecret"; accessTokenUrl = "responseCode"; redirectUrl = "http://localhost:8081/server/callbackCode"; response_type = "code"; OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient()); String requestUrl = null; try { //構建oauthd的請求。設置請求服務地址(accessTokenUrl)、clientId、response_type、redirectUrl OAuthClientRequest accessTokenRequest = OAuthClientRequest .authorizationLocation(accessTokenUrl) .setResponseType(response_type) .setClientId(clientId) .setRedirectURI(redirectUrl) .buildQueryMessage(); requestUrl = accessTokenRequest.getLocationUri(); System.out.println(requestUrl); } catch (Exception e) { e.printStackTrace(); } System.out.println(requestUrl); return "redirect:http://localhost:8080/oauthserver/" + requestUrl; } //接受客戶端返回的code,提交申請access token的請求 @RequestMapping("/callbackCode") public Object toLogin(HttpServletRequest request)throws OAuthProblemException{ System.out.println("-----------客戶端/callbackCode--------------------------------------------------------------------------------"); clientId = "clientId"; clientSecret = "clientSecret"; accessTokenUrl="http://localhost:8080/oauthserver/responseAccessToken"; userInfoUrl = "userInfoUrl"; redirectUrl = "http://localhost:8081/server/accessToken"; HttpServletRequest httpRequest = (HttpServletRequest)request; code = httpRequest.getParameter("code"); System.out.println(code); OAuthClient oAuthClient =new OAuthClient(new URLConnectionClient()); try { OAuthClientRequest accessTokenRequest = OAuthClientRequest .tokenLocation(accessTokenUrl) .setGrantType(GrantType.AUTHORIZATION_CODE) .setClientId(clientId) .setClientSecret(clientSecret) .setCode(code) .setRedirectURI(redirectUrl) .buildQueryMessage(); //去服務端請求access token,並返回響應 OAuthAccessTokenResponse oAuthResponse =oAuthClient.accessToken(accessTokenRequest, OAuth.HttpMethod.POST); //獲取服務端返回過來的access token String accessToken = oAuthResponse.getAccessToken(); //查看access token是否過時 Long expiresIn =oAuthResponse.getExpiresIn(); System.out.println("客戶端/callbackCode方法的token:::"+accessToken); System.out.println("-----------客戶端/callbackCode--------------------------------------------------------------------------------"); return"redirect:http://localhost:8081/server/accessToken?accessToken="+accessToken; } catch (OAuthSystemException e) { e.printStackTrace(); } return null; } //接受服務端傳回來的access token,由此token去請求服務端的資源(用戶信息等) @RequestMapping("/accessToken") public ModelAndView accessToken(String accessToken ) { System.out.println("---------客戶端/accessToken----------------------------------------------------------------------------------"); userInfoUrl = "http://localhost:8080/oauthserver/userInfo"; System.out.println("accessToken"); OAuthClient oAuthClient =new OAuthClient(new URLConnectionClient()); try { OAuthClientRequest userInfoRequest =new OAuthBearerClientRequest(userInfoUrl) .setAccessToken(accessToken).buildQueryMessage(); OAuthResourceResponse resourceResponse =oAuthClient.resource(userInfoRequest, OAuth.HttpMethod.GET, OAuthResourceResponse.class); String username = resourceResponse.getBody(); System.out.println(username); ModelAndView modelAndView =new ModelAndView("usernamePage"); modelAndView.addObject("username",username); System.out.println("---------客戶端/accessToken----------------------------------------------------------------------------------"); return modelAndView; } catch (Exception e) { e.printStackTrace(); } System.out.println("---------客戶端/accessToken----------------------------------------------------------------------------------"); return null; } }