说明: 本文档用于描述spring-oauth-server对外开发的接口(API)使用, 所有标记 public 的API都是公开的, 其他的API则需要先授权获取 access_token 后可调用 (如何传递access_token请查看 https://andaily.com/blog/?p=500).

获取access_token (grant_type=authorization_code) public

使用grant_type=authorization_code 方式来获取access_token, 需要先获取code

  • 请求URI: /oauth2/token POST

    请求参数说明:
    参数名 参数值 必须? 备注
    client_id {client_id}
    client_secret {client_secret}
    grant_type authorization_code 固定值
    code {code}
    redirect_uri {redirect_uri}
    code_verifier {code_verifier} PKCE时必须
    请求示例:
      curl --location 'http://localhost:8080/oauth2/token' \
      --header 'Content-Type: application/json' \
      --form 'client_id="client11"' \
      --form 'grant_type="authorization_code"' \
      --form 'redirect_uri="http://localhost:8083/oauth2/callback"' \
      --form 'code="-VEnyAcEflDxjMh4Hr-6YejZq4Mel5gihFy_FMyotDxLhILeMBQheJkL4mdJ0sKD_C8xpa_sMNGf_I2tYJIVki8a4ktT2QsHojhbV3HpbGLVhJ0qDc8kfXjWt7u_24QO"' \
      --form 'client_secret="secret22"'

    响应
    • 正常 [200]
      {
        "access_token": "7154afT_cxvLDq1naSg6Aq9ueSFSW8xRr5txryW5MlddRe7nV0RogTYwPsJc_rrRqwaIvLleerLhkjtIN2E2U-4J_BzvYNCsv8BVLqeerCObwgwpP3t__NMMUakzRL2i",
        "refresh_token": "TZ9tzVwE_VLoJxALUSw4A4A0Nj7SLSWXCc69U9rvNmSnqR8Hbz-1m4uHebJWsAK0sa7SDIR4SNXOB3iaM0p1bH_8EBrljoBApQgdYi1uYzcVwYq55OVV2RUHN2BJwfSr",
        "scope": "openid profile",
        "id_token": "eyJraWQiOiJzb3MtZWNjLWtpZDEiLCJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJ1bml0eSIsImF1ZCI6IjZ1ck5MZ1I2b3NrMkU1NmVrcCIsInVwZGF0ZWRfYXQiOiIiLCJhenAiOiI2dXJOTGdSNm9zazJFNTZla3AiLCJhdXRoX3RpbWUiOjE2OTc3MDczNTQsImlzcyI6Imh0dHA6Ly8xMjcuMC4wLjE6ODA4MCIsIm5pY2tuYW1lIjoiIiwiZXhwIjoxNjk3NzA5MjA4LCJpYXQiOjE2OTc3MDc0MDgsImp0aSI6IjEyNTc0MjU2NTk4MDI2ODY2NzI3NDAwMTMxNjk5NDk0Iiwic2lkIjoidXdwN255RnJwdlNtWmlQS2hCdWVSVFZfcVRKYkN6ZjAyTmYwQTZGN1lrSSJ9.3w-7EY9SwKA-UkXlhDfD2BbSwP6nCSLZxNgKwhkkMY8YPbMkygbj374SmEmsit7NlpRXHCtW6ULZ9_IVZ9MTBg",
        "token_type": "Bearer",
        "expires_in": 3599
      }
    • 异常 [401]
      {
          "error": "invalid_grant"
      }

返回

获取access_token (grant_type=client_credentials) public

使用grant_type=client_credentials 方式来获取access_token, 不需要username, password

  • 请求URI: /oauth2/token POST

    请求参数说明:
    参数名 参数值 必须? 备注
    client_id {client_id}
    client_secret {client_secret}
    grant_type client_credentials 固定值
    scope {scope} 如: openid
    请求示例:
    curl --location 'http://localhost:8080/oauth2/token' \
    --header 'Content-Type: application/json' \
    --form 'client_id="6urNLgR6osk2E56ekp"' \
    --form 'client_secret="6urNLgR6osk2E56ekp"' \
    --form 'grant_type="client_credentials"' \
    --form 'scope="openid profile"'

    响应
    • 正常 [200]
      {
          "access_token": "p2i1WHiiFBCgTJFTs63OvO9-bclB9DbsgsebDo_ntMw_BAleu2RzIQzzFfaaJAR5oiL3xwN3xMyNTRZSrXM_1ANycleysPU5l3xuZ0aQX4V-Va178qg6e-PvLqLBsD_i",
          "scope": "openid profile",
          "token_type": "Bearer",
          "expires_in": 3599
      }
    • 异常 [401]
      {
          "error": "invalid_client"
      }

返回

刷新access_token (grant_type=refresh_token) public

用于在access_token要过期时换取新的access_token (grant_type需要有refresh_token)

  • 请求URI: /oauth2/token POST

    请求参数说明:
    参数名 参数值 必须? 备注
    client_id {client_id}
    client_secret {client_secret}
    grant_type refresh_token 固定值
    refresh_token {refresh_token}
    请求示例:
    curl --location 'http://localhost:8080/oauth2/token' \
    --header 'Content-Type: application/json' \
    --form 'client_id="6urNLgR6osk2E56ekp"' \
    --form 'client_secret="6urNLgR6osk2E56ekp"' \
    --form 'grant_type="refresh_token"' \
    --form 'refresh_token="TZ9tzVwE_VLoJxALUSw4A4A0Nj7SLSWXCc69U9rvNmSnqR8Hbz-1m4uHebJWsAK0sa7SDIR4SNXOB3iaM0p1bH_8EBrljoBApQgdYi1uYzcVwYq55OVV2RUHN2BJwfSr"'

    响应
    • 正常 [200]
      {
          "access_token": "YnVdTXl0MhslsrOjiz1ffSixvPnWCN-XS-UBlkS89daZbd_TvXtSSo_ODuFVWPWw1KsO5WQykVPjwSe_Kreo8ngIP9DglaXJMbYJJu4Wa6_geOINj5ksmnbfb6pHrQHr",
          "refresh_token": "TZ9tzVwE_VLoJxALUSw4A4A0Nj7SLSWXCc69U9rvNmSnqR8Hbz-1m4uHebJWsAK0sa7SDIR4SNXOB3iaM0p1bH_8EBrljoBApQgdYi1uYzcVwYq55OVV2RUHN2BJwfSr",
          "scope": "openid profile",
          "id_token": "eyJraWQiOiJzb3MtZWNjLWtpZDEiLCJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJ1bml0eSIsImF1ZCI6IjZ1ck5MZ1I2b3NrMkU1NmVrcCIsInVwZGF0ZWRfYXQiOjAsImF6cCI6IjZ1ck5MZ1I2b3NrMkU1NmVrcCIsImF1dGhfdGltZSI6MTY5NzcwNzM1NCwiaXNzIjoiaHR0cDovLzEyNy4wLjAuMTo4MDgwIiwibmlja25hbWUiOiIiLCJleHAiOjE2OTc3MjQyNjMsImlhdCI6MTY5NzcyMjQ2MywianRpIjoiMDc4OTc4MTUxNzEwNTgwNDE2ODY0NzgxMDQ1OTM5MDYiLCJzaWQiOiJ1d3A3bnlGcnB2U21aaVBLaEJ1ZVJUVl9xVEpiQ3pmMDJOZjBBNkY3WWtJIn0.j0KVv7bAi85zbX-0wvWe83n_CQdmJLGrHJNFwF5jA1-wa8QzaSwJbznpjbHLGTv-UbI2YeHLn8N5iGXDarbC9Q",
          "token_type": "Bearer",
          "expires_in": 3599
      }
    • 异常 [401]
      {
          "error": "invalid_client"
      }

检查token (/oauth2/introspect) public

校验, 检查token的有效性

  • 请求URI: /oauth2/introspect POST

    请求参数说明:
    参数名 参数值 必须? 备注
    client_id {client_id}
    client_secret {client_secret}
    token {token} token可以是access_token, refresh_tokenid_token
    请求示例:
    curl --location 'http://localhost:8080/oauth2/introspect' \
    --header 'Content-Type: application/json' \
    --form 'client_id="6urNLgR6osk2E56ekp"' \
    --form 'client_secret="6urNLgR6osk2E56ekp"' \
    --form 'token="GaHu88XEEAz41xMHfDk05bg9uSJ5Go1RF6jOe5eX7OhHD_52NK_fuwvVWq_dTRIhK8WR9SnCAtBBc0fVsOyGgz8-MhmVTG-dcDi6QtGQQtYxwmGrD-fOhpmePdUv6pwV"'

    响应
    • 正常 [200]
      {
          "active": true,
          "sub": "admin",
          "aud": [
              "6urNLgR6osk2E56ekp"
          ],
          "nbf": 1697721873,
          "scope": "openid profile",
          "iss": "http://127.0.0.1:8080",
          "exp": 1697725474,
          "iat": 1697721874,
          "jti": "a1aa8f82-c885-45b3-a469-c2f595e8f12d",
          "client_id": "6urNLgR6osk2E56ekp",
          "token_type": "Bearer"
      }

      根据不同类型的token响应结果不相同; active=true表示token为有效的

    • 异常 [200]
      {
          "active": false
      }

返回

撤销token (/oauth2/revoke) public

撤销已经签发的token

  • 请求URI: /oauth2/revoke POST

    请求参数说明:
    参数名 参数值 必须? 备注
    client_id {client_id}
    client_secret {client_secret}
    token {token} token可以是access_token, refresh_tokenid_token
    请求示例:
    curl --location 'http://localhost:8080/oauth2/revoke' \
    --header 'Content-Type: application/json' \
    --form 'client_id="6urNLgR6osk2E56ekp"' \
    --form 'client_secret="6urNLgR6osk2E56ekp"' \
    --form 'token="TZ9tzVwE_VLoJxALUSw4A4A0Nj7SLSWXCc69U9rvNmSnqR8Hbz-1m4uHebJWsAK0sa7SDIR4SNXOB3iaM0p1bH_8EBrljoBApQgdYi1uYzcVwYq55OVV2RUHN2BJwfSr"'

    响应
    • 正常 [200]
      
                                      

      此API不管什么token结果都响应200; 若token是有效的会成功撤销

    • 异常 [200]
      
                                  

[device_code]流程 - 发起认证(/oauth2/device_authorization)public

发起认证, 获取user_code, device_code等信息

  • 请求URI: /oauth2/device_authorization POST

    请求参数说明:
    参数名 参数值 必须? 备注
    client_id {client_id}
    client_secret {client_secret}
    scope {scope} 如: openid profile
    请求示例:
    curl --location 'http://localhost:8080/oauth2/device_authorization' \
    --header 'Content-Type: application/json' \
    --form 'client_id="6urNLgR6osk2E56ekp"' \
    --form 'client_secret="6urNLgR6osk2E56ekp"' \
    --form 'scope="openid profile"'

    响应
    • 正常 [200]
      {
          "user_code": "PCKJ-FWZS",
          "device_code": "ZPMq2sfyHPj_pJ78T6J4yGcsAAi_XbuBjtQz2NLxYWKDHbcqUhg2nFHe3Ynp3V1SyCOwYEoaz9lPvqt-oj0sXKxJDnC5usJmANVqMQ-8Qjpp1ROi9gljdQY2NO3YYvIo",
          "verification_uri_complete": "http://127.0.0.1:8080/oauth2/device_verification?user_code=PCKJ-FWZS",
          "verification_uri": "http://127.0.0.1:8080/oauth2/device_verification",
          "expires_in": 300
      }
    • 异常 [401]
      {
          "error": "invalid_client"
      }

[device_code]流程 - 获取token(/oauth2/token)public

设备上轮循调用, 获取token

  • 请求URI: /oauth2/token POST

    请求参数说明:
    参数名 参数值 必须? 备注
    client_id {client_id}
    client_secret {client_secret}
    grant_type urn:ietf:params:oauth:grant-type:device_code 固定值
    device_code {device_code} 发起认证时返回的device_code值
    请求示例:
    curl --location 'http://localhost:8080/oauth2/token' \
    --header 'Content-Type: application/json' \
    --form 'client_id="6urNLgR6osk2E56ekp"' \
    --form 'client_secret="6urNLgR6osk2E56ekp"' \
    --form 'grant_type="urn:ietf:params:oauth:grant-type:device_code"' \
    --form 'device_code="iBv-_clBQtJR4w2eN8bgGBnwWgcoem6FCJlHgahhHNOq9oImcJAWLYKJ-jJOk207X19uE-glkArRLnhXgpm0C0pQcoxAZyoMmgznvWxOITQUYFYdAluBTo-fmDteKSgh"'

    响应
    • 正常 [200]
      {
          "access_token": "QqPGuiF9c2HKYQEdxrs9E0WsRijEl_z9sINI6CFD5yMulXaZutLTktVtLP3zcr22XuYJOzWZMzOgvjWl2tqAoMo3S2MHBgxjPmx5gfr6DjeQPsW3fFPVc6pOa5Ll6u4S",
          "refresh_token": "7vtQtkU95tjt7nkaX8DZnDVntrgPYIoXB6_4WsV9FzMi-ppoPB_H5qmufi4EHqAuJPwdlxXYdDbVYoGudXd0iCPfmqT5B8CcW7zRsgaKQOHQlPw9Ju3wMGNSRk14YRWI",
          "scope": "profile",
          "token_type": "Bearer",
          "expires_in": 3599
      }
    • 异常 [400]
      {
          "error": "authorization_pending",
          "error_uri": "https://datatracker.ietf.org/doc/html/rfc8628#section-3.5"
      }

      说明: error=authorization_pending 表示授权正在进行中, 设备上需要轮循继续等待授权结果

OIDC /userinfo

客户端带上access_token获取用户信息

  • 请求URI: /userinfo GET

    请求参数说明:
    参数名 参数值 必须? 备注
    请求示例:
    curl --location 'http://localhost:8080/userinfo' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer eyJraWQiOiJzb3MtcnNhLWtpZDIiLCJhbGciOiJSUzI1NiJ9.eyJzdWI...'

    响应
    • 正常 [200]
      {
          "sub": "unity",
          "updated_at": 0,
          "nickname": ""
      }
    • 异常 [401]
      
                                  

OIDC /openid-configurationpublic

OIDC well-known API

  • 请求URI: /.well-known/openid-configuration GET

    请求参数说明:
    参数名 参数值 必须? 备注
    请求示例:
    curl --location 'http://localhost:8080/.well-known/openid-configuration' \
    --header 'Content-Type: application/json'

    响应
    • 正常 [200]
      {
          "issuer": "http://127.0.0.1:8080",
          "authorization_endpoint": "http://127.0.0.1:8080/oauth2/authorize",
          "device_authorization_endpoint": "http://127.0.0.1:8080/oauth2/device_authorization",
          "token_endpoint": "http://127.0.0.1:8080/oauth2/token",
          "token_endpoint_auth_methods_supported": [
              "client_secret_basic",
              "client_secret_post",
              "client_secret_jwt",
              "private_key_jwt"
          ],
          "jwks_uri": "http://127.0.0.1:8080/oauth2/jwks",
          "userinfo_endpoint": "http://127.0.0.1:8080/userinfo",
          "end_session_endpoint": "http://127.0.0.1:8080/connect/logout",
          "response_types_supported": [
              "code"
          ],
          "grant_types_supported": [
              "authorization_code",
              "client_credentials",
              "refresh_token",
              "urn:ietf:params:oauth:grant-type:device_code",
              "password",
              "urn:ietf:params:oauth:grant-type:jwt-bearer"
          ],
          "revocation_endpoint": "http://127.0.0.1:8080/oauth2/revoke",
          "revocation_endpoint_auth_methods_supported": [
              "client_secret_basic",
              "client_secret_post",
              "client_secret_jwt",
              "private_key_jwt"
          ],
          "introspection_endpoint": "http://127.0.0.1:8080/oauth2/introspect",
          "introspection_endpoint_auth_methods_supported": [
              "client_secret_basic",
              "client_secret_post",
              "client_secret_jwt",
              "private_key_jwt"
          ],
          "subject_types_supported": [
              "public"
          ],
          "id_token_signing_alg_values_supported": [
              "RS256",
              "ES256"
          ],
          "scopes_supported": [
              "openid",
              "profile",
              "email",
              "address",
              "phone"
          ]
      }
    • 异常 [400]
      
                                  

返回

OAuth2.1 /oauth-authorization-serverpublic

OAuth2.1 well-known API

  • 请求URI: /.well-known/oauth-authorization-server GET

    请求参数说明:
    参数名 参数值 必须? 备注
    请求示例:
    curl --location 'http://localhost:8080/.well-known/oauth-authorization-server' \
    --header 'Content-Type: application/json'

    响应
    • 正常 [200]
      {
          "issuer": "http://127.0.0.1:8080",
          "authorization_endpoint": "http://127.0.0.1:8080/oauth2/authorize",
          "device_authorization_endpoint": "http://127.0.0.1:8080/oauth2/device_authorization",
          "token_endpoint": "http://127.0.0.1:8080/oauth2/token",
          "token_endpoint_auth_methods_supported": [
              "client_secret_basic",
              "client_secret_post",
              "client_secret_jwt",
              "private_key_jwt"
          ],
          "jwks_uri": "http://127.0.0.1:8080/oauth2/jwks",
          "response_types_supported": [
              "code"
          ],
          "grant_types_supported": [
              "authorization_code",
              "client_credentials",
              "refresh_token",
              "urn:ietf:params:oauth:grant-type:device_code"
          ],
          "revocation_endpoint": "http://127.0.0.1:8080/oauth2/revoke",
          "revocation_endpoint_auth_methods_supported": [
              "client_secret_basic",
              "client_secret_post",
              "client_secret_jwt",
              "private_key_jwt"
          ],
          "introspection_endpoint": "http://127.0.0.1:8080/oauth2/introspect",
          "introspection_endpoint_auth_methods_supported": [
              "client_secret_basic",
              "client_secret_post",
              "client_secret_jwt",
              "private_key_jwt"
          ],
          "code_challenge_methods_supported": [
              "S256"
          ]
      }
    • 异常 [400]
      
                                  

© 2013 - 2023 spring-oauth-server