Skip to content
This repository has been archived by the owner on Jun 2, 2024. It is now read-only.

Gitlab master #39

Open
wants to merge 45 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
41d31ab
Add .gitlab-ci.yml to test code
stanhu Apr 24, 2021
503cd73
Rename .gemspec and update home page
stanhu Apr 24, 2021
633bc20
Update dependencies
shmokmt Mar 25, 2021
e05891d
Run test on 3.0
shmokmt Mar 25, 2021
2601518
Merge branch 'sh-add-gitlab-ci' into 'master'
stanhu Apr 24, 2021
922ed8d
Fix handling of JWT without key ID
stanhu Apr 23, 2021
770661f
Clean up nonce creation in tests
stanhu Apr 24, 2021
c6a01bc
Merge branch 'sh-fix-missing-jwt-kid' into 'master'
stanhu Apr 24, 2021
ed647d0
Fetch key from JWKS URI if available
stanhu Apr 21, 2021
eec47cf
Merge branch 'sh-fetch-jwks-uri-if-available' into 'master'
stanhu Apr 24, 2021
5688347
Update README.md with link to original project
stanhu Apr 24, 2021
8b6c2fd
Update CHANGELOG.md
stanhu Apr 24, 2021
3ff8f03
Merge branch 'sh-update-readme' into 'master'
stanhu Apr 24, 2021
34dc464
Release v0.4.0
stanhu Apr 24, 2021
bee781f
Always convert client_signing_alg to be a symbol
stanhu Apr 24, 2021
922870a
Merge branch 'sh-allow-client-signing-alg-sym' into 'master'
stanhu Apr 25, 2021
faa8efa
SImplify error handling for decoding individual keys
stanhu Apr 25, 2021
65d85f2
Merge branch 'sh-simplify-decode-error-handling' into 'master'
stanhu Apr 26, 2021
41fa475
Add email_verified field to info dict
chandrn7 May 7, 2021
1115c30
Merge branch 'add-email-verified' into 'master'
stanhu May 7, 2021
5a78d9b
Release v0.5.0
stanhu May 7, 2021
62adec2
Support verification of HS256-signed JWTs
stanhu Jul 8, 2021
968e798
Merge branch 'sh-support-hs256' into 'master'
stanhu Jul 8, 2021
cede014
Release v0.6.0
stanhu Jul 8, 2021
24d21a5
Merge branch 'sh-release-0.6.0' into 'master'
stanhu Jul 8, 2021
5349818
Add option for specifying jwt_secret
stanhu Jul 16, 2021
4d7cdec
Merge branch 'sh-add-jwt-secret' into 'master'
stanhu Jul 16, 2021
624b459
Release v0.7.0
stanhu Jul 16, 2021
018fbb2
Merge branch 'sh-release-0.7.0' into 'master'
stanhu Jul 16, 2021
fb59cf0
Add base64-encoded jwt_secret option
stanhu Jul 16, 2021
d47dff7
Merge branch 'sh-add-jwt-secret-base64' into 'master'
stanhu Jul 16, 2021
74aa517
Release v0.8.0
stanhu Jul 16, 2021
b40b8df
Merge branch 'sh-release-0.8.0' into 'master'
stanhu Jul 16, 2021
83542a1
Fix jwt_secret documentation
stanhu Jul 16, 2021
7497ee7
Merge branch 'sh-fix-docs' into 'master'
stanhu Jul 16, 2021
d9fbe7d
Adding CONTRIBUTING.md after license audit review
Nov 15, 2021
7c82159
Merge branch 'BronwynBarnett-master-patch-37733' into 'master'
stanhu Dec 3, 2021
0de7c5b
add support for ES[256|384|512|256K] algos
aflat Jan 3, 2022
cbdf26b
Merge branch 'master' into 'master'
stanhu Jan 4, 2022
8072b56
Release v0.9.0
stanhu Jan 4, 2022
16e56a1
Merge branch 'sh-release-0.9.0' into 'master'
stanhu Jan 4, 2022
ff5417d
Assume public key encryption unless HMAC is specified
stanhu Jan 4, 2022
d556f61
Merge branch 'sh-future-proof-public-keys' into 'master'
stanhu Jan 4, 2022
bb6206a
Release v0.9.1
stanhu Jan 4, 2022
d664f21
Merge branch 'sh-release-0.9.1' into 'master'
stanhu Jan 4, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.test-template: &test
cache:
paths:
- vendor/ruby
before_script:
- gem install bundler --no-document
- bundle config set --local path 'vendor/ruby'
- bundle install -j $(nproc) --path vendor # Install dependencies into ./vendor/ruby
- ruby -v # Print out ruby version for debugging
script:
- bundle exec rake test

rspec-2.5:
image: "ruby:2.5"
<<: *test

rspec-2.6:
image: "ruby:2.6"
<<: *test

rspec-2.7:
image: "ruby:2.7"
<<: *test

rspec-3.0:
image: "ruby:3.0"
<<: *test
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ rvm:
- 2.5
- 2.6
- 2.7
- 3.0
- jruby-head
- ruby-head
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,35 @@
# v0.9.1 (01.03.2022)

- [Assume public key encryption unless HMAC is specified](https://gitlab.com/gitlab-org/gitlab-omniauth-openid-connect/-/merge_requests/19)

# v0.9.0 (01.03.2022)

- [Add support for ES[256|384|512|256K] algorithms](https://gitlab.com/gitlab-org/gitlab-omniauth-openid-connect/-/merge_requests/17)

# v0.8.0 (07.16.2021)

- [Add `jwt_secret_base64` option to support binary secrets](https://gitlab.com/gitlab-org/gitlab-omniauth-openid-connect/-/merge_requests/12)

# v0.7.0 (07.16.2021)

- [Add `jwt_secret` option to support Keycloak private key](https://gitlab.com/gitlab-org/gitlab-omniauth-openid-connect/-/merge_requests/10)

# v0.6.0 (07.08.2021)

- [Support verification of HS256-signed JWTs](https://gitlab.com/gitlab-org/gitlab-omniauth-openid-connect/-/merge_requests/8)

# v0.5.0 (05.07.2021)

- [Add email_verified field to info dict](https://gitlab.com/gitlab-org/gitlab-omniauth-openid-connect/-/merge_requests/7)
- [Simplify error handling for decoding individual keys](https://gitlab.com/gitlab-org/gitlab-omniauth-openid-connect/-/merge_requests/6)
- [Always convert client_signing_alg to be a symbol](https://gitlab.com/gitlab-org/gitlab-omniauth-openid-connect/-/merge_requests/5)

# v0.4.0 (04.23.2021)

- [Fetch key from JWKS URI if available](https://gitlab.com/gitlab-org/gitlab-omniauth-openid-connect/-/merge_requests/3)
- [Fix handling of JWT without key ID](https://gitlab.com/gitlab-org/gitlab-omniauth-openid-connect/-/merge_requests/2)
- [Add .gitlab-ci.yml and test with Ruby 3.0](https://gitlab.com/gitlab-org/gitlab-omniauth-openid-connect/-/merge_requests/1)

# v0.3.5 (07.06.2020)

- bugfix: Info from decoded id_token is not exposed into `request.env['omniauth.auth']` [#61](https://github.com/m0n9oose/omniauth_openid_connect/pull/61)
Expand Down
40 changes: 40 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## Developer Certificate of Origin and License

By contributing to GitLab B.V., you accept and agree to the following terms and
conditions for your present and future contributions submitted to GitLab B.V.
Except for the license granted herein to GitLab B.V. and recipients of software
distributed by GitLab B.V., you reserve all right, title, and interest in and to
your Contributions.

All contributions are subject to the Developer Certificate of Origin and license set out at [docs.gitlab.com/ce/legal/developer_certificate_of_origin](https://docs.gitlab.com/ce/legal/developer_certificate_of_origin).

_This notice should stay as the first item in the CONTRIBUTING.md file._

## Code of conduct

As contributors and maintainers of this project, we pledge to respect all people
who contribute through reporting issues, posting feature requests, updating
documentation, submitting pull requests or patches, and other activities.

We are committed to making participation in this project a harassment-free
experience for everyone, regardless of level of experience, gender, gender
identity and expression, sexual orientation, disability, personal appearance,
body size, race, ethnicity, age, or religion.

Examples of unacceptable behavior by participants include the use of sexual
language or imagery, derogatory comments or personal attacks, trolling, public
or private harassment, insults, or other unprofessional conduct.

Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct. Project maintainers who do not follow the
Code of Conduct may be removed from the project team.

This code of conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community.

Instances of abusive, harassing, or otherwise unacceptable behavior can be
reported by emailing [email protected].

This Code of Conduct is adapted from the [Contributor Covenant](https://contributor-covenant.org), version 1.1.0,
available at [https://contributor-covenant.org/version/1/1/0/](https://contributor-covenant.org/version/1/1/0/).
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# OmniAuth::OpenIDConnect

This project was forked from
[m0n9oose/omniauth_openid_connect](https://github.com/m0n9oose/omniauth_openid_connect)
since a number of important bug fixes have not been merged in the past year.

Originally was [omniauth-openid-connect](https://github.com/jjbohn/omniauth-openid-connect)

I've forked this repository and launch as separate gem because maintaining of original was dropped.
Expand All @@ -10,7 +14,7 @@ I've forked this repository and launch as separate gem because maintaining of or

Add this line to your application's Gemfile:

gem 'omniauth_openid_connect'
gem 'gitlab-omniauth-openid-connect', require: 'omniauth_openid_connect'

And then execute:

Expand All @@ -19,7 +23,7 @@ And then execute:
Or install it yourself as:

$ gem install omniauth_openid_connect

## Supported Ruby Versions

OmniAuth::OpenIDConnect is tested under 2.4, 2.5, 2.6, 2.7
Expand Down Expand Up @@ -62,6 +66,8 @@ config.omniauth :openid_connect, {
| post_logout_redirect_uri | The logout redirect uri to use per the [session management draft](https://openid.net/specs/openid-connect-session-1_0.html) | no | empty | https://myapp.com/logout/callback |
| uid_field | The field of the user info response to be used as a unique id | no | 'sub' | "sub", "preferred_username" |
| client_options | A hash of client options detailed in its own section | yes | | |
| jwt_secret | For HMAC with SHA2 (e.g. HS256) signing algorithms, specify the secret used to sign the JWT token. Defaults to the OAuth2 client secret if not specified. For secrets in binary, use `jwt_secret_base64`. | no | client_options.secret | "mysecret" |
| jwt_secret_base64 | For HMAC with SHA2 (e.g. HS256) signing algorithms, specify the base64-encoded secret used to sign the JWT token. Defaults to the OAuth2 client secret if not specified. `jwt_secret` takes precedence. | no | client_options.secret | "bXlzZWNyZXQ=\n"

### Client Config Options

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,31 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'omniauth/openid_connect/version'

Gem::Specification.new do |spec|
spec.name = 'omniauth_openid_connect'
spec.name = 'gitlab-omniauth-openid-connect'
spec.version = OmniAuth::OpenIDConnect::VERSION
spec.authors = ['John Bohn', 'Ilya Shcherbinin']
spec.email = ['[email protected]', '[email protected]']
spec.summary = 'OpenID Connect Strategy for OmniAuth'
spec.description = 'OpenID Connect Strategy for OmniAuth.'
spec.homepage = 'https://github.com/m0n9oose/omniauth_openid_connect'
spec.homepage = 'https://gitlab.com/gitlab-org/gitlab-omniauth-openid-connect'
spec.license = 'MIT'

spec.files = `git ls-files -z`.split("\x0")
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ['lib']

spec.add_dependency 'addressable', '~> 2.5'
spec.add_dependency 'addressable', '~> 2.7'
spec.add_dependency 'omniauth', '~> 1.9'
spec.add_dependency 'openid_connect', '~> 1.1'
spec.add_dependency 'openid_connect', '~> 1.2'
spec.add_development_dependency 'coveralls', '~> 0.8'
spec.add_development_dependency 'faker', '~> 1.6'
spec.add_development_dependency 'faker', '~> 2.17'
spec.add_development_dependency 'guard', '~> 2.14'
spec.add_development_dependency 'guard-bundler', '~> 2.2'
spec.add_development_dependency 'guard-bundler', '~> 3.0'
spec.add_development_dependency 'guard-minitest', '~> 2.4'
spec.add_development_dependency 'minitest', '~> 5.1'
spec.add_development_dependency 'mocha', '~> 1.7'
spec.add_development_dependency 'rake', '~> 12.0'
spec.add_development_dependency 'rubocop', '~> 0.63'
spec.add_development_dependency 'simplecov', '~> 0.12'
spec.add_development_dependency 'minitest', '~> 5.14'
spec.add_development_dependency 'mocha', '~> 1.12'
spec.add_development_dependency 'rake', '~> 13.0'
spec.add_development_dependency 'rubocop', '~> 1.12'
spec.add_development_dependency 'simplecov', '~> 0.16'
end
2 changes: 1 addition & 1 deletion lib/omniauth/openid_connect/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

module OmniAuth
module OpenIDConnect
VERSION = '0.3.5'
VERSION = '0.9.1'.freeze
end
end
95 changes: 86 additions & 9 deletions lib/omniauth/strategies/openid_connect.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require 'addressable/uri'
require 'base64'
require 'timeout'
require 'net/http'
require 'open-uri'
Expand Down Expand Up @@ -36,7 +37,9 @@ class OpenIDConnect

option :issuer
option :discovery, false
option :client_signing_alg
option :client_signing_alg # Deprecated since we detect what is used to sign the JWT
option :jwt_secret
option :jwt_secret_base64
option :client_jwk_signing_key
option :client_x509_signing_key
option :scope, [:openid]
Expand Down Expand Up @@ -65,6 +68,7 @@ def uid
{
name: user_info.name,
email: user_info.email,
email_verified: user_info.email_verified,
nickname: user_info.preferred_username,
first_name: user_info.given_name,
last_name: user_info.family_name,
Expand Down Expand Up @@ -177,13 +181,35 @@ def authorize_uri
end

def public_key
return config.jwks if options.discovery
@public_key ||= begin
if options.discovery
config.jwks
elsif configured_public_key
configured_public_key
elsif client_options.jwks_uri
fetch_key
end
end
end

key_or_secret
# Some OpenID providers use the OAuth2 client secret as the shared secret, but
# Keycloak uses a separate key that's stored inside the database.
def secret
options.jwt_secret || base64_decoded_jwt_secret || client_options.secret
end

private

def base64_decoded_jwt_secret
return unless options.jwt_secret_base64

Base64.decode64(options.jwt_secret_base64)
end

def fetch_key
@fetch_key ||= parse_jwk_key(::OpenIDConnect.http_client.get_content(client_options.jwks_uri))
end

def issuer
resource = "#{ client_options.scheme }://#{ client_options.host }"
resource = "#{ resource }:#{ client_options.port }" if client_options.port
Expand Down Expand Up @@ -225,8 +251,62 @@ def access_token
@access_token
end

# Unlike ::OpenIDConnect::ResponseObject::IdToken.decode, this
# method splits the decoding and verification of JWT into two
# steps. First, we decode the JWT without verifying it to
# determine the algorithm used to sign. Then, we verify it using
# the appropriate public key (e.g. if algorithm is RS256) or
# shared secret (e.g. if algorithm is HS256). This works around a
# limitation in the openid_connect gem:
# https://github.com/nov/openid_connect/issues/61
def decode_id_token(id_token)
::OpenIDConnect::ResponseObject::IdToken.decode(id_token, public_key)
decoded = JSON::JWT.decode(id_token, :skip_verification)
algorithm = decoded.algorithm.to_sym

keyset =
case algorithm
when :HS256, :HS384, :HS512
secret
else
public_key
end

decoded.verify!(keyset)
::OpenIDConnect::ResponseObject::IdToken.new(decoded)
rescue JSON::JWK::Set::KidNotFound
# If the JWT has a key ID (kid), then we know that the set of
# keys supplied doesn't contain the one we want, and we're
# done. However, if there is no kid, then we try each key
# individually to see if one works:
# https://github.com/nov/json-jwt/pull/92#issuecomment-824654949
raise if decoded&.header&.key?('kid')

decoded = decode_with_each_key!(id_token, keyset)

raise unless decoded

decoded

end

def decode!(id_token, key)
::OpenIDConnect::ResponseObject::IdToken.decode(id_token, key)
end

def decode_with_each_key!(id_token, keyset)
return unless keyset.is_a?(JSON::JWK::Set)

keyset.each do |key|
begin
decoded = decode!(id_token, key)
rescue JSON::JWS::VerificationFailed, JSON::JWS::UnexpectedAlgorithm, JSON::JWS::UnknownAlgorithm
next
end

return decoded if decoded
end

nil
end

def client_options
Expand Down Expand Up @@ -262,11 +342,8 @@ def session
super
end

def key_or_secret
case options.client_signing_alg
when :HS256, :HS384, :HS512
client_options.secret
when :RS256, :RS384, :RS512
def configured_public_key
@configured_public_key ||= begin
if options.client_jwk_signing_key
parse_jwk_key(options.client_jwk_signing_key)
elsif options.client_x509_signing_key
Expand Down
1 change: 0 additions & 1 deletion test/fixtures/id_token.txt

This file was deleted.

Loading