diff --git a/CHANGELOG.md b/CHANGELOG.md index 4714e63..1055c6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Unreleased +* Enable [OAuth2 PKCE extension](https://datatracker.ietf.org/doc/html/rfc7636) in our GDS OAuth2 OmniAuth Strategy. + # 18.0.0 * Drop support for Ruby 2.7. (#277) diff --git a/lib/omniauth/strategies/gds.rb b/lib/omniauth/strategies/gds.rb index 2ebec64..f84e3c2 100644 --- a/lib/omniauth/strategies/gds.rb +++ b/lib/omniauth/strategies/gds.rb @@ -4,6 +4,8 @@ class OmniAuth::Strategies::Gds < OmniAuth::Strategies::OAuth2 uid { user["uid"] } + option :pkce, true + info do { name: user["name"], diff --git a/spec/system/authentication_and_authorisation_spec.rb b/spec/system/authentication_and_authorisation_spec.rb index e2c0d2c..605f33d 100644 --- a/spec/system/authentication_and_authorisation_spec.rb +++ b/spec/system/authentication_and_authorisation_spec.rb @@ -1,6 +1,37 @@ require "spec_helper" RSpec.describe "Authenication and authorisation" do + context "omniauth request phase" do + let(:authorize_params) { Rack::Utils.parse_query(URI.parse(page.response_headers["Location"]).query) } + + before do + visit "/auth/gds" + end + + it "includes pkce code_challenge_method in request for /oauth/authorize" do + expect(authorize_params["code_challenge_method"]).to eq("S256") + end + + it "includes pkce code_challenge in request for /oauth/authorize" do + expect(authorize_params["code_challenge"]).to be_present + end + end + + context "omniauth callback phase" do + it "includes pkce code_verifier in request for /oauth/access_token" do + visit "/auth/gds" + + state = Rack::Utils.parse_query(URI.parse(page.response_headers["Location"]).query)["state"] + + stub_request(:post, "http://signon/oauth/access_token") + + visit "/auth/gds/callback?state=#{state}" + + expect(WebMock).to have_requested(:post, "http://signon/oauth/access_token") + .with(body: hash_including({ "code_verifier" => /.*/ })) + end + end + context "when accessing a route that doesn't require permissions or authentication" do it "allows access" do visit "/not-restricted"