`
hzy0769
  • 浏览: 46081 次
  • 性别: Icon_minigender_1
  • 来自: 东莞
社区版块
存档分类
最新评论

OAuth2.0原理与简单实现演示

阅读更多

最近在学习Oauth,趁有时间把一些实践经验和理解记录下来,目前oauth最新的版本是2.0,相比1.0更简单更安全,在企业的业务系统中可用来实现SSO

 

1OAuth的简述

OAuthOpen Authorization,开放授权)是为用户资源的授权定义了一个安全、开放及简单的标准,第三方无需知道用户的账号及密码,就可获取到用户的授权信息,并且这是安全的。

 

2、名称定义

在详细讲解OAuth 2.0之前,需要了解几个专用名词。它们对读懂后面的讲解,至关重要。

1Third-party application:第三方应用程序,本文中又称"客户端"client)。

2Resource Owner:资源所有者,本文中又称"用户"user)。

3User Agent:用户代理,本文中就是指浏览器。

4Authorization server:认证服务器,即服务提供商专门用来处理认证的服务器。

5Resource server:资源服务器,即服务提供商存放用户生成的资源的服务器。它与认证服务器,可以是同一台服务器,也可以是不同的服务器。

 

知道了上面这些名词,就不难理解,OAuth的作用就是让"客户端"安全可控地获取"用户"的授权,与"服务商提供商"进行互动。

 

3OAuth的原理



 

 

上图是Oauth2.0其中的授权码模式(authorization code),因为这个模式比较常用,我主要学习这个为主,图中我分为5个步骤讲解

 

【A】    用户请求访问客户端,或者将前者导向至认证服务器,带上参数:client_idredirect_url

【B】    用户登录认证服务器,并选择是否授权给客户端访问

【C】    用户选择同意授权,认证服务器把用户导向至redirect_url,并且附上授权码(authorization code

【D】   客户端向认证服务器请求access token,需要带上参数:client_idclient_secretredirect_uri,和上一步获取的authorization code;认证服务器检查参数正确则返回access tonken表示授权成功

【E】    客户端使用access token请求资源服务器获取用户资源。

 

3、OAuth2.0简单实现(java

       国外有几个开源的java版的oauth实现,可以帮助较快的搭建一个oauth服务器,例如以下几个(可点击打开对应官网)

·         Java

·         Apache Oltu

·         Spring Security for OAuth

·         Apis Authorization Server (v2-31)

·         Restlet Framework (draft 30)

·         Apache CXF

 

 

Apache Oltu

目前我只是尝试了Oltu,比较轻量级,也不需要依赖其他服务,比较简单,但是官方的文档实在简陋,也是花了些时间才大概搞明白怎么用,下面就放出代码给大家演示下

 

服务端

获取授权码服务端代码示例

@RequestMapping("/authorize")

public ModelAndView authorize(HttpServletRequest request)

           throws OAuthSystemException, OAuthProblemException, URISyntaxException {

       ModelAndView mav = new ModelAndView();

       // 构建OAuth请求

       OAuthAuthzRequest oAuthzRequest = new OAuthAuthzRequest(request);

       // 获取OAuth客户端Id

       String clientId = oAuthzRequest.getClientId();

       // 校验客户端Id是否正确

       if (!checkClientId(clientId)) {

           mav.addObject("msg", "无效的客户ID");

           mav.setViewName("forward:/ljdp/oauth/authorizefail");

           returnmav;

       }

      

       //检查用户是否登陆和同意授权,如何还没登陆则跳转至登陆页面,然后进行授权提示

       //待开发。。。

      

      

       //生成授权码

       String authCode = null;

       String responseType = oAuthzRequest.getParam(OAuth.OAUTH_RESPONSE_TYPE);

       //ResponseType仅支持CODETOKEN

       if(responseType.equals(ResponseType.CODE.toString())){

           OAuthIssuerImpl oAuthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());

           authCode = oAuthIssuerImpl.authorizationCode();

           System.out.println("授权码="+authCode);

       }

      

       //获取客户端重定向地址

       String redirectURI = oAuthzRequest.getParam(OAuth.OAUTH_REDIRECT_URI);

       mav.setViewName("redirect:"+redirectURI+"?code="+authCode);

       returnmav;

}

 

 

获取Access Token服务端代码示例

@RequestMapping("/accesstoken")

public ResponseEntity<String> accessToken(HttpServletRequest request) throws OAuthSystemException, OAuthProblemException{

       //构建OAuth请求

       OAuthTokenRequest tokenRequest = new OAuthTokenRequest(request);

       //获取OAuth客户端Id

       String clientId = tokenRequest.getClientId();

       //校验客户端Id是否正确

       if(!checkClientId(clientId)){

           OAuthResponse oAuthResponse = OAuthASResponse

                  .errorResponse(HttpServletResponse.SC_BAD_REQUEST)

                  .setError(OAuthError.TokenResponse.INVALID_CLIENT)

                  .setErrorDescription("无效的客户端Id")

                  .buildJSONMessage();

           System.out.println(oAuthResponse.getBody());

           return new ResponseEntity<String>(oAuthResponse.getBody(), HttpStatus.valueOf(oAuthResponse.getResponseStatus()));

       }

      

       //检查客户端安全KEY是否正确

       if(!checkClientSecret(tokenRequest.getClientSecret())){

           OAuthResponse response = OAuthResponse.errorResponse(HttpServletResponse.SC_UNAUTHORIZED)

                     .setError(OAuthError.TokenResponse.UNAUTHORIZED_CLIENT)

                     .setErrorDescription("客户端安全KEY认证不通过")

                      .buildJSONMessage();

           return new ResponseEntity<String>(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));

       }

      

       //检查redirect_uri是否和认证的一致

       if(!checkRedirectUri(tokenRequest.getRedirectURI())){

           OAuthResponse response = OAuthResponse.errorResponse(HttpServletResponse.SC_UNAUTHORIZED)

                  .setError(OAuthError.TokenResponse.UNAUTHORIZED_CLIENT)

                  .setErrorDescription("客户端认证不通过")

                  .buildJSONMessage();

           return new ResponseEntity<String>(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));

       }

      

       //验证类型,有AUTHORIZATION_CODE/PASSWORD/REFRESH_TOKEN/CLIENT_CREDENTIALS

        if(tokenRequest.getParam(OAuth.OAUTH_GRANT_TYPE).equals(GrantType.AUTHORIZATION_CODE.toString())){

           String authCode = tokenRequest.getParam(OAuth.OAUTH_CODE);

           if(!checkAuthCode(authCode)){

              OAuthResponse response = OAuthResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST)

                     .setError(OAuthError.TokenResponse.INVALID_GRANT)

                       .setErrorDescription("错误的授权码") 

                       .buildJSONMessage();

              return new ResponseEntity<String>(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));

           }

           //生成访问令牌

           OAuthIssuerImpl authIssuerImpl = new OAuthIssuerImpl(new MD5Generator());

           String accessToken = authIssuerImpl.accessToken();

          

           //生成OAuth响应

           OAuthResponse response = OAuthASResponse

                  .tokenResponse(HttpServletResponse.SC_OK)

                  .setAccessToken(accessToken)

                  .setExpiresIn("1000")

                  .buildJSONMessage();

           System.out.println(response.getBody());

//         HttpHeaders headers = new HttpHeaders();

//         headers.setContentType(MediaType.APPLICATION_JSON);

           return new ResponseEntity<String>(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));

       }

      

       OAuthResponse response = OAuthResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST)

              .setError(OAuthError.TokenResponse.UNSUPPORTED_GRANT_TYPE)

                .setErrorDescription("不支持此授权类型") 

                .buildJSONMessage();

       return new ResponseEntity<String>(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));

}

 

Accesstoken获取授权用户资源服务器端代码示例

@RequestMapping("/resource")

@ResponseBody

public AuthUserInfo resource(HttpServletRequest request, HttpServletResponse response) {

// Make the OAuth Request out of this request and validate it

    // Specify where you expect OAuth access token (request header, body

    // or query string)

    OAuthAccessResourceRequest oauthRequest =

new OAuthAccessResourceRequest(request, ParameterStyle.QUERY);

 

    // Get the access token

    String accessToken = oauthRequest.getAccessToken();

   

    // ... validate access token

 

    //验证通过返回用户信息

    return new AuthUserInfo("test", "测试");

}

 

 

客户

获取accessToken代码示例

OAuthClientRequest request = OAuthClientRequest

       //获取accesstoken地址

       .tokenLocation("http://localhost:8080/ljdp/oauth/accesstoken")

       //授权方式

       .setGrantType(GrantType.AUTHORIZATION_CODE)

       //你的clientidsecret

       .setClientId("your-application-client-id")

       .setClientSecret("your-application-client-secret")

       //第一步重定向的uri

       .setRedirectURI("http://localhost:8080/ljdp/oauth/getcode")

       //第一步获取的认证码

       .setCode("****")

       .buildQueryMessage();

 

//create OAuth client that uses custom http client under the hood

OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());

 

//Custom response classes are an easy way to deal with oauth providers that introduce modifications to

//OAuth 2.0 specification

OAuthJSONAccessTokenResponse oAuthResponse = oAuthClient.accessToken(request, OAuthJSONAccessTokenResponse.class);

 

String accessToken = oAuthResponse.getAccessToken();

Long expiresIn = oAuthResponse.getExpiresIn();

 

accesstoken获取用户资源代码示例

OAuthClientRequest bearerClientRequest = new OAuthBearerClientRequest(

       "http://localhost:8080/ljdp/oauth/resource")

       .setAccessToken("********")

       .buildQueryMessage();

 

OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());

 

OAuthResourceResponse resourceResponse = oAuthClient.resource(

       bearerClientRequest, OAuth.HttpMethod.GET,

       OAuthResourceResponse.class);

 

System.out.println(resourceResponse.getBody());

System.out.println(resourceResponse.getResponseCode());

 

 

 

 

 

  • 大小: 21.6 KB
分享到:
评论

相关推荐

    springboot OAuth2.0-demo

    在"springboot OAuth2.0-demo"这个项目中,开发者已经实现了一个简单的OAuth2.0授权流程的示例。这个项目可能包含以下组件: - `AuthorizationServerConfig`:配置OAuth2.0授权服务器,定义令牌策略和范围。 - `...

    spring oauth2.0 例子

    这个"spring oauth2.0 例子"是一个在MyEclipse集成开发环境中创建的示例项目,用于演示如何在Spring框架中实现OAuth2.0认证和授权流程。 首先,OAuth2.0的核心概念包括客户端、资源所有者(用户)、授权服务器和...

    oauth2.0apache服务端源码

    通过深入研究 Apache Amber 的源码,开发者不仅可以理解 OAuth 2.0 协议的工作原理,还能学习到如何在实际项目中实现和定制 OAuth 2.0 服务端。这将有助于提升应用的安全性和用户体验,因为用户可以在不泄露用户名和...

    Node.js-使用node.js实现OAuth2.0的一个非常简单的演示

    Node.js 是一个基于 Chrome V8 引擎...通过研究和运行这个示例,你可以深入理解 OAuth2.0 的工作原理以及如何在 Node.js 中实现它。同时,也可以根据实际需求对示例进行扩展,比如添加更多的授权类型、令牌验证策略等。

    php-oauth2.0 demo

    在这个"php-oauth2.0 demo"项目中,我们将探讨如何在PHP环境中实现OAuth 2.0的基本功能。 1. **OAuth 2.0 架构** OAuth 2.0 主要有四个角色:资源所有者(Resource Owner)、客户端(Client)、认证服务器...

    NET Core 3.1 MVC演示Xero OAuth 2.0客户端身份验证和OAuth 2.0API

    .NET Core 3.1 MVC框架是Microsoft开发的一个高性能...通过深入研究这个项目,开发者可以学习到OAuth 2.0的工作原理,以及如何安全地在.NET Core环境中实现这一功能,从而扩展其应用的功能,与Xero的会计数据无缝交互。

    zifangsky-OAuth2.0Demo-master.zip

    学习这个项目,你可以理解OAuth2.0协议的工作原理,掌握服务端和客户端的实现细节,同时了解如何在实际项目中安全地使用OAuth2.0进行授权登录。这对于开发涉及用户授权的Web应用或者API服务至关重要。

    IOS sina 腾讯 微博 Oauth2.0 授权DEMO

    这个“IOS sina 腾讯 微博 OAuth2.0 授权DEMO”是一个演示如何在iOS应用中实现Sina Weibo和Tencent Weibo的OAuth2.0授权流程的实例。 首先,OAuth2.0的核心概念是授权码(Authorization Code)。当用户同意应用访问...

    auth2.0 安装包及资料学习(包含个版本的php_oauth.dll)

    这个“auth2.0 安装包及资料学习”压缩包提供了多种资源,帮助开发者理解和实践 OAuth 2.0 的实现,特别强调了与 PHP 和 MySQL 的集成。 1. **OAuth 2.0 概述** OAuth 2.0 是一个开放标准,允许用户让第三方应用在...

    OAuth2-Sample:OAuth2.0样本

    OAuth2-Sample是一个基于OAuth2.0协议的示例项目,主要展示了如何在Java环境中实现OAuth2.0授权框架。OAuth2.0是互联网上广泛...通过研究这个示例,你可以更好地掌握OAuth2.0的工作原理,以及如何在实际项目中实现它。

    《OAuth 2实战》代码.zip

    通过分析和学习这些代码,开发者可以更好地理解OAuth 2.0的工作原理,掌握如何在自己的应用中安全、高效地实施OAuth 2.0授权。这有助于提升应用程序的安全性,保护用户数据,并为用户提供无缝的第三方服务接入体验。

    AzureAD-NativeClient-Java:此示例演示了使用 Azure AD 保护的 JSP 中的 Web API。 消费者可以通过 OAuth 2.0 协议获取 JWT 访问令牌。 访问令牌被发送到 Web API 以对用户进行身份验证。 Web API 使用 java 来验证访问令牌

    消费者可以通过 OAuth 2.0 协议获取 JWT 访问令牌。 访问令牌被发送到 Web API 以对用户进行身份验证。 Web API 使用 java 来验证访问令牌。 有关协议在此方案和其他方案中的工作方式的详细信息,请参阅。 有关...

    OAuth2.in.Action.2017.3.pdf

    - **章节7**:深入讨论OAuth2.0的各种实现细节及可能存在的安全风险。 - **主题**:覆盖最佳实践、常见漏洞(如令牌泄露、重放攻击)及其防范措施。 - **案例分析**:通过具体案例讲解如何避免这些安全问题。 ...

    autest.rar

    1. **文档**:包含详细的开发指南或教程,解释OAuth2.0的工作原理和流程。这通常会包括客户端注册、获取client_id和client_secret,以及获取access_token的过程。 - **授权流程**:OAuth2.0分为几个关键步骤:资源...

    Python库 | oauth2sample-0.1.tar.gz

    `oauth2sample`是这样一个库,它专注于OAuth 2.0协议的实现,这是一种广泛使用的授权框架,用于安全地获取和使用用户的数据。`oauth2sample-0.1.tar.gz`是一个包含该库源代码的压缩包文件,通过解压可以获取到其内部...

    oAuthWithSpringJava:提供带有oAuth的spring的示例实现

    在这个"oAuthWithSpringJava"项目中,开发者可能已经创建了一个使用Spring Security和oAuth2.0的示例应用,以演示如何在Java应用程序中实现授权功能。Spring Security是Spring生态系统的一个模块,专门用于处理应用...

    基于Java的源码-API访问授权的开放标准 OAuth.zip

    - 文件"aaronpk-oauth.net-2e34467"可能是一个开源项目或者示例,用于演示如何在Java中实现OAuth 2.0的客户端或服务器端功能。 - 使用这个项目,开发者可以学习如何设置OAuth 2.0的授权流程,创建自定义授权端点,...

    platzi-autenticacion:OAuth认证课程

    在这个“platzi-autenticacion:OAuth认证课程”中,我们将深入探讨OAuth 2.0协议的工作原理,以及如何在实际的JavaScript项目中实现它。 OAuth 2.0 主要包含四个角色:资源所有者、资源服务器、客户端和授权服务器...

    resource-server:演示OAuth2

    "resource-server:演示OAuth2" 是一个基于Spring Security的项目,它展示了如何配置和实现OAuth 2.0 的资源服务器。 首先,OAuth 2.0 的核心概念包括客户端、用户、资源所有者和授权服务器。在这个项目中,...

    oauthDemo代码

    "oauthDemo代码"是一个示例项目,用于演示OAuth的实现过程。这个项目可能包含了以下关键知识点: 1. OAuth流程:OAuth通常涉及四个角色:资源所有者(用户)、客户端(第三方应用)、资源服务器(服务提供者)和...

Global site tag (gtag.js) - Google Analytics