From 418507d63c2eb602571a77f6a66173a26d4dc092 Mon Sep 17 00:00:00 2001 From: "Peter H. Boling" Date: Sun, 31 Aug 2025 04:30:07 -0600 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20Add=20Example=20for=20JHipster?= =?UTF-8?q?=20UAA=20Server=20Integration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - closes https://github.com/ruby-oauth/oauth2/issues/355 --- CHANGELOG.md | 1 + README.md | 49 ++++++++++++++++++ docs/OAuth2.html | 2 +- docs/OAuth2/AccessToken.html | 2 +- docs/OAuth2/Authenticator.html | 2 +- docs/OAuth2/Client.html | 2 +- docs/OAuth2/Error.html | 2 +- docs/OAuth2/FilteredAttributes.html | 2 +- .../FilteredAttributes/ClassMethods.html | 2 +- docs/OAuth2/Response.html | 2 +- docs/OAuth2/Strategy.html | 2 +- docs/OAuth2/Strategy/Assertion.html | 2 +- docs/OAuth2/Strategy/AuthCode.html | 2 +- docs/OAuth2/Strategy/Base.html | 2 +- docs/OAuth2/Strategy/ClientCredentials.html | 2 +- docs/OAuth2/Strategy/Implicit.html | 2 +- docs/OAuth2/Strategy/Password.html | 2 +- docs/OAuth2/Version.html | 2 +- docs/_index.html | 2 +- docs/file.CHANGELOG.html | 17 ++++--- docs/file.CITATION.html | 2 +- docs/file.CODE_OF_CONDUCT.html | 2 +- docs/file.CONTRIBUTING.html | 2 +- docs/file.FUNDING.html | 2 +- docs/file.LICENSE.html | 2 +- docs/file.OIDC.html | 2 +- docs/file.README.html | 51 ++++++++++++++++++- docs/file.REEK.html | 2 +- docs/file.RUBOCOP.html | 2 +- docs/file.SECURITY.html | 2 +- docs/file.access_token.html | 2 +- docs/file.authenticator.html | 2 +- docs/file.client.html | 2 +- docs/file.error.html | 2 +- docs/file.filtered_attributes.html | 2 +- docs/file.oauth2-2.0.10.gem.html | 2 +- docs/file.oauth2-2.0.11.gem.html | 2 +- docs/file.oauth2-2.0.12.gem.html | 2 +- docs/file.oauth2-2.0.13.gem.html | 2 +- docs/file.oauth2.html | 2 +- docs/file.response.html | 2 +- docs/file.strategy.html | 2 +- docs/file.version.html | 2 +- docs/index.html | 51 ++++++++++++++++++- docs/top-level-namespace.html | 2 +- 45 files changed, 199 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4882ff50..5b78172a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - simplified client definitions) - document how to implement an OIDC client with this gem in OIDC.md - also, list libraries built on top of the oauth2 gem that implement OIDC +- README: Add example for JHipster UAA (Spring Cloud) password grant, converted from Postman/Net::HTTP ### Changed ### Deprecated ### Removed diff --git a/README.md b/README.md index 434f932c..a029a2cb 100644 --- a/README.md +++ b/README.md @@ -798,6 +798,55 @@ resp = access.get("/v1/things") access = client.password.get_token("jdoe", "s3cret", scope: "read") ``` +#### Examples + +
+JHipster UAA (Spring Cloud) password grant example (legacy; avoid when possible) + +```ruby +# This converts a Postman/Net::HTTP multipart token request to oauth2 gem usage. +# JHipster UAA typically exposes the token endpoint at /uaa/oauth/token. +# The original snippet included: +# - Basic Authorization header for the client (web_app:changeit) +# - X-XSRF-TOKEN header from a cookie (some deployments require it) +# - grant_type=password with username/password and client_id +# Using oauth2 gem, you don't need to build multipart bodies; the gem sends +# application/x-www-form-urlencoded as required by RFC 6749. + +require "oauth2" + +client = OAuth2::Client.new( + "web_app", # client_id + "changeit", # client_secret + site: "http://localhost:8080/uaa", + token_url: "/oauth/token", # absolute under site (or "oauth/token" relative) + auth_scheme: :basic_auth, # sends HTTP Basic Authorization header +) + +# If your UAA requires an XSRF header for the token call, provide it as a header. +# Often this is not required for token endpoints, but if your gateway enforces it, +# obtain the value from the XSRF-TOKEN cookie and pass it here. +xsrf_token = ENV["X_XSRF_TOKEN"] # e.g., pulled from a prior set-cookie value + +access = client.password.get_token( + "admin", # username + "admin", # password + headers: xsrf_token ? {"X-XSRF-TOKEN" => xsrf_token} : {}, + # JHipster commonly also accepts/needs the client_id in the body; include if required: + # client_id: "web_app", +) + +puts access.token +puts access.to_hash # full token response +``` + +Notes: +- Resource Owner Password Credentials (ROPC) is deprecated in OAuth 2.1 and discouraged. Prefer Authorization Code + PKCE. +- If your deployment strictly demands the X-XSRF-TOKEN header, first fetch it from an endpoint that sets the XSRF-TOKEN cookie (often "/" or a login page) and pass it to headers. +- For Basic auth, auth_scheme: :basic_auth handles the Authorization header; you do not need to base64-encode manually. + +
+ ### Refresh Tokens When the server issues a refresh_token, you can refresh manually or implement an auto-refresh wrapper. diff --git a/docs/OAuth2.html b/docs/OAuth2.html index 29589692..5ac242ac 100644 --- a/docs/OAuth2.html +++ b/docs/OAuth2.html @@ -415,7 +415,7 @@

diff --git a/docs/OAuth2/AccessToken.html b/docs/OAuth2/AccessToken.html index 40443e45..be573ceb 100644 --- a/docs/OAuth2/AccessToken.html +++ b/docs/OAuth2/AccessToken.html @@ -3069,7 +3069,7 @@

diff --git a/docs/OAuth2/Authenticator.html b/docs/OAuth2/Authenticator.html index 2d8d9d58..d1e8ac9b 100644 --- a/docs/OAuth2/Authenticator.html +++ b/docs/OAuth2/Authenticator.html @@ -883,7 +883,7 @@

diff --git a/docs/OAuth2/Client.html b/docs/OAuth2/Client.html index eb046f10..083e6461 100644 --- a/docs/OAuth2/Client.html +++ b/docs/OAuth2/Client.html @@ -2656,7 +2656,7 @@

diff --git a/docs/OAuth2/Error.html b/docs/OAuth2/Error.html index b852be13..2a1497a9 100644 --- a/docs/OAuth2/Error.html +++ b/docs/OAuth2/Error.html @@ -772,7 +772,7 @@

diff --git a/docs/OAuth2/FilteredAttributes.html b/docs/OAuth2/FilteredAttributes.html index 82ca2b5c..8eecda7f 100644 --- a/docs/OAuth2/FilteredAttributes.html +++ b/docs/OAuth2/FilteredAttributes.html @@ -335,7 +335,7 @@

diff --git a/docs/OAuth2/FilteredAttributes/ClassMethods.html b/docs/OAuth2/FilteredAttributes/ClassMethods.html index e729ba40..8f462b6b 100644 --- a/docs/OAuth2/FilteredAttributes/ClassMethods.html +++ b/docs/OAuth2/FilteredAttributes/ClassMethods.html @@ -280,7 +280,7 @@

diff --git a/docs/OAuth2/Response.html b/docs/OAuth2/Response.html index 17bbd4f8..59b51256 100644 --- a/docs/OAuth2/Response.html +++ b/docs/OAuth2/Response.html @@ -1619,7 +1619,7 @@

diff --git a/docs/OAuth2/Strategy.html b/docs/OAuth2/Strategy.html index 1117d94d..a2cb9437 100644 --- a/docs/OAuth2/Strategy.html +++ b/docs/OAuth2/Strategy.html @@ -107,7 +107,7 @@

Defined Under Namespace

diff --git a/docs/OAuth2/Strategy/Assertion.html b/docs/OAuth2/Strategy/Assertion.html index 69264be5..431c6130 100644 --- a/docs/OAuth2/Strategy/Assertion.html +++ b/docs/OAuth2/Strategy/Assertion.html @@ -481,7 +481,7 @@

diff --git a/docs/OAuth2/Strategy/AuthCode.html b/docs/OAuth2/Strategy/AuthCode.html index 6480e47e..eb2b5df1 100644 --- a/docs/OAuth2/Strategy/AuthCode.html +++ b/docs/OAuth2/Strategy/AuthCode.html @@ -483,7 +483,7 @@

diff --git a/docs/OAuth2/Strategy/Base.html b/docs/OAuth2/Strategy/Base.html index 05d29d90..b4cccf51 100644 --- a/docs/OAuth2/Strategy/Base.html +++ b/docs/OAuth2/Strategy/Base.html @@ -195,7 +195,7 @@

diff --git a/docs/OAuth2/Strategy/ClientCredentials.html b/docs/OAuth2/Strategy/ClientCredentials.html index 1e935d28..ae1ee71f 100644 --- a/docs/OAuth2/Strategy/ClientCredentials.html +++ b/docs/OAuth2/Strategy/ClientCredentials.html @@ -343,7 +343,7 @@

diff --git a/docs/OAuth2/Strategy/Implicit.html b/docs/OAuth2/Strategy/Implicit.html index f6a52a17..89cda099 100644 --- a/docs/OAuth2/Strategy/Implicit.html +++ b/docs/OAuth2/Strategy/Implicit.html @@ -420,7 +420,7 @@

diff --git a/docs/OAuth2/Strategy/Password.html b/docs/OAuth2/Strategy/Password.html index 874eacd3..7f30be63 100644 --- a/docs/OAuth2/Strategy/Password.html +++ b/docs/OAuth2/Strategy/Password.html @@ -374,7 +374,7 @@

diff --git a/docs/OAuth2/Version.html b/docs/OAuth2/Version.html index 185cbff7..b77c91f2 100644 --- a/docs/OAuth2/Version.html +++ b/docs/OAuth2/Version.html @@ -111,7 +111,7 @@

diff --git a/docs/_index.html b/docs/_index.html index 0aeb681f..847f17b2 100644 --- a/docs/_index.html +++ b/docs/_index.html @@ -366,7 +366,7 @@

Namespace Listing A-Z

diff --git a/docs/file.CHANGELOG.html b/docs/file.CHANGELOG.html index 1800d34a..b28f4c4b 100644 --- a/docs/file.CHANGELOG.html +++ b/docs/file.CHANGELOG.html @@ -79,15 +79,16 @@

Added

  • document how to implement an OIDC client with this gem in OIDC.md
  • +
  • README: Add example for JHipster UAA (Spring Cloud) password grant, converted from Postman/Net::HTTP +

    Changed

    +

    Deprecated

    +

    Removed

    +

    Fixed

    +

    Security

    +
  • @@ -1244,7 +1245,7 @@

    diff --git a/docs/file.CITATION.html b/docs/file.CITATION.html index cfb8a348..6b826eb1 100644 --- a/docs/file.CITATION.html +++ b/docs/file.CITATION.html @@ -82,7 +82,7 @@ diff --git a/docs/file.CODE_OF_CONDUCT.html b/docs/file.CODE_OF_CONDUCT.html index b734d9de..f6e031d6 100644 --- a/docs/file.CODE_OF_CONDUCT.html +++ b/docs/file.CODE_OF_CONDUCT.html @@ -191,7 +191,7 @@

    Attribution

    diff --git a/docs/file.CONTRIBUTING.html b/docs/file.CONTRIBUTING.html index 47ab5b39..6b6331c4 100644 --- a/docs/file.CONTRIBUTING.html +++ b/docs/file.CONTRIBUTING.html @@ -274,7 +274,7 @@

    Manual process

    diff --git a/docs/file.FUNDING.html b/docs/file.FUNDING.html index 8898aed1..40725527 100644 --- a/docs/file.FUNDING.html +++ b/docs/file.FUNDING.html @@ -104,7 +104,7 @@

    Another Way to Support Open diff --git a/docs/file.LICENSE.html b/docs/file.LICENSE.html index 668c2ecc..a07d6c0e 100644 --- a/docs/file.LICENSE.html +++ b/docs/file.LICENSE.html @@ -60,7 +60,7 @@
    MIT License

    Copyright (c) 2017-2025 Peter H. Boling, of Galtzo.com, and oauth2 contributors
    Copyright (c) 2011-2013 Michael Bleigh and Intridea, Inc.

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    SOFTWARE.
    diff --git a/docs/file.OIDC.html b/docs/file.OIDC.html index bba61a62..6d44d273 100644 --- a/docs/file.OIDC.html +++ b/docs/file.OIDC.html @@ -247,7 +247,7 @@

    Raw OIDC with ruby-oauth/oauth2

    diff --git a/docs/file.README.html b/docs/file.README.html index 984b4d15..d8f9587c 100644 --- a/docs/file.README.html +++ b/docs/file.README.html @@ -937,6 +937,55 @@

    Common Flows (end-to-end)

    access = client.password.get_token("jdoe", "s3cret", scope: "read")
     
    +

    Examples

    + +
    +JHipster UAA (Spring Cloud) password grant example (legacy; avoid when possible) + +```ruby +# This converts a Postman/Net::HTTP multipart token request to oauth2 gem usage. +# JHipster UAA typically exposes the token endpoint at /uaa/oauth/token. +# The original snippet included: +# - Basic Authorization header for the client (web_app:changeit) +# - X-XSRF-TOKEN header from a cookie (some deployments require it) +# - grant_type=password with username/password and client_id +# Using oauth2 gem, you don't need to build multipart bodies; the gem sends +# application/x-www-form-urlencoded as required by RFC 6749. + +require "oauth2" + +client = OAuth2::Client.new( + "web_app", # client_id + "changeit", # client_secret + site: "http://localhost:8080/uaa", + token_url: "/oauth/token", # absolute under site (or "oauth/token" relative) + auth_scheme: :basic_auth, # sends HTTP Basic Authorization header +) + +# If your UAA requires an XSRF header for the token call, provide it as a header. +# Often this is not required for token endpoints, but if your gateway enforces it, +# obtain the value from the XSRF-TOKEN cookie and pass it here. +xsrf_token = ENV["X_XSRF_TOKEN"] # e.g., pulled from a prior set-cookie value + +access = client.password.get_token( + "admin", # username + "admin", # password + headers: xsrf_token ? => xsrf_token : {}, + # JHipster commonly also accepts/needs the client_id in the body; include if required: + # client_id: "web_app", +) + +puts access.token +puts access.to_hash # full token response +``` + +Notes: +- Resource Owner Password Credentials (ROPC) is deprecated in OAuth 2.1 and discouraged. Prefer Authorization Code + PKCE. +- If your deployment strictly demands the X-XSRF-TOKEN header, first fetch it from an endpoint that sets the XSRF-TOKEN cookie (often "/" or a login page) and pass it to headers. +- For Basic auth, auth_scheme: :basic_auth handles the Authorization header; you do not need to base64-encode manually. + +
    +

    Refresh Tokens

    When the server issues a refresh_token, you can refresh manually or implement an auto-refresh wrapper.

    @@ -1327,7 +1376,7 @@

    Please give the project a star ⭐ ♥ diff --git a/docs/file.REEK.html b/docs/file.REEK.html index b7f88131..90047ac4 100644 --- a/docs/file.REEK.html +++ b/docs/file.REEK.html @@ -61,7 +61,7 @@ diff --git a/docs/file.RUBOCOP.html b/docs/file.RUBOCOP.html index 12b309de..2b54635d 100644 --- a/docs/file.RUBOCOP.html +++ b/docs/file.RUBOCOP.html @@ -161,7 +161,7 @@

    Benefits of rubocop_gradual

    diff --git a/docs/file.SECURITY.html b/docs/file.SECURITY.html index 72e893b1..5543e445 100644 --- a/docs/file.SECURITY.html +++ b/docs/file.SECURITY.html @@ -113,7 +113,7 @@

    Enterprise Support

    diff --git a/docs/file.access_token.html b/docs/file.access_token.html index 0f803ede..f5c107c0 100644 --- a/docs/file.access_token.html +++ b/docs/file.access_token.html @@ -84,7 +84,7 @@ diff --git a/docs/file.authenticator.html b/docs/file.authenticator.html index abf4b0bc..92e43342 100644 --- a/docs/file.authenticator.html +++ b/docs/file.authenticator.html @@ -81,7 +81,7 @@ diff --git a/docs/file.client.html b/docs/file.client.html index 04fbe9c3..54a8ee04 100644 --- a/docs/file.client.html +++ b/docs/file.client.html @@ -111,7 +111,7 @@ diff --git a/docs/file.error.html b/docs/file.error.html index f6679210..a67057bf 100644 --- a/docs/file.error.html +++ b/docs/file.error.html @@ -68,7 +68,7 @@ diff --git a/docs/file.filtered_attributes.html b/docs/file.filtered_attributes.html index deb0dfd6..321800fb 100644 --- a/docs/file.filtered_attributes.html +++ b/docs/file.filtered_attributes.html @@ -66,7 +66,7 @@ diff --git a/docs/file.oauth2-2.0.10.gem.html b/docs/file.oauth2-2.0.10.gem.html index 4651750e..f2067f05 100644 --- a/docs/file.oauth2-2.0.10.gem.html +++ b/docs/file.oauth2-2.0.10.gem.html @@ -61,7 +61,7 @@ diff --git a/docs/file.oauth2-2.0.11.gem.html b/docs/file.oauth2-2.0.11.gem.html index bd91a146..0de82d22 100644 --- a/docs/file.oauth2-2.0.11.gem.html +++ b/docs/file.oauth2-2.0.11.gem.html @@ -61,7 +61,7 @@ diff --git a/docs/file.oauth2-2.0.12.gem.html b/docs/file.oauth2-2.0.12.gem.html index 77de0097..a68ef53b 100644 --- a/docs/file.oauth2-2.0.12.gem.html +++ b/docs/file.oauth2-2.0.12.gem.html @@ -61,7 +61,7 @@ diff --git a/docs/file.oauth2-2.0.13.gem.html b/docs/file.oauth2-2.0.13.gem.html index e14b7573..b709b725 100644 --- a/docs/file.oauth2-2.0.13.gem.html +++ b/docs/file.oauth2-2.0.13.gem.html @@ -61,7 +61,7 @@ diff --git a/docs/file.oauth2.html b/docs/file.oauth2.html index ae49d83e..13aa7462 100644 --- a/docs/file.oauth2.html +++ b/docs/file.oauth2.html @@ -69,7 +69,7 @@ diff --git a/docs/file.response.html b/docs/file.response.html index 3f4f9aee..4d995be8 100644 --- a/docs/file.response.html +++ b/docs/file.response.html @@ -77,7 +77,7 @@ diff --git a/docs/file.strategy.html b/docs/file.strategy.html index 7efc0324..4a213119 100644 --- a/docs/file.strategy.html +++ b/docs/file.strategy.html @@ -93,7 +93,7 @@ diff --git a/docs/file.version.html b/docs/file.version.html index 216e9cb2..40991e29 100644 --- a/docs/file.version.html +++ b/docs/file.version.html @@ -65,7 +65,7 @@ diff --git a/docs/index.html b/docs/index.html index 28ad4d8b..d06c59d7 100644 --- a/docs/index.html +++ b/docs/index.html @@ -937,6 +937,55 @@

    Common Flows (end-to-end)

    access = client.password.get_token("jdoe", "s3cret", scope: "read")
     
    +

    Examples

    + +
    +JHipster UAA (Spring Cloud) password grant example (legacy; avoid when possible) + +```ruby +# This converts a Postman/Net::HTTP multipart token request to oauth2 gem usage. +# JHipster UAA typically exposes the token endpoint at /uaa/oauth/token. +# The original snippet included: +# - Basic Authorization header for the client (web_app:changeit) +# - X-XSRF-TOKEN header from a cookie (some deployments require it) +# - grant_type=password with username/password and client_id +# Using oauth2 gem, you don't need to build multipart bodies; the gem sends +# application/x-www-form-urlencoded as required by RFC 6749. + +require "oauth2" + +client = OAuth2::Client.new( + "web_app", # client_id + "changeit", # client_secret + site: "http://localhost:8080/uaa", + token_url: "/oauth/token", # absolute under site (or "oauth/token" relative) + auth_scheme: :basic_auth, # sends HTTP Basic Authorization header +) + +# If your UAA requires an XSRF header for the token call, provide it as a header. +# Often this is not required for token endpoints, but if your gateway enforces it, +# obtain the value from the XSRF-TOKEN cookie and pass it here. +xsrf_token = ENV["X_XSRF_TOKEN"] # e.g., pulled from a prior set-cookie value + +access = client.password.get_token( + "admin", # username + "admin", # password + headers: xsrf_token ? => xsrf_token : {}, + # JHipster commonly also accepts/needs the client_id in the body; include if required: + # client_id: "web_app", +) + +puts access.token +puts access.to_hash # full token response +``` + +Notes: +- Resource Owner Password Credentials (ROPC) is deprecated in OAuth 2.1 and discouraged. Prefer Authorization Code + PKCE. +- If your deployment strictly demands the X-XSRF-TOKEN header, first fetch it from an endpoint that sets the XSRF-TOKEN cookie (often "/" or a login page) and pass it to headers. +- For Basic auth, auth_scheme: :basic_auth handles the Authorization header; you do not need to base64-encode manually. + +
    +

    Refresh Tokens

    When the server issues a refresh_token, you can refresh manually or implement an auto-refresh wrapper.

    @@ -1327,7 +1376,7 @@

    Please give the project a star ⭐ ♥ diff --git a/docs/top-level-namespace.html b/docs/top-level-namespace.html index 599b7b92..e19df3d2 100644 --- a/docs/top-level-namespace.html +++ b/docs/top-level-namespace.html @@ -100,7 +100,7 @@

    Defined Under Namespace