OAuth2.0受權碼模式學習

OAuth2.0受權碼模式學習

四種受權方式

1,受權碼模式java

2,簡化模式web

3,密碼模式spring

4,客戶端模式apache

 

受權碼模式

四種受權模式中最完成,最嚴密的受權。服務器

(1)用戶訪問客戶端,後者將前者導入認證服務器app

(2)用戶選擇是否給予客戶端受權dom

(3)假設用戶給予受權,認證服務器將用戶導向客戶端事先指定的「重定向URL」(redirection URL),同時附上一個受權碼。學習

(4)客戶端收到受權碼,附上早先的「重定向URL」,向認證服務器中申請令牌(assess token)和更新令牌(refresh tokenui

 

接入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;

    }
}

 
相關文章
相關標籤/搜索