「服务器」Oauth2验证框架之项目实现

「服务器」Oauth2验证框架之项目实现

在上一篇文章中(OAUTH2验证框架之入门教程)中,咱们已经讲到了Oauth2验证框架的工做原理。知道Oauth2验证框架工做的六个步骤:php

  • (A)用户打开客户端之后,客户端要求用户给予受权。git

  • (B)用户赞成给予客户端受权。github

  • (C)客户端使用上一步得到的受权,向认证服务器申请令牌。数据库

  • (D)认证服务器对客户端进行认证之后,确认无误,赞成发放令牌。编程

  • (E)客户端使用令牌,向资源服务器申请获取资源。api

  • (F)资源服务器确认令牌无误,赞成向客户端开放资源。数组

那么在具体的项目中,真正是怎么实现的呢?针对这个问题,本文下面将重点介绍。浏览器

Oauth2.0是一个很通用的验证框架,不少编程语言都对其进行了实现,包括Java、PHP、Python、NodeJS、Ruby、NET、Erlang、Go、C等。你们能够在以下页面,查看本身所使用语言的实现方案。安全

https://oauth.net/code/服务器

本文以PHP的实现方案为例,来说述Oauth2在项目中的工做流程。Java、Python、NodeJS、Ruby、NET、Erlang、Go、C等语言在项目中的工做流程,你们能够对照PHP的描述,自行融会贯通。

bshaffer/oauth2-server-php是一个库,能够实现符合标准的OAuth 2.0服务器。 使用它您的用户能够对应用程序客户端进行身份验证和受权,并保护您的API。

在具体讲述bshaffer/oauth2-server-phpr的具体实现以前,咱们先了解一下其中涉及到的几个重要概念:

  • 受权模式(Grant Types):授予类型容许您展现客户端接收令牌的多种方式。

  • 控制器(Controllers):OAuth服务器有3个端点,每一个端点均可以由控制器进行配置。每一个端点都在OAuth进程中执行不一样的功能。受权端点(Authorize Endpoint):用户在这里由客户端重定向来受权请求。令牌端点(Token Endpoint) :客户端向该端点发出请求以得到访问令牌。资源端点(Resource Endpoint(s)) :客户端请求资源,为认证令牌提供访问令牌。该库支持许多不一样的受权类型,包括官方OAuth规范定义的全部受权类型。

  • 存储对象(Storage Objects):该库使用存储接口来容许与多个数据层进行交互。PDO、Redis、Mongo、Cassandra、Doctrine Storage等存储类随库提供,但接口也容许您进行自定义。

  • 其余概念:Response Object、Scope、User IDs、JWT Access Tokens

受权模式(Grant Types)

bshaffer/oauth2-server-php库已经实现了OAuth 2.0受权框架RFC中定义的全部受权模式:

  1. 受权码模式(authorization code)

  2. 简化模式(implicit)

  3. 密码模式(resource owner password credentials)

  4. 客户端模式(client credentials)

控制器(Controllers)

大多数OAuth2 API将具备受权请求、令牌请求和资源请求的端点。 OAuth2 Server对象具备处理每一个请求的方法。下面的每一个控制器经过相同的名称对应于端点:

一、受权控制器

对于受权端点,要求用户使用受权码(受权码模式)或访问令牌(简化模式)对客户端进行认证和重定向。它有两个方法:

  • handleAuthorizeRequest

  • validateAuthorizeRequest

handleAuthorizeRequest()的做用是接收受权请求,返回受权响应。

validateAuthorizeRequest()的做用是接收受权请求,若是传入请求不是有效的受权请求,则返回false。 若是请求有效,则返回检索到的客户端详细信息和输入数组。 在向用户显示登陆或受权表单以前,应用程序应该调用它。

二、资源控制器

对于任何须要oauth2身份验证的资源请求(即API调用)。 控制器将验证传入的请求,而后容许应用程序返回受保护的资源。它有两个方法:

  • verifyResourceRequest

  • getAccessTokenData

verifyResourceRequest()的做用是接收访问资源的请求,根据请求判断访问令牌(access token)是否存在,无论请求是否合法,将返回一个布尔值(true or false)。

getAccessTokenData()的做用是讲接收的请求做为参数,若是该请求有被受权返回访问令牌(access token),不然返回null。

三、令牌控制器

对于使用配置的受权类型的令牌端点,将访问令牌(access token)返回给客户端。它有两个方法:

  • grantAccessToken

  • handleTokenRequest

grantAccessToken()的做用是接收获取访问令牌(access token)的请求,若是请求有效,将返回访问令牌(access token)。

handleTokenRequest()的做用是接收获取访问令牌(access token)的请求,返回适当响应的响应对象

存储对象

该库支持多个不一样存储引擎的适配器。 其中包括PDO(用于MySQL,SQLite,PostgreSQL等),MongoDB,Redis和Cassandra。这是经过多个PHP接口完成的,这个接口决定了如何存储不一样的对象。 接口容许对多个平台进行扩展和定制,使得编写本身的存储类容易。存储接口还能够轻松地将对象存储在多个数据存储系统中。

下载安装

一、要求

这个库须要PHP 5.3.9+。 可是,PHP 5.2.x-5.3.8也有一个稳定的发布和开发分支。

二、下载

这个库托管在GitHub上,若是不能使用composer工具,你们也能够在以下页面下载使用:

https://github.com/bshaffer/oauth2-server-php

三、安装

这个库遵循zend PSR-0标准。 有许多自动加载器能够自动加载这个库,可是若是你不使用它,你能够手动注册OAuth2 Autoloader,以下:

「服务器」Oauth2验证框架之项目实现

若是你可使用composer工具,能够直接使用以下命令,这个库将自动加载到你的项目中:

composer.phar require bshaffer/oauth2-server-php "^1.10"

开始使用

前面已经讲到,OAuth2 Server库已经实现了OAuth 2.0受权框架RFC中定义的全部受权模式,包括:受权码模式(authorization code)、简化模式(implicit)、密码模式(resource owner password credentials)、客户端模式(client credentials)。下面咱们来逐一说明。

注意:咱们这里假设咱们的受权服务器的域名为:

https://api.mysite.com

资源服务器的域名为:

https://myredirecturi.com

一、受权码模式(authorization code)

受权码模式是功能最完整、流程最严密的受权模式。它的特色就是经过客户端的后台服务器,与"服务提供商"的认证服务器进行互动。如图:

「服务器」Oauth2验证框架之项目实现

具体实现以下:

①、建立一个OAuth2 GrantType AuthorizationCode的实例并将其添加到您的服务器,以下:

「服务器」Oauth2验证框架之项目实现

②、当用户访问资源服务器时,咱们将其导引到受权服务器,以下:

https://api.mysite.com/authorize?response_type=code&client_id=TestClient&redirect_uri=https://myredirecturi.com/cb

③、受权服务器验证成功后,受权服务器将传递一个受权码到资源服务器,以下:

https://myredirecturi.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz

④、资源服务器利用接收到的受权码(code),调用受权服务器的接口,获取访问令牌(access token),以下:

「服务器」Oauth2验证框架之项目实现

若是调用成功,将返回以下数据:

「服务器」Oauth2验证框架之项目实现

二、简化模式(implicit)

简化模式(implicit grant type)不经过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了"受权码"这个步骤,所以得名。全部步骤在浏览器中完成,令牌对访问者是可见的,且客户端不须要认证。

「服务器」Oauth2验证框架之项目实现

具体实现以下:

①、在建立服务器时,只需配置服务器以容许简化模式。以下:

「服务器」Oauth2验证框架之项目实现

这容许受权控制器直接从请求返回访问令牌到服务器的受权端点。

②、当使用简化模式时,访问令牌将被受权控制器检索。 客户端经过在OAuth服务器的“受权”端点中设置查询字符串参数response_type = token来指定受权类型。

当用户访问资源服务器时,咱们将其导引到受权服务器,以下:

https://api.mysite.com/authorize?response_type=token&client_id=TestClient&redirect_uri=https://myredirecturi.com/cb

③、受权服务器验证成功后,受权服务器将传递一个访问令牌到资源服务器,以下:

https://myredirecturi.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&token_type=bearer&expires_in=3600

三、密码模式(resource owner password credentials)

密码模式中,用户向客户端提供本身的用户名和密码。客户端使用这些信息,向"服务商提供商"索要受权。

在这种模式中,用户必须把本身的密码给客户端,可是客户端不得储存密码。这一般用在用户对客户端高度信任的状况下,好比客户端是操做系统的一部分,或者由一个著名公司出品。而认证服务器只有在其余受权模式没法执行的状况下,才能考虑使用这种模式。

「服务器」Oauth2验证框架之项目实现

具体实现以下:

①、建立一个OAuth2 GrantType UserCredentials的实例并将其添加到您的服务器

「服务器」Oauth2验证框架之项目实现

注意:用户存储对于每一个应用程序都是高度自定义的,因此强烈建议您使用OAuth2 Storage UserCredentialsInterface来实现本身的存储。

②、直接发送用户凭证来获取访问令牌

「服务器」Oauth2验证框架之项目实现

若是您的客户端是公共的(默认状况下,当客户端没有与此相关的秘钥时是这样的),则能够省略请求中的client_secret值:

「服务器」Oauth2验证框架之项目实现

③、当响应成功时,将返回访问令牌(access token),以下:

「服务器」Oauth2验证框架之项目实现

四、客户端模式(client credentials)

客户端模式指客户端以本身的名义,而不是以用户的名义,向"服务提供商"进行认证。严格地说,客户端模式并不属于OAuth框架所要解决的问题。在这种模式中,用户直接向客户端注册,客户端以本身的名义要求"服务提供商"提供服务,其实不存在受权问题。

「服务器」Oauth2验证框架之项目实现

具体实现以下:

①、建立一个OAuth2 GrantType ClientCredentials的实例并将其添加到您的服务器

「服务器」Oauth2验证框架之项目实现

②、配置参数

客户端模式具备如下配置:

allow_credentials_in_request_body

除了受权HTTP头以外,是否在POST主体中查找凭证。默认值:true

「服务器」Oauth2验证框架之项目实现

③、调用接口获取访问令牌(access token)

「服务器」Oauth2验证框架之项目实现

调用成功时,返回以下数据:

「服务器」Oauth2验证框架之项目实现

补充拓展

经过上面的介绍,你们应该基本清楚了Oauth2的使用了。下面做为扩展内容,你们能够选择使用。

1、受权模式

除了上面介绍的四种模式以外,该库仍是实现了另外两种模式:刷新令牌模式(Refresh Token)和JWT Bearer模式。

一、刷新令牌(Refresh Token)

刷新令牌模式用于获取额外的访问令牌,以延长客户端对用户资源的受权。

具体实现以下:

①、建立一个OAuth2 GrantType RefreshToken的实例并将其添加到您的服务器

「服务器」Oauth2验证框架之项目实现

注意:

  • 只有在使用受权码模式或密码模式检索令牌时才提供刷新令牌。

  • 若是将实现OAuth2 Storage RefreshTokenInterface的存储提供给您的OAuth2 Server实例,则只会返回刷新令牌。

②、配置参数

刷新令牌模型具备如下配置:

always_issue_new_refresh_token

是否在成功的令牌请求时发出新的刷新令牌。默认:false

「服务器」Oauth2验证框架之项目实现

访问令牌返回类型具备如下配置:

refresh_token_lifetime

刷新令牌到期以前的时间。默认:1209600(14天)

「服务器」Oauth2验证框架之项目实现

可是,当使用服务器的配置数组建立服务器时,能够发送这两个配置选项:

「服务器」Oauth2验证框架之项目实现

③、刷新令牌

使用受权码模式或密码模式检索令牌:

「服务器」Oauth2验证框架之项目实现

若是执行成功,将返回以下数据:

「服务器」Oauth2验证框架之项目实现

刷新令牌能够用来生成一个等于或小于范围的新访问令牌:

「服务器」Oauth2验证框架之项目实现

若是执行成功,将返回以下数据:

「服务器」Oauth2验证框架之项目实现

若是服务器配置为同时获取令牌和刷新令牌,那么刷新令牌也会随着此响应返回:

「服务器」Oauth2验证框架之项目实现

二、JWT Bearer

JWT Bearer模式用于客户端但愿接收访问令牌而不传输敏感信息(如客户端密钥)的状况。 这也能够与受信任的客户端一块儿使用,以在没有用户受权的状况下访问用户资源。

具体实现以下:

①、建立OAuth2 GrantType JwtBearer的实例并将其添加到您的服务器

「服务器」Oauth2验证框架之项目实现

JWT请求须要使用公钥加密技术来签署JWT声明。 下面的代码片断提供了一个如何完成的例子。

「服务器」Oauth2验证框架之项目实现

注意:本示例使用此库中提供的OAuth2 Encryption Jwt类。 这对于JWT身份验证不是必需的,可是方便。

②、而后能够调用该函数来为请求生成负载。 编写脚原本生成jwt并请求令牌:

「服务器」Oauth2验证框架之项目实现

执行成功,将返回以下数据:

「服务器」Oauth2验证框架之项目实现

2、受权范围(scope)

在OAuth2应用程序中使用受权范围(scope)一般是正确许可的关键。 受权范围(scope)用于资源全部者限制对客户的受权。 如:Facebook用户向客户受权各类不一样功能的能力(“访问基本信息”,“贴在墙上”等)。

在这个库中,受权范围(scope)是经过实现OAuth2 Storage ScopeInterface来处理的。 可使用您本身的实现或利用现有的OAuth2 Storage Memory类来完成:

「服务器」Oauth2验证框架之项目实现

这是最简单的方法,但范围也能够动态配置:

「服务器」Oauth2验证框架之项目实现

此示例假定正在使用的类实现OAuth2 Storage ScopeInterface:

「服务器」Oauth2验证框架之项目实现

验证受权范围

在服务器类中配置受权范围(scope)将确保客户端请求的受权范围(scope)是有效的。 可是,要确保正确验证受权范围(scope),须要执行两个步骤。

首先,请求的受权范围(scope)必须在受权的状况下暴露给资源全部者。 在这个库中,这个被实现了100%。 用户界面或必须清楚受权的范围。

其次,资源请求自己必须指定访问它所需的受权范围(scope)

「服务器」Oauth2验证框架之项目实现

自定义受权范围

因为每一个应用程序的受权范围(scope)的实现可能会有很大差别,所以提供除OAuth2 Scope之外的其余类别可能会有所帮助。 在自定义类中实现OAuth2 ScopeInterface以彻底自定义。

state状态参数默认是受权重定向所必需的。 这至关于一个CSRF令牌,并为您的受权请求提供会话验证。 这是为了安全目的而默认启用的,可是当你配置你的服务器时你能够删除这个需求

「服务器」Oauth2验证框架之项目实现

使用多个范围

您能够经过在受权请求中提供以空格分隔(可是网址安全)的做用域列表来请求多个做用域。 它看起来像这样:

「服务器」Oauth2验证框架之项目实现

这将建立一个具备如下四个范围的受权代码:“onescope”,“twoscope”,“redscope”和“bluescope”,而后使用OAuth2 ScopeUtil类对这些范围进行验证,以确保它们存在。 若是您收到错误invalid_scope:请求不支持的做用域,这是由于您须要在服务器对象上设置可用的做用域,以下所示:

「服务器」Oauth2验证框架之项目实现

限制客户端访问范围

客户端可用的范围由客户端存储中的做用域字段和做用域存储中定义的可用做用域列表的组合来控制。当客户端有一个配置的范围列表时,客户端被限制为仅使用那些范围。 当没有配置范围时,客户端可使用的范围不受限制,它可使用受权服务器内可用的全部范围。

3、User IDs

将本地用户与访问令牌相关联

一旦你对一个用户进行了认证并发布了一个访问令牌(好比一个受权控制器),那么你可能想知道当访问令牌被使用时哪一个用户被应用。您能够经过使用handleAuthorizeRequest的可选user_id参数来执行此操做:

「服务器」Oauth2验证框架之项目实现

这将使用访问令牌将用户标识保存到数据库中。 当令牌被客户端使用时,您能够检索关联的ID:

「服务器」Oauth2验证框架之项目实现

参考地址:https://bshaffer.github.io/oauth2-server-php-docs

相关文章
相关标签/搜索