• 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;
    
        }
    }
    
     
  • 相关阅读:
    Spring 中的事务操作、注解、以及 XML 配置
    ..OBJLED.axf: Error: L6218E: Undefined symbol EXTI_Init (referred from exti.o). 错误修改
    ADC分辨率
    单片机ADC检测4-20mA电路,以及计算方法
    STM32速度---网页讲解
    转载电子发烧友网---STM32的IO口灌入电流和输出驱动电流
    精密电阻性能
    ..OBJCAN.axf: Error: L6411E: No compatible library exists with a definition of startup symbol __main.
    asp.net---jquery--ajax 实现滚动条滚动到底部分页显示
    柱状图dataLabels 文字格式 以及如何获取柱子的name(名称)属性
  • 原文地址:https://www.cnblogs.com/ltian123/p/10457729.html
Copyright © 2020-2023  润新知