全部产品

OAuth2.0模板使用指南

概述

IDaaS支持基于标准OAuth2协议,实现从IDaaS到业务应用的单点登录功能。

本文主要包含以下内容:

  • 时序说明 - OAuth2协议的简单时序图说明,以及交互参数

  • 主要流程 - OAuth2.0模板使用主要流程

  • 操作步骤 - 从新建开始配置一个OAuth2应用,以及如何在客户端中开发,包含具体API请求、响应和错误提示

  • FAQ - 常见问题以及其对策

时序说明

场景:SP发起单点登录时序

OAuth 2.0的草案是在2010年5月初在IETF发布的。OAuth 2.0是OAuth协议的下一版本,但不向后兼容OAuth 1.0。 OAuth 2.0关注客户端开发者的简易性,同时为Web应用,PC应用和手机,和IOT设备提供专门的认证流程。规范在IETF OAuth工作组的主导下,OAuth标准于2010年末完成。

OAuth2是一个授权协议, 主要用来作为API的保护, 我们称之为STS(安全令牌服务, Security Token Service)。 但是在某些情况下, 也可以被用来实现WEB SSO单点登录。一般的流程是用户把发起页面的URL和state参数关联上, 并保存在SP本地,用户登录后, 可以获取一个Code, 利用Code拿到AT(Access Token) 后, 可以利用这个AT获取用户信息userinfo, 进而从state 中, 获取到对应的原始URL,并跳转到这个URL, 从而实现登录到一个业务应用SP的效果。 本文档详细描述了这个SSO过程。

详细时序图(以授权码模式为例):

oauth2_flow

说明:

第[5]步参数要求

  • response_type:必选、值固定为"code"

  • client_id:必选、第三方应用的标识ID

  • state:推荐、Client提供的一个字符串,服务器会原样返回给Client,它既能防止CSRF、XSRF, 同时也可以用来对应SP初始发起的状态。

  • redirect_uri:必选、授权成功后的重定向地址

  • scope:可选、表示授权范围

  • prompt:可选

第[6]步校验内容

  • a.client_id是否合法

  • b.prompt:

    1. 若应用请求IDP时不带prompt参数,则逻辑为用户没登录就跳转到登录页

    2. 若应用请求IDP时带参数prompt=none,则默认用户已经登录验证,如果IDP发现用户未登录验证,则直接报interaction_required错误

    3. 若应用请求IDP时带参数prompt=login,则不论用户是否已经登录认证,都重新走一次认证流程

第[11]步返回参数

  • 跳转到[5]中指定redirect_uri,并返回:code:授权码 state:步骤[5]中客户端提供的state参数原样返回

第[13]步校验参数

  • state是否和自己发送出的一致

第[14]步请求参数

  • grant_type:必选、固定值"authorization_code"

  • code:必选、Authorization Response中响应的code

  • redirect_uri:必选、必须和Authorization Request中提供的redirect_uri相同

  • client_id:必选、必须和AuthorizationRequest中提供的client_id相同

  • client secret: client的secret,用于授权服务器校验client的合法身份

第[15]步校验参数

  • a.client_id、client_secret(若有)是否合法

  • b.redirect_uri是否和步骤[A]中的redirect_uri一致

  • c.code是否合法:

  • >是否过期

  • >是否被重复使用,若是就视为一次攻击,加入日志审计,并将之前为code生成的access token撤销

  • >比较code和应用的client id是否匹配

  • d.server必须在http server头部返回:Cache-Control:no-store and Pragma:no-cache,确保client不会被缓存

第[16]步返回参数

  • access_token:访问令牌

  • refresh_token:刷新令牌

  • expires in:过期时间

第[19]步完成单点登录

  • 完成了这一步,就获取到access_token和用户信息,可以展示当前登录用户信息,基于此保存的session会话,用户可以不用再频繁登录,实现点击图标即可跳转应用的过程

主要流程

Step1 创建OAuth2应用,基于OAuth2模板快速创建应用

Step2 授权OAuth2应用,对OAuth2应用授予访问权限

Step3 获取应用信息,基于配置应用信息主要为获取授权码Code

Step4 访问授权URL获取Code,通过相关应用配置,跳转应用地址

Step5 完成应用侧的开发/配置,就可以实现业务应用单点登录功能

操作步骤

Step1 创建OAuth2应用:

1、首先以IT管理员账号登录云盾IDaaS管理平台。具体操作请参考 IT管理员指南-登录 。

2、点击左侧导航栏应用>添加应用选择右侧OAuth。

2

3、选择OAuth2应用模板点击添加应用

5

4、Redirect URI : 填写需要使用OAuth2单点登录应用的URL

GrantType : 选择authorization_code

其他参数默认即可,有需要也可按照实际需要修改

Step2 OAuth2应用授权

应用授权:选择应用(搜索应用)、选择组织机构(搜索组织机构)、勾选授权即可

6

Step3 获取应用信息

点击左侧导航栏应用>应用列表查看 OAuth2 应用详情, 获得Client Id、Client Secret、Authorize URL.

78

Step4 登录获取Code

参考SP发起单点登录时序:认证成功生成code

应用通过一个IDP登录按钮等或其它方式, 触发浏览器打开 AuthorizeURL,使用授权的账户进行登录,登录成功后跳转到回调地址redirect_uri,并把Code参数一同转发过去。

9

Step5 完成应用侧的开发/配置

5.1、利用Code从服务器获取AT(Access Token)

参考SP发起单点登录时序:请求access_token

无论是JAVA, PHP, 还是.NET应用, 接下来要做的是,应用通过URL参数拿到这个Code 后, 紧接着构建一个应用Token 换AT(Access Token)的过程。

Request URI: https://{IDaaS_server}/oauth/token?grant_type=authorization_code&code={code}&client_id={client_id}&client_secret={client_secret}&redirect_uri={redirect_uri}

IDaaS_server:为实例用户登录页地址(推荐使用)、实例开放接口域名也可以使用

10注: OAuth支持多种grant_type 这里使用的是authorization_code模式。

接口说明:获得 access_token

请求方式:POST

请求参数

参数

类型

是否必选

示例值

描述

code

String

vuQ3n6

用户登录成功后回调传递的code值

client_id

String

oauth2 client_id

OAuth2 client_id

client_secret

String

oauth2 client_secret

OAuth2 client_secret

redirect_uri

String

http://example.com

重定向 url

    • 返回参数示例:

{
    "access_token": "b833ca9f-82f7-485e-a18a-4e3e2422f808",
    "token_type": "bearer",
    "refresh_token": "073283f5-6263-4130-86bd-64cbafbaae94",
    "expires_in": 7199,
    "scope": "read"
}

参数

类型

示例值

描述

access_token

String

333ab704-abc0-48b3-8af0-496eedd15383

Access Token

token_type

String

bearer

Token 类型

refresh_token

String

073283f5-6263-4130-86bd-64cbafbaae94

刷新token

expires_in

String

7199

Access Token 过期时间

scope

String

read

申请的权限范围

    • 错误码说明

    HttpCode

    错误码

    错误信息

    描述

    400

    invalid_grant

    Invalid authorization code: "code".

    无效的授权码

    400

    invalid_grant

    Redirect URI mismatch.

    重定向 URI 不匹配

    401

    Unauthorized

    Unauthorized

    未授权的访问

    403

    Forbidden

    Forbidden

    无权限访问

    404

    ResourceNotFound

    ResourceNotFound

    访问的资源不存在

    415

    UnsupportedMediaType

    UnsupportedMediaType

    不支持的媒体类型

    500

    InternalError

    The request processing has failed due to some unknown error, exception or failure.

    发生未知错误

    {code}需要替换为授权应答Authorization Response中提取到的 code 参数的值。

    注意 Code 的值只能用一次

    {client_id}、{client_secret}需要替换为认证成功生成code中获得的值

    {redirect_uri} 需要替换为302重定向到IDP进行认证授权添加 OAuth2 应用时输入的跳转值

    以上完成后你将获得AT(Access Token),此AT将作为你访问的凭证。

    5.2、获取用户信息userinfo

    参考SP发起单点登录时序:应用请求userinfo(携带access_token)

    在获取到AT(Access Token)后,应用可以接着向IDaaS平台发送进一步的请求, 以获取到用户信息,实现登录到一个业务应用SP的效果。

    发送GET请求到https://{IDaaS_server}/api/bff/v1.2/oauth2/userinfo?access_token={access_token}

    {access_token}替换为前一步获取到的AT(Access Token)

    从返回参数即可获取userinfo信息

    Request URI: https://{IDaaS_server}/api/bff/v1.2/oauth2/userinfo

      • 接口说明:获取用户详细信息

      • 请求方式:GET

      • 请求参数

      参数

      类型

      是否必选

      示例值

      描述

      access_token

      String

      333ab704-abc0-48b3-8af0-496eedd15383

      Access Tok

        • 返回参数响应示例

      {
          "success": true,
          "code": "200",
          "message": null,
          "requestId": "149DA248-8F49-4820-B87A-5EA36D932354",
          "data": {
              "sub": "823071756087671783",
              "ou_id": "2079225187122667069",
              "nickname": "test",
              "phone_number": 11136618971,
              "ou_name": "阿里云IDAAS",
              "email": "test@test.com",
              "username": "test"
          }
      }

        • 参数说明

      参数

      类型

      示例值

      描述

      success

      boolean

      true

      是否成功

      code

      String

      200

      状态码

      message

      String

      null

      返回消息

      requestId

      String

      B3776BB1-930F-4581-B4C3-18F2D7D136CA

      请求ID

      data

      Object

      响应数据

      sub

      String

      823071756087671783

      子编号

      ouid

      String

      2079225187122667069

      父组织ID

      nickname

      String

      test

      昵称

      phone_number

      String

      11136618971

      手机号

      ou_name

      String

      阿里云IDAAS

      父组织名称

      email

      String

      test@test.com

      邮箱

      username

      String

      test

      用户名

        • 错误码说明

        HttpCode

        错误码

        错误信息

        描述

        401

        Unauthorized

        Unauthorized

        未授权的访问

        403

        Forbidden

        Forbidden

        无权限访问

        404

        ResourceNotFound

        ResourceNotFound

        访问的资源不存在

        415

        UnsupportedMediaType

        UnsupportedMediaType

        不支持的媒体类型

        500

        InternalError

        The request processing has failed due to some unknown error, exception or failure.

        发生未知错误

        这样, 用户登录成功后, 浏览器有了主会话, 一个SP应用利用它获取一个令牌AT(AccessToken),应用拿到AT令牌后去IDaaS认证中心校验令牌是否有效,同时到/userinfo接口去拉取更多的用户信息, 获取到具体的子账户UserId, 有了UserId 就可以创建SP的子会话。 从而在子会话有效期都不用再登录,实现从IDaaS单点登录到应用的全过程。

      FAQ

      1. 如何强制用户登录认证?

      在登录接口增加prompt参数, 当prompt=login则强制跳转登录页 , 也就是在下图 Authorize URL后面增加"&prompt=login"则不论用户是否已经登录认证,都会展示登录页,用户必须进行一次认证,才可继续单点登录流程。

      https://cjl.idaas.test.com/oauth/authorize?response_type=code&scope=read&client_id=825d9cffb88ae45d023ae08cd5eb4ca6yk5YBPePbqV&redirect_uri=http%3A%2F%2Flocalhost%3A8082%2Fasd&state=38e78b11072df978a89138144e6e0933zxm3GeFnjLi_idp&prompt=login
      2. 如何保存初始发起页面?

      在SP发起一个SSO请求的时候, SP需要能够把对应的URL, 保存在内存中, 并和OAuth 中的State 参数关联起来。 这样, 在IDaaS返回State 后, 可以找到当初的URL, 并跳转到这个URL, 实现DeepLinking。比如使用了JAVA的Spring框架的话, 可以用SavedRequest来完成。