ccrockett / omniauth-keycloak Goto Github PK
View Code? Open in Web Editor NEWKeycloak Strategy for OmniAuth.
License: MIT License
Keycloak Strategy for OmniAuth.
License: MIT License
I use the path helper [:scope]_[:provider]_omniauth_authorize_path to redirect to my keylcoak (OAuth2/OpenIDConnect) auth service.
To set the UI language on the auth login page, one can either set an Accept-Language http header or add a query parameter to the endpoint's url.
I wonder, if there is any way to pass query parameters and/or headers to the authorization request via the url helper. I found out, that one can do something like user_keycloakopenid_omniauth_authorize_path(ui_locale: 'en'), but this does add the parameter to the redirect_uri, not to the top level request url.
Hi! Do you guys plan to update the dependencies so OpenSSL 3 can be used? From what I could make out, only json-jwt
would need to be updated.
Cheers
Mentioning this here as a patch for CVE-2023-51774 / [GHSA-c8v6-786g-vjx6] has been released to address this vulnerability by json-jwt folks.
The gem json-jwt has security issues. This was already handled in 47a003b. But that change is not released yet. Could you please do that?
I think the during the test mode setup phase should skip fetching the Keycloak configuration, so when testing you don't need to rely upon having a running Keycloak instance somewhere. This now makes it quite hard to test this omniauth strategy because of this requirement.
I haven't looked at other omniauth strategies what they do but according to omniauth testing wiki page. Omniauth is just supposed to redirect the user to the callback url with the mocked result. Now because of this external config fetch request, testing the callback behavior is harder than it needs to be I think.
I'm on the right track with this? I'd happy to make a PR about this.
EDIT:
I actually managed to test the login with the browser by mocking the keycloak configuration and certs api locally with WebMock. Either way I think code should not make external requests in test mode.
Hi,
first of all thanks for this gem.
I just create a new rails 6.1 project and first thing to me is to get auth working.. so there is nothing installed except this gem plus its dependencies..
i have configured this initializer:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :keycloak_openid, 'xxxCLIENTxxx', 'xxxKEYxxx',
client_options: {site: 'https://auth.xxxDOMAINxxx.com', realm: 'xxxREALMxxx'}
end
this route:
post '/auth/:provider/callback', to: 'sessions#create'
and just for testing a quick and dirty
<%= button_to 'Sign In', '/auth/keycloak_openid' %>
to get the ball rolling.. i click on it and get this No route matches [POST] "/auth/keycloak_openid"
error.
however, Omniauth is present and its config suggests the keycloak_openid
provider is too:
i also gave auth/keycloak
a shot (yeah, proly made no sense, but just in case)... - same thing
idk what i did wrong here, maybe its a bug (with rails 6.1)..(?)
Hi,
When an error occurs in setup_phase (Keycloak is down for exemple), the server is crashing because of the exception at thise line:(Faraday::ConnectionFailed)
response = Faraday.get config_url
This function set_up phase is called from omniauth gem, not from the server directly
How can we catch it from the server to prevent the crash and to handle the error , please ?
Thanks for any suggesion.
Hi,
This gem has been extremely helpful, but I'm missing a major piece to complete my implementation.
My use-case is a multi tenant approach, where the Realm and Client are expected to change.
I'm using this gem alongside of Devise and this line of devise.rb
is loaded loaded only once when the application starts
config.omniauth :keycloak_openid, "Example-Client-Name", "example-secret-if-configured", client_options: { site: "https://example.keycloak-url.com", realm: "example-realm" }, :strategy_class => OmniAuth::Strategies::KeycloakOpenId
I'm forced to have a single client in this case.
Is there a possibility where I can dynamically configure the Client and Realm per request?
Any pointers on how to go about this would be really helpful.
Thanks
I'm using omniauth-keycloak with devise in a rails + react project and I have keycloak omniauth hooked up successfully for regular login/signup. I'm trying to add it to the devise invitation flow and am running into an issue passing the invitation_token
so it is accessible in the omniauth callback endpoint.
I added the param into authorize_options
and passed it as a hidden input in the form as per #24 but this doesn't seem to do anything to the callback request. I'm not sure if I'm misunderstanding the feature or if there is something wrong with the config.
I also tried passing the param directly in the form action e.g. action={'/auth/keycloak?invitation_token=${token}'}
but this causes an Incorrect redirect_uri
error in the callback phase, presumably due to the invitation_token
in the query params. The keycloak integration redirect uri is set to http://localhost:3000/*
Relevant code:
# config/initializers/devise.rb
config.omniauth :keycloak_openid,
ENV["KEYCLOAK_CLIENT"],
ENV["KEYCLOAK_SECRET"],
client_options: {
site: ENV["KEYCLOAK_AUTH_URL"],
realm: "standard",
},
authorize_options: [:invitation_token],
name: :keycloak,
strategy_class: OmniAuth::Strategies::KeycloakOpenId
// form.tsx
<form action={`/api/auth/keycloak`} method="post">
<Input hidden={true} name="invitation_token" value={invitationToken} />
<input
type="hidden"
name="authenticity_token"
value={document.querySelector("[name=csrf-token]").content}
/>
<Button type="submit">Login</Button>
</form>
Hello all, I'm getting this invalid JSON format error. Since my app's ruby version is 2.2.2 I'm using gem 'omniauth-keycloak', '~> 1.1' version. After logging via keycloak I'm able to get the authorization_code using that ID token and the refresh token are also fetched. When I debugged this further, this error is happening at this point.
header, claims, signature = input.split('.', JWS::NUM_OF_SEGMENTS).collect do |segment|
Base64.urlsafe_decode64 segment.to_s
end
**This is the setup that I used for my app.**
gem 'omniauth', '~> 1.9.0'
gem 'omniauth-oauth2', '~> 1.6.0'
gem 'omniauth-keycloak', '~> 1.1'
gem 'json-jwt', '~> 1.9.4'
**Backtrace**
(keycloakopenid) Callback phase initiated.
"/usr/local/rvm/gems/ruby-2.2.2/gems/json-jwt-1.9.4/lib/json/jose.rb:66:in `rescue in decode'",
"/usr/local/rvm/gems/ruby-2.2.2/gems/json-jwt-1.9.4/lib/json/jose.rb:60:in `decode'",
"/usr/local/rvm/gems/ruby-2.2.2/gems/omniauth-keycloak-1.1.0/lib/omniauth/strategies/keycloak-openid.rb:70:in `raw_info'",
Hi, thanks for the amazing omniauth keycloak integration you've put on this gem!
When I'd to test some example apps with a demo keycloak instance, my keycloak instance return multiple certificate keys and I've trouble on the following code:
omniauth-keycloak/lib/omniauth/strategies/keycloak-openid.rb
Lines 47 to 51 in 6813692
Are there any reason to specify it?
In keycloak 17.0.0 and afterwards they have removed the support for redirect_uri
on logout request. They suggest the usage of
post_logout_redirect_uri
and id_token_hint
. To use the RP initiated logout we therefore require the id_token
. Unfortunately after digging around quite a bit, I found out that id_token
is not exposed in the auth hash in omniauth-keycloak. the access_token.token is exposed , but the access_token['id_token'] is not exposed. By passing scope: 'openid'
this id_token is available inside access_token['id_token']. Without this id_token
it is not possible to use the RP initiated logout feature of keycloak. Do you think it is possible to expose this id_token
inside the extra hash?
Or maybe there is already a hidden configuration that I am missing?
Hi,
I am facing an issue with omniauth_keycloak.
Below i have sample test url ->
https://test_url.com/users/auth/keycloakopenid/callback?state=c19b6e7dff2fa008b87d0a726daa3a&session_state=da4ba031-dd24-4374-bb2b-6fda3e9045a8&code=ec954250-f1c25-ed86c846b2a6.da4ba031-dd24-4374-bb2b-6fda3e9041cfe-c933-4e16-896a-f0c04758815a
After adding my keycloak sso details I am getting below error logs
{"@timestamp": "2023-07-03T08:08:03.377+0000","@Version":"1","log_type":"LOG","log_level":"INFO","level_value":20000,"logger_name":"org.slf4j.impl.StaticLoggerBinder","service_name":"cdt-cdt","artifact_id":"NOT_SET","trace_token":"undefined","thread_name":"scala-execution-context-global-26","message": "Reconfiguring Qlogger"}
We got a solution for this issue. But we didn't understand where we need to do the changes.
the solution is we need to sort the "use" values in the keys list.
If use value as 'enc' and it is coming first into the keys list then we are getting the issue. or else it is working fine.
Could please suggest where we need to sort the below keys like rails(devise.rb file)application level or in gem (https://github.com/ccrockett/omniauth-keycloak/blob/master/lib/omniauth/strategies/keycloak-openid.rb) this page?
{
"keys": [{
"kid": "uaC38HXBBhkgaEjKavC9t0SQTTM",
"kty": "RSA",
"alg": "RS256",
"use": "enc",
"n": "xn1E1P-ceqpSLEyY7PdInW6peF5cC3DCYkch5u8ckUEJ-IwCZtzIypVhagNuRYxN0XSoYi6SL0oL83su6o_lHjKDkC5y5w",
"e": "AQAB",
"x5c": ["MIICnttG+ApMjcgq2vuQT+w=="],
"x5t": "SgLLN3V0WIISSF6I",
"x5t#S256": "OX6FsNccV2uaiKTm4b9lQju6EelZY"
}, {
"kid": "6-p2qQ_LRKc5PtYvQrysDhrUzIc",
"kty": "RSA",
"alg": "RSA-OAEP",
"use": "sig",
"n": "YN-3eOq3w6uVHWt0UkKAdIjMvkjUjjMj_DhQOqJepgWwsVThJ8IJw",
"e": "AQAB",
"x5c": ["MIICnTCCWZFxJrzndobBsTlmspxpRZotxR4LZJr6B6srzxjpuQw7jmGAl8/VQzEreDAnxCWafydCCv04lQ=="],
"x5t": "BVUvObKSA6v4TMtoMI",
"x5t#S256": "4wby9rmzuPmxIONg7TGCU"
}]
}
I noticed the version 1.5.1 of this gem added this #24 change. This change added request_phase
method here. However what this is doing for me is that it's overwriting scope
that I have set when configuring the provider like this:
provider(:keycloak_openid,
"client_id",
"client_secret",
name: "keycloak",
scope: "openid", # <-- this line here!!!
client_options: {
# Base url as empty, defaults to "/auth/..." base url.
base_url: "", site: "keycloak_url_here", realm: "test_realm"
})
What is basically happening is the request_phase
method is overwriting my scope
with nil
instead of "openid"
. This in turn causes Keycloak not to return ID token for me anymore.
I could provide a fix for this but not sure if I'm setting the scope correctly. Or could this be fixed in the gem to conditionally set value from request.params
if it's nil? Maybe something along these lines:
def request_phase
options.authorize_options.each do |key|
options[key] = request.params[key.to_s] if options[key].nil?
end
super
end
With Keycloak 17 "/auth" was removed from all endpoints. Thus, endpoints as http://localhost:8080/auth/realms/fdz/protocol/openid-connect/auth
have changed to http://localhost:8080/realms/fdz/protocol/openid-connect/auth
.
See upgrading guide:
https://www.keycloak.org/docs/latest/upgrading/index.html
Workaround is to use the --http-relative-path '/auth'
option with the keycloak start command
To be integrated at corporate level, my RoR 5.2.4 application needs a new authentication provider: Keycloak.
Here, the Keycloak server URL to retrieve configuration information is: https://identity-a.bit.admin.ch/realms/bfs-sis-a
Which should correspond to the following configuration in config/inititalizers/devise.rb:
config.omniauth :keycloak_openid,
"BFS.SIS",
client_options: { site: "https://identity-a.bit.admin.ch", realm: "bfs-sis-a" },
strategy_class: OmniAuth::Strategies::KeycloakOpenId
Unfortunately, the configuration request issued by my application fails, as it is visible in this trace:
Started POST "/users/auth/keycloakopenid" for 127.0.0.1 at 2021-11-22 16:29:35 +0100
D, [2021-11-22T16:29:35.599250 #9892] DEBUG -- omniauth: (keycloakopenid) Going to get Keycloak configuration. URL: https://identity-a.bit.admin.ch/auth/realms/bfs-sis-a/.well-known/openid-configuration
E, [2021-11-22T16:29:35.667631 #9892] ERROR -- omniauth: (keycloakopenid) Keycloak configuration request failed with status: 404. URL: https://identity-a.bit.admin.ch/auth/realms/bfs-sis-a/.well-known/openid-configuration
D, [2021-11-22T16:29:35.667881 #9892] DEBUG -- omniauth: (keycloakopenid) Request phase initiated.
As you can see, the requested URL differs by the "/auth/" part, that seems to belong to the default URL of Keycloak. But our dedicated server's configuration appears to be different.
Reading the code of the gem, I see that this URL element cannot be changed.
Can you please let me know if my analysis is correct, and if we have a solution?
Thanks a lot!
Why did the auth/keycloak route switch to post and whats the inteded functionality now? (I upgraded from 1.2 to 1.4)
Maybe I got the concept wrong, but I am using this route with redirect_to, which is not possible now anymore.
Could someone enlighten me?
If there is any demand for that, and I am not the only only one with this issue, I could add it to the readme afterwards.
Thanks a lot for the great gem and the help!
Hi!
I have this gem
Using oauth2 1.4.4
Using omniauth 1.9.1
Using omniauth-oauth2 1.6.0
Using omniauth-keycloak 1.2.0
Also I did bundle and bundle install but I get this error:
Traceback (most recent call last):
49: from bin/rails:3:in <main>' 48: from bin/rails:3:in
load'
47: from /Users/catalinarojas/portal-backend/bin/spring:15:in <top (required)>' 46: from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'
45: from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in require' 44: from /Library/Ruby/Gems/2.6.0/gems/spring-2.1.0/lib/spring/binstub.rb:11:in
<top (required)>'
43: from /Library/Ruby/Gems/2.6.0/gems/spring-2.1.0/lib/spring/binstub.rb:11:in load' 42: from /Library/Ruby/Gems/2.6.0/gems/spring-2.1.0/bin/spring:49:in
<top (required)>'
41: from /Library/Ruby/Gems/2.6.0/gems/spring-2.1.0/lib/spring/client.rb:30:in run' 40: from /Library/Ruby/Gems/2.6.0/gems/spring-2.1.0/lib/spring/client/command.rb:7:in
call'
39: from /Library/Ruby/Gems/2.6.0/gems/spring-2.1.0/lib/spring/client/rails.rb:28:in call' 38: from /Library/Ruby/Gems/2.6.0/gems/spring-2.1.0/lib/spring/client/rails.rb:28:in
load'
37: from /Users/catalinarojas/portal-backend/bin/rails:9:in <top (required)>' 36: from /Library/Ruby/Gems/2.6.0/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:291:in
require'
35: from /Library/Ruby/Gems/2.6.0/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:257:in load_dependency' 34: from /Library/Ruby/Gems/2.6.0/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:291:in
block in require'
33: from /Library/Ruby/Gems/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in require' 32: from /Library/Ruby/Gems/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in
require_with_bootsnap_lfi'
31: from /Library/Ruby/Gems/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in register' 30: from /Library/Ruby/Gems/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in
block in require_with_bootsnap_lfi'
29: from /Library/Ruby/Gems/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in require' 28: from /Library/Ruby/Gems/2.6.0/gems/railties-5.2.4.3/lib/rails/commands.rb:18:in
invoke' 26: from /Library/Ruby/Gems/2.6.0/gems/railties-5.2.4.3/lib/rails/command/base.rb:69:in
perform'dispatch' 24: from /Library/Ruby/Gems/2.6.0/gems/thor-1.0.1/lib/thor/invocation.rb:127:in
invoke_command'run' 22: from /Library/Ruby/Gems/2.6.0/gems/railties-5.2.4.3/lib/rails/commands/server/server_command.rb:142:in
perform'tap' 20: from /Library/Ruby/Gems/2.6.0/gems/railties-5.2.4.3/lib/rails/commands/server/server_command.rb:145:in
block in perform'require' 18: from /Library/Ruby/Gems/2.6.0/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:257:in
load_dependency'block in require' 16: from /Library/Ruby/Gems/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in
require'require_with_bootsnap_lfi' 14: from /Library/Ruby/Gems/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in
register'block in require_with_bootsnap_lfi' 12: from /Library/Ruby/Gems/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in
require'<main>' 10: from /Library/Ruby/Gems/2.6.0/gems/bundler-2.0.2/lib/bundler.rb:114:in
require'require' 8: from /Library/Ruby/Gems/2.6.0/gems/bundler-2.0.2/lib/bundler/runtime.rb:65:in
each'block in require' 6: from /Library/Ruby/Gems/2.6.0/gems/bundler-2.0.2/lib/bundler/runtime.rb:76:in
each'block (2 levels) in require' 4: from /Library/Ruby/Gems/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in
require'require_with_bootsnap_lfi' 2: from /Library/Ruby/Gems/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in
register'block in require_with_bootsnap_lfi' /Library/Ruby/Gems/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in
require': cannot load such file -- /Library/Ruby/Gems/2.6.0/gems/omniauth-keycloak-1.2.0/lib/omniauth-keycloak.rb (LoadError)The line https://github.com/ccrockett/omniauth-keycloak/blob/master/omniauth-keycloak.gemspec#L27C1-L27C52 is preventing us from using omniauth-oauth2 1.8.0.... Can we update this?
I am currently trying to get this to work with a fresh Keycloak, and am struggling the the Keycloak configuration.
I suspect I am missing something.
It would be nice to have an example configuration for Keycloak
My pplication is running on Ruby 2.7 / Rails 5.2.4 on Windows 10 and SUSE (SLES 15.SP3).
It uses Devise for authentication, with omniauth-keycloak, which worked fine for several months.
This morning I had tu run "bundle update" for an unrelated subject. After this update, invoking the link to Keycloak remote server for authentication issues the following error:
DEBUG -- omniauth: (keycloakopenid) Going to get Keycloak configuration. URL: https://identity-a.manage.ch/realms/bfs-sis-a/.well-known/openid-configuration
E, [2022-07-19T08:57:43.384693 #13364] ERROR -- omniauth: (keycloakopenid) Authentication failure! uninitialized constant OmniAuth::Strategies::KeycloakOpenId::MultiJson: NameError, uninitialized constant OmniAuth::Strategies::KeycloakOpenId::MultiJson
Processing by Users::OmniauthCallbacksController#failure as HTML
And redirects to the sign-in page.
The OmniAuth::Strategies::KeycloakOpenId::MultiJson constant does not exist in the project indeed.
The closest constant OmniAuth::Strategies::KeycloakOpenId i used in the devise.rb initializer:
config.omniauth :keycloak_openid,
"BFS.SIS",
client_options: { base_url: '', site: Rails.application.credentials.integration[:authentication_url], realm: "bfs-sis-a" },
strategy_class: OmniAuth::Strategies::KeycloakOpenId
Installed gem versions are:
How could I solve this issue?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.