zoukankan      html  css  js  c++  java
  • oauth简单使用

    一、oauth原理参考

      理解OAuth 2.0

    二、本例中采用授权码模式

      

      大致流程

      (A)用户访问客户端,后者将前者导向认证服务器。
      (B)用户选择是否给予客户端授权。
      (C)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。
      (D)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
      (E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。

      参数含义

      response_type:表示授权类型,必选项,此处的值固定为"code"
      client_id:表示客户端的ID,必选项
      redirect_uri:表示重定向URI,可选项
      scope:表示申请的权限范围,可选项,本例中无
      state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值,本例中无

    三、项目中依赖oauth相关jar

    <!-- oauth -->
    <dependency>
        <groupId>org.apache.oltu.oauth2</groupId>
        <artifactId>org.apache.oltu.oauth2.resourceserver</artifactId>
        <version>${oauth2-version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.oltu.oauth2</groupId>
        <artifactId>org.apache.oltu.oauth2.authzserver</artifactId>
        <version>${oauth2-version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.oltu.oauth2</groupId>
        <artifactId>org.apache.oltu.oauth2.client</artifactId>
        <version>${oauth2-version}</version>
    </dependency>

    四、获取授权码

    /**
     * 获取授权码-服务端
     *
     * @param request
     * @return
     * @throws OAuthProblemException
     * @throws OAuthSystemException
     */
    @RequestMapping(value = "/authorize", method = RequestMethod.GET)
    @ResponseBody
    public Object authorize(HttpServletRequest request) throws URISyntaxException, OAuthProblemException, OAuthSystemException {
        try {
            // 构建OAuth授权请求
            OAuthAuthzRequest oauthRequest = new OAuthAuthzRequest(request);
    
            // 1.获取OAuth客户端id
            String clientId = oauthRequest.getClientId();
            // 校验客户端id是否正确
            LightUserResult lightUserResult = userApi.queryUserByClientId(clientId);
            if (null == lightUserResult) {
                OAuthResponse response =
                        OAuthASResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
                                .setError(OAuthError.TokenResponse.INVALID_CLIENT)
                                .setErrorDescription("无效的客户端ID")
                                .buildJSONMessage();
                return new ResponseEntity(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));
            }
    
            // 2.生成授权码
            String authCode = null;
            String responseType = oauthRequest.getParam(OAuth.OAUTH_RESPONSE_TYPE);
            // ResponseType仅支持CODE和TOKEN
            if (responseType.equals(ResponseType.CODE.toString())) {
                OAuthIssuerImpl oAuthIssuer = new OAuthIssuerImpl(new MD5Generator());
                authCode = oAuthIssuer.authorizationCode();
                // 存入缓存中authCode-username
                RedisUtil.getRedis().set(authCode, lightUserResult.getUserName());
            }
            return new ResponseEntity(authCode, HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity("内部错误", HttpStatus.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
        }
    }

    五、根据授权码获取token

    /**
     * 获取访问令牌
     *
     * @param request
     * @return
     * @throws OAuthProblemException
     * @throws OAuthSystemException
     */
    @RequestMapping(value = "accessToken", method = RequestMethod.POST)
    @ResponseBody
    public Object accessToken(HttpServletRequest request) throws OAuthProblemException, OAuthSystemException {
        try {
            // 构建OAuth请求
            OAuthTokenRequest tokenRequest = new OAuthTokenRequest(request);
    
            // 1.获取OAuth客户端id
            String clientId = tokenRequest.getClientId();
            // 校验客户端id是否正确
            LightUserResult lightUserResult = userApi.queryUserByClientId(clientId);
            if (null == lightUserResult) {
                OAuthResponse oAuthResponse = OAuthResponse
                        .errorResponse(HttpServletResponse.SC_BAD_REQUEST)
                        .setError(OAuthError.TokenResponse.INVALID_CLIENT)
                        .setErrorDescription("无效的客户端ID")
                        .buildJSONMessage();
                return new ResponseEntity(oAuthResponse.getBody(), HttpStatus.valueOf(oAuthResponse.getResponseStatus()));
            }
    
            // 2.检查客户端安全key是否正确
            if (!lightUserResult.getClientSecret().equals(tokenRequest.getClientSecret())) {
                OAuthResponse oAuthResponse = OAuthResponse
                        .errorResponse(HttpServletResponse.SC_UNAUTHORIZED)
                        .setError(OAuthError.TokenResponse.UNAUTHORIZED_CLIENT)
                        .setErrorDescription("客户端安全key认证不通过")
                        .buildJSONMessage();
                return new ResponseEntity<>(oAuthResponse.getBody(), HttpStatus.valueOf(oAuthResponse.getResponseStatus()));
            }
    
            // 3.检查授权码是否正确
            String authCode = tokenRequest.getParam(OAuth.OAUTH_CODE);
            // 检查验证类型,此处只检查AUTHORIZATION_CODE类型,其他的还有password或REFRESH_TOKEN
            if (!tokenRequest.getParam(OAuth.OAUTH_GRANT_TYPE).equals(GrantType.AUTHORIZATION_CODE.toString())) {
                if (null == RedisUtil.getRedis().get(authCode)) {
                    OAuthResponse response = OAuthASResponse
                            .errorResponse(HttpServletResponse.SC_BAD_REQUEST)
                            .setError(OAuthError.TokenResponse.INVALID_GRANT)
                            .setErrorDescription("授权码错误")
                            .buildJSONMessage();
                    return new ResponseEntity(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));
    
                }
            }
    
            // 4.生成访问令牌Access Token
            OAuthIssuer oAuthIssuer = new OAuthIssuerImpl(new MD5Generator());
            final String accessToken = oAuthIssuer.accessToken();
            // 将访问令牌加入缓存:accessToken-username
            RedisUtil.getRedis().set(accessToken, lightUserResult.getUserName());
    
            // 5.生成OAuth响应
            OAuthResponse response = OAuthASResponse
                    .tokenResponse(HttpServletResponse.SC_OK)
                    .setAccessToken(accessToken)
                    .setExpiresIn(expiresIn)
                    .buildJSONMessage();
    
            return new ResponseEntity(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity("内部错误", HttpStatus.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
        }
    
    }

     六、简单测试

    @RequestMapping("authority")
    @ResponseBody
    public JSONObject authority() throws OAuthSystemException, OAuthProblemException {
        JSONObject result = new JSONObject();
        OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
        OAuthClientRequest codeTokenRequest = OAuthClientRequest
                .authorizationLocation("http://127.0.0.1:8080/auth-web/oauth/authorize")
                .setResponseType(ResponseType.CODE.toString())
                .setClientId("c1ebe466-1cdc-4bd3-ab69-77c3561b9dee")
                .buildQueryMessage();
        //获取 code
        OAuthResourceResponse codeResponse = oAuthClient.resource(
                codeTokenRequest, OAuth.HttpMethod.GET, OAuthResourceResponse.class);
        if(codeResponse.getResponseCode() != HttpServletResponse.SC_OK) {
            result.put("code", codeResponse.getResponseCode());
            result.put("msg", codeResponse.getBody());
        } else {
            String authCode = codeResponse.getBody();
            OAuthClientRequest accessTokenRequest = OAuthClientRequest
                    .tokenLocation("http://127.0.0.1:8080/auth-web/oauth/accessToken")
                    .setGrantType(GrantType.AUTHORIZATION_CODE)
                    .setClientId("c1ebe466-1cdc-4bd3-ab69-77c3561b9dee").setClientSecret("d8346ea2-6017-43ed-ad68-19c0f971738b")
                    .setCode(authCode).setRedirectURI("http://127.0.0.1:8080/auth-web/")
                    .buildQueryMessage();
            //获取access token
            OAuthAccessTokenResponse tokenResponse =
                    oAuthClient.accessToken(accessTokenRequest, OAuth.HttpMethod.POST);
            if(tokenResponse.getResponseCode() != HttpServletResponse.SC_OK) {
                result.put("code", tokenResponse.getResponseCode());
                result.put("msg", tokenResponse.getBody());
                return result;
            } else {
                //验证token
                OAuthClientRequest validateRequest =
                        new OAuthBearerClientRequest("http://127.0.0.1:8080/auth-web/oauth/validate")
                                .setAccessToken(tokenResponse.getAccessToken()).buildQueryMessage();
                OAuthResourceResponse validateResponse = oAuthClient.resource(
                        validateRequest, OAuth.HttpMethod.GET, OAuthResourceResponse.class);
                if(validateResponse.getResponseCode() != HttpServletResponse.SC_OK) {
                    result.put("code", validateResponse.getResponseCode());
                    result.put("msg", validateResponse.getBody());
                } else {
                    JSONObject body = JSON.parseObject(validateResponse.getBody());
                    result.put("code", body.getString("code"));
                    result.put("msg", body.getString("msg"));
                }
            }
        }
        return result;
    }
    public static ResponseEntity oauthValidate(HttpServletRequest request) throws OAuthProblemException, OAuthSystemException {
    
        // 构建OAuth资源请求
        OAuthAccessResourceRequest resourceRequest = new OAuthAccessResourceRequest(request, ParameterStyle.QUERY);
        // 获取访问令牌access Token
        String accessToken = resourceRequest.getAccessToken();
        // 验证访问令牌
        if (null == RedisUtil.getRedis().get(accessToken)) {
            // 如果不存在或过期了,返回未验证错误,需重新验证
            OAuthResponse response = OAuthRSResponse
                    .errorResponse(HttpServletResponse.SC_UNAUTHORIZED)
                    .setError(OAuthError.ResourceResponse.INVALID_TOKEN)
                    .setErrorDescription("访问令牌不存在或已过期,请重新验证")
                    .buildJSONMessage();
            return new ResponseEntity(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));
        }
        return new ResponseEntity("验证成功", HttpStatus.valueOf(HttpServletResponse.SC_OK));
    }

    七、项目地址

      oauth认证demo下载

  • 相关阅读:
    selenium+python(模块化驱动测试)
    selenium+Python(处理html5的视频播放)
    selenium+Python(文件下载)
    selenium+Python(文件上传)
    selenium+Python(alert 、confirm 、prompt 的处理)
    selenium+Python(表单、多窗口切换)
    Cookie跳转登录验证码
    几种典型的软件自动化测试框架
    Python开发利器之UliPad
    selenium+python(数据驱动测试)
  • 原文地址:https://www.cnblogs.com/hujunzheng/p/7126766.html
Copyright © 2011-2022 走看看