OAuth2.0授权码模式学习

OAuth2.0授权码模式学习

四种授权方式

1,授权码模式

2,简化模式

3,密码模式

4,客户端模式

授权码模式

四种授权模式中最完成,最严密的授权。

(1)用户访问客户端,后者将前者导入认证服务器

(2)用户选择是否给予客户端授权

(3)假设用户给予授权,认证服务器将用户导向客户端事先指定的“重定向URL”(redirection URL),同时附上一个授权码。

(4)客户端收到授权码,附上早先的“重定向URL”,向认证服务器中申请令牌(assess token)和更新令牌(refresh token

接入QQ登录的前置条件以及开放平台账号申请

引入官方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;

    }
}

 
原文地址:https://www.cnblogs.com/ltian123/p/10457729.html