Keycloak client baseurl is not accepting url without http - keycloak

I am developing react app. And keeping keycloak for signup. After completing signup keycloak is triggering an email for email verification. When the user verify I want to redirect that verified user to this url e.g. com.abcd.xyzApp/(My app). But I am not able to set this URL(com.abcd.xyzApp/) in keycloak baseurl without http. Getting error "Error! Base URL is not a valid URL"
Is there any solution? Thanks

This should work by using the redirect_uri query parameter when initiating the login. However, this redirect_uri param is lost in case email verification gets triggered.
I already filed a ticket for this a while ago (see KEYCLOAK-16860).
You may want to redirect to a custom http(s) endpoint and initiate an app specific redirect from there as mentioned here.

Related

What is the proper way to invoke Keycloak's end_session_endpoint

Environment: Keycloak 12.0.4
We plan to allow various OpenIDC-protected applications to initiate a "single sign-out" using Keycloak's end_session_endpoint. In our case, we'd like to provide our own URL that applications will hit when they want to sign-out. That URL will either programmatically invoke the end_session_endpoint or simply redirect the user's browser to that endpoint.
The Keycloak documentation and examples I've seen so far are a bit confusing regarding how to invoke this endpoint. For example, do I need to add a query parameter with the id token as a value? (I noticed, for example, that mod_auth_openidc includes an id_token_hint query param.) I assume this call has to be authenticated, so do I include the client id/secret as the credentials?
Thanks!
You have standard how to call RP-Initiated Logout:
https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout
An RP requests that the OP log out the End-User by redirecting the End-User's User Agent to the OP's Logout Endpoint.
It is a redirect, not API call, because you very likely wants to delete also IDP session (cookies on used Keycloak domain in your case).
Here's some additional information from the keycloak-user group which I think completely answers the question:
You can look at
https://openid.net/specs/openid-connect-session-1_0-17.html#RPLogout.
From our implementation, we rely on either cookies or the
id_token_hint to identify the user and logout sessions. So you don't
necessarily need to send id_token_hint if cookies are sent when
redirecting the user from your application to Keycloak. You can also
send a state param to match if the logout action sent to your
application originated from a valid logout request.
Note, however, that we don't force the id_token_hint and do not ask
the user for confirmation, as per spec. But there are discussions to
introduce a consent page.
In regards to logout, messages are sent to clients through the
backchannel.
Edit: Here's the actual (latest) RP-initated logout spec: https://openid.net/specs/openid-connect-rpinitiated-1_0.html.
The logout URL needs to be build from
the OpenID Connect end session endpoint
a target redirect URI where the user should be sent after logout, provided as query param post_logout_redirect_uri
The encoded ID token as query param id_token_hint
In Spring it can be built like this:
String logoutLink = UriComponentsBuilder.fromUri(endSessionEndpoint)
.queryParam("post_logout_redirect_uri", logoutUrlEncoded)
.queryParam("id_token_hint",
((OidcUser) authentication.getPrincipal()).getIdToken().getTokenValue())
.build().toUriString();

Facebook OAuth security using passport-facebook

I am currently using a client-side React component to have a user login to Facebook via OAuth in my application. On the server-side, I use the npm package passport-facebook-token to validate the authenticity of the accessToken after a successful client-side login.
One practice I do not see often is in addition to asking Facebook if the accessToken is valid, shouldn't the server also check if the email provided by the client's payload matches the e-mail coming back from Facebook? Allow me to use defined client/server technologies to illustrate my question:
1) User uses React component on the client to authenticate with Facebook.
2) React component successfully authenticates with Facebook and fires an HTTP request to the server with an access token and the user's email.
3) The server, running Node.JS and passport-facebook, now needs to verify the authenticity of the access token directly from Facebook. Facebook does not care for an e-mail. It will just verify the access token.
4) Facebook returns a response to Node.js confirming the authenticity of the access token. The response also contains other metadata about the user, including their email and other profile data.
My question is, should Node.js take the email that's also coming back from Facebook's access token verification payload, and verify that it is what came back from the React client? Would this not prevent someone from brute-forcing an accessToken and require them to not only have an accessToken but also know who the accessToken belongs to? This could prevent a user from submitting a bunch of HTTP POST requests to the Node.js server attempting different access tokens. They would not only have to guess an access token assigned to the application's clientID, but also know the e-mail it belongs to. Is this an over-engineered approach?
Really the best way I can think of to make your OAuth accessToken and 'code' value less prone to brute-forcing is using a Cryptographic Number Generator to create a 128-bit length string of random data and encoding it with base 64 to use as your code. It's extremely unlikely that it would be guessed by a computer or by someone redirecting to and from the authorization endpoint and the redirect-uri with query parameters.
Another method of fortification is limiting the rate of authorizations by IP address (which you can do instead of email through Node.js) but that is usually not a problem for most well-equipped hackers. I highly advise the first method for creating a more secure service.
Your approach to validate the email as well as the token is a bit superfluous because Facebook's opaque user access tokens are inherently tied to email.
From Facebook
An access token is an opaque string that identifies a user, app, or Page
"opaque" is defined by Auth0 here
Opaque Access Tokens are tokens in a proprietary format that typically contain some identifier to information in a server’s persistent storage
In your case, the identifier is the user's email, and the server belongs to Facebook.
I will elaborate further. Here is your step by step with some edits:
User uses React component on the client to authenticate with Facebook, inputting both their email and password directly to Facebook. React component gets the token from Facebook on login success.
React component successfully authenticates with Facebook and fires an HTTP request to the server with an access token and the user's email.
The server, running Node.JS and passport-facebook, now needs to verify the authenticity of the access token directly from Facebook. Facebook does not care for an e-mail. It will just verify the access token because the access token is already tied to the email.
Facebook returns a response to Node.js confirming the authenticity of the access token. The response also contains other metadata about the user, including their email and other profile data.
This is Facebook's bug bounty program. If their OAuth was really as cracked as to require a second email validation, it would have been patched almost immediately by this incentive.

Why google-oauth API requires redirect-url?

I'm trying to set up an authorization flow with google-oauth2 API.
The task is to authorize users with google accounts in my web-application which consists of frontend and backend parts.
The flow according to the documentation consists of 2 steps:
1) obtaining an auth code
2) exchanging an auth code for a token
In my flow, FE client obtains an auth code from google and submits it to BE, which then exchanges it for a token, so no redirect URL (or sometimes called callback URL) is used.
I do not understand why google API requires me to provide redirect_uri for the second step? Since this step is performed by a server, not a browser, I don't see any sense in this piece of info. The server just calls the POST /oauth2/v4/token google endpoint and receives token in response.
see step 4 at https://developers.google.com/identity/protocols/OpenIDConnect
According to this, it's to guard against stealing the access_token. If a service doesn't check the initial redirect_uri, the authorization code is sent to the hacker's redirect_uri, which can then exchange it for an access_token, i.e. illegal access to the user's account. To actually get the access_token, the redirect_uri is specified again and this time must be checked by the server against the ones that are registered for that application. At that point, the hacker is foiled as the fake redirect_uri doesn't match any of the legal ones. Apparently some servers don't check the redirect_uri during the authorization stage and sending the redirect_uri again when requesting the access_token is meant to provide a final safey check.

What is the real purpose of Redirect_Uri in OpenIdConnect?

I am trying to setup OpenID Connect Authentication (Single-tenanted) for my web application. I understand how Reply Url in AAD is supposed to work. AAD admin registers a web application with SignInUrl, ReplyUri, AppIdUri,.. Microsoft AAD handles the complete user experience to prompt & validate the credentials. An attacker may not be able to pose legitimate site attack (since it is *.microsoftonline.com page).
Questions:
What is the real purpose of Redirect_Uri in OpenIdConnect? Does it fight Redirect_Uri Attack?
I tried to send different Redirect_Uri from web client. Microsoft AAD fails by reply urls do not match error. But while refreshing the web application, it is signed in now. Should AAD not invalidate my attempt of logging in with illegitimate redirect uri?
Please suggest me how to view Redirect Uri. I would like to harness the real benefit.
What is the real purpose of Redirect_Uri in OpenIdConnect?
From the OpenID Connect, 3.1.2.1 Authentication Request:
redirect_uri
REQUIRED. Redirection URI to which the response will be sent.
This URI MUST exactly match one of the Redirection URI values
for the Client pre-registered at the OpenID Provider [...]
So, the purpose of redirect_uri is to tell the OpenID Provider (Azure AD, in your case) where the response to the request should be sent, after the user signs in.
Does it fight Redirect_Uri Attack?
The parameter itself offer the functionality described above, it doesn't mitigate any attack. It is the responsibility of the client (i.e. your app) and the OpenID Provider (i.e. Azure AD) to ensure they are doing the right thing to prevent exposing the risk of an attack (including an attack related to redirections).
For example, if an OpenID Provider did not validate that the redirect_uri from the request exactly matches a redirection URI configured for the client, then an attacker might be able to construct an authorization request with a redirect_uri pointing to a URL controlled by the attacker, and then trick a user into triggering the request. The response to the request would then be sent to the attacker, rather than to the relying party the user thinks they're signing in to.
There are other attacks related to redirect_uri which could happen if the relying party (i.e. your app, in this case) exposed a vulnerability (for example, by enabling an open redirection attack, or by authorizing a reply URL which is not actually in your control).
Many of these (and other) attacks, as well as the current best practices to mitigate or prevent them, are described in OAuth 2.0 Security Best Current Practice.
I tried to send different Redirect_Uri from web client. Microsoft AAD fails by reply urls do not match error. But while refreshing the web application, it is signed in now. Should AAD not invalidate my attempt of logging in with illegitimate redirect uri?
This seems like there is an issue in your application. When Azure AD detects that the requested redirect_uri does not exactly match an authorized reply URI for the client, Azure AD does not redirect back to the client with an authorization code or any tokens.
It is possible that your app had already established a session previously, or is incorrectly processing the OpenID Connect flow. It's impossible to say without knowing the specific details of how the app is implemented.
Now I think I found the mystery behind the signin-redirect_uri anomalies.
Questions:
What is the real purpose of Redirect_Uri in OpenIdConnect? Does it fight Redirect_Uri Attack?
[OP] Yes, it does. If redirect_uri domain differs from AAD server Registration and web client, it invalidates the sign-in attempt.
I tried to send different Redirect_Uri from web client. Microsoft AAD fails by reply urls do not match error. But while refreshing the web application, it is signed in now. Should AAD not invalidate my attempt of logging in with illegitimate redirect uri?
[OP] Redirect_Uri does not behave when I hosted my application in localhost even on different ports or same domain. So, it ignores Redirect_Uri validation, if I click on Sign-In despite the first Reply-Uri-Mismatch error.
Please note that Redirect_Uri does handle Open redirect attack if an attacker wants to redirect the victim to illegitimate page for re-entering the credentials.

Okta is returning an invalid redirect uri when connected to IdentityServer 3 and performing sign out

I'm trying to integrate Okta as a third party Identity Provider for a system I am working on that is using the IdentityServer 3 framework to support my customers that use Okta. I have everything working great except log out. When a user logs out of my system, it initiates the end session call back to Okta to log the user out. My problem is that the Identity Server is sending a session id along with the post logout redirect uri for context, but Okta refuses to accept the redirect uri because it is not known. I've tried multiple variations in the setup in Okta for this url but because the id value is dynamic, i'm not able to specify an exact url. Is there a way to have it support any urls that are going to a specific hostname or even up to the page path? I've tried adding my host into the API security area for trusted origins but it did not work either. I've also tried overriding the postback url for my system to be a static page, but then the IdentityServer Signout message cookie is never cleaned up correctly. This same code works without any problems when running for Azure as the IDP. Has anyone run into this before and have any thoughts? Any help is appreciated.
An example of the post to Okta at signout with the postback url is something like this,
https://dev-xx.oktapreview.com/oauth2/default/v1/logout?post_logout_redirect_uri=https%3a%2f%2fmyurl.com%2fidp%2flogout%2f%3fid%3d83617adbc6769e5d4d0fbca4dced3991&max_age=5&id_token_hint=eyJraWQiOiJ1aXJYc1RYTkTVVGenBXU1JfMWt6WndNSXBQQUVqT0dndWhjbloxR3pNIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIwMHU4eTlrajNyT2NreW11cTBoNyIsIm5hbWUiOiJKYW1lcyBSZWFtZXMiLCJsb2NhbGUiOiJlbi1VUyIsImVtYWlsIjoiamFtZXMucmVhbWVzQHJlYWxwYWdlLmNvbSIsInZlciI6MSwiaXNzIjoiaHR0cHM6Ly9kZXYtNDg5MDgyLm9rdGFwcmV2aWV3LmNvbS9vYXV0aDIvZGVmYXVsdCIsImF1ZCI6IjBvYWVvdXMycWFJTWJ3U0dhMGg3IiwiaWF0IjoxNTM2MjQ5NzY2LCJleHAiOjE1MzYyNTMzNjYsImp0aSI6IklELlVUem5sTC1FRUY0aHFoZlNSbG5wV1cyUGRxQzlBRk1PcDZiOTh6UERRUUEiLCJhbXIiOlsicHdkIl0sImlkcCI6IjAwbzh5OWZycXVmOFlpaG50MGg3Iiwibm9uY2UiOiI2MzY3MTg0NjU0NTA1NzI4ODQuWldOaVlqZG1aamt0Wm1Fd01TMDBNVGc1TFRreE4yTXRaR1kzTWpreVl6ZGpOekprTm1GbU16WTJaRFl0TURBeE15MDBNMkUwTFdJM01ERXRNek5oWTJOaU1qZ3daamd4IiwicHJlZmVycmVkX3VzZXJuYW1lIjoiamFtZXMucmVhbWVzQHJlYWxwYWdlLmNvbSIsImdpdmVuX25hbWUiOiJKYW1lcyIsImZhbWlseV9uYW1lIjoiUmVhbWVzIiwiem9uZWluZm8iOiJBbWVyaWNhL0xvc19BbmdlbGVzIiwidXBkYXRlZF9hdCI6MTUyMzYyNjUzMiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImF1dGhfdGltZSI6MTUzNjI0OTc2NiwiY19oYXNoIjoiMWoxa1JTSGhObGRGWGNmSDdCQXRBUSJ9.gvG_8dnlAMr9XI-atCjIKVF04L4oMzerXmeT0BAG76RLle-q2pgb8PDvV4cTicLH16QLzboSgocC6t6WoegbUeJLLuzZHd2rQkm8Y4iRheoV05uKhd2mpLA9LyexlJ9oVJ8Xi_D4BqN_bygphAv79B4L8-Ezz3YgGDmSkK3WutB55_r_7XM0OCCCetvNu4S8KXbKHUxgg5cpQ6y7o-d5eIH6I8bpoOoA0gy7Liwsm7IyQUe5_jdorObgBHIEfDx4mjNRENJUQ7InASwbL7eND7COZYyXRwzn7vHU0_XkBaUW9wsY-VJUaihOwEcgVS1MPbGLoSUY9k0TmcUVN3-Q&state=83617adbc6769e5d4d0fbca4dced3991&x-client-SKU=ID_NET&x-client-ver=1.0.40306.1554
the id=83617... is what is tripping up Okta from trusting the redirect url. I've tried adding all of these combinations of urls into the logout redirect uri setup and none let it accept it,
https://myurl.com/idp/logout/
https://myurl.com/idp/logout/?id=
https://myurl.com/idp/logout?id=
https://myurl.com
https://myurl.com/
https://myurl.com/idp
https://myurl.com/idp/
https://myurl.com/idp/logout
None seem to work.