Skip to content

Commit

Permalink
Add PKCE
Browse files Browse the repository at this point in the history
https://trello.com/c/59EBweBx

In alphagov/signon#2312 we enabled the [OAuth2
PKCE extension](https://datatracker.ietf.org/doc/html/rfc7636) in
Signon.

In this commit we update our GDS OAuth2 OmniAuth Strategy to make use of
the PKCE extension. This means that any of our apps using this Gem will
benefit from the additional protection offered by the PKCE extension.
  • Loading branch information
chrisroos committed Aug 23, 2023
1 parent 4466b36 commit fd3dc54
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
2 changes: 2 additions & 0 deletions lib/omniauth/strategies/gds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
class OmniAuth::Strategies::Gds < OmniAuth::Strategies::OAuth2
uid { user["uid"] }

option :pkce, true

info do
{
name: user["name"],
Expand Down
31 changes: 31 additions & 0 deletions spec/system/authentication_and_authorisation_spec.rb
Original file line number Diff line number Diff line change
@@ -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"
Expand Down

0 comments on commit fd3dc54

Please sign in to comment.