I am using OpenID Connect in Keycloak as an authentication solution and I've just encountered the following scenario.
Client A sends an authorisation request to the Authorization server and provide redirect_url of client B in that request.
Authorization server authenticate the user and redirect the user to the provided redirect_url(which is for client B) with authentication_code.
Client B communicates with Authorization server with its own client_id and secret and takes its token.
I want to know why OpenID Connect has allowed this
process, is it a normal thing for a client to initiate authentication for another client? Why the issued authentication_code is not bound to the client who has initiated the authentication and why it the authentication_code can be used by other client with other client_id?
Note: I know that validity of redirection_url will be checked in that process but I want to know why authorization code is not bound to client_id itself.
If it's indeed possible in Keycloak then it's a problem of the implementation, not the spec. The Oauth spec in section 4.1.2. indicates this for the authorization code:
The authorization code is bound to the client identifier and redirection URI.
As for the redirect URI it should also be verified and client A should be able to use redirect URI of client B only if that other redirect URI was whitelisted for client A.
The Proof Key for Code Exchange is also something which would prevent such a use of an Oauth flow as you described here.
Related
Assume aim is to authorize access to Resource Server (RS) resource.com/resource via access token but using OpenId Connect for authentication instead of relying on custom authentication integrations of Authorization Server available in OAuth2.
I am not clear how they interoperate, how does the id token feed into subsequent OAuth2 flows in particular.
1.OpenId Connect is implemented as an OAuth2 "authorize access to user profile/identity", but what flow does it use for it?. At this point, The requester (user agent or client app) gets id token and access token to userInfo.
2.But now, identity obtained, an authorization/access token to end service (Resource Server RS) is needed.
What is the next step until the end goal of access token to Resource Server?
Here we have another OAuth2 flow, so that based on identity of user and client the end access token is obtained. I do not have the details of this. I saw detailed presentations of OpenId connect up to the point of having the id token and access token to userInfo and detailed presentation of OAuth2 flows all 4 of them, but never saw an end to end concatenation of these protocols, is there such an integration?
Does the requester send the id token to authorization server together with the request for code or access token directly (depending on the flow)? I never saw an end to end flow, can you indicate a video or text description of it?
Normally, client applications don't send ID tokens to authorization servers. (In the specification, there is a request parameter id_token_hint. But, it should be ignored here to avoid confusion.)
Normally, resource servers require only access tokens. Client applications don't have to send ID tokens to resource servers.
Reading "Diagrams of All The OpenID Connect Flows" may help you.
I'm building a web app that uses the Oauth2.0 protocol. I have registered my app with the authorization server and received my client id and client secret.
I'm now working on Authorization part and specifically using the Authorization Code grant type. In that process i'm sending the user to the authorize endpoint with the following query parameters:code, client_id, redirect_uri, scope and state. (omitting the client_secret)
The problem that i'm dealing with is i'm getting an error back saying I need to provide the client_secret as well.
I was under the impression the client_secret is not needed at this part and shouldn't be sent in this request but rather when the client sends the authorization code (along with id & secret) to obtain the access token.
So my question is, Is it wrong (against oauth 2 protocol) that the authorization server requires the client secret to be sent in the request for the authorization code?
I am not 100% sure of this, but I did some research myself and what I found is that is not a real problem not to keep the "client secret" a secret. The only possibility of someone malicious being able to get through the Authorization specs is prevented by some facts:
1. Client need to get authorization code directly from the user, not from the service
Even if user indicates the service that he/she trusts the client, the
client cannot get authorization code from the service just by showing
client id and client secret. Instead, the client has to get the
authorization code directly from the user. (This is usually done by
URL redirection, which I will talk about later.) So, for the malicious
client, it is not enough to know client id/secret trusted by the user.
It has to somehow involve or spoof user to give it the authorization
code, which should be harder than just knowing client id/secret.
2. Redirect URL is registered with client id/secret
Let’s assume that the malicious client somehow managed to involve the
user and make her/him click "Authorize this app" button on the service
page. This will trigger the URL redirect response from the service to
user’s browser with the authorization code with it. Then the
authorization code will be sent from user’s browser to the redirect
URL, and the client is supposed to be listening at the redirect URL to
receive the authorization code. (The redirect URL can be localhost
too, and I figured that this is a typical way that a “public client”
receives authorization code.) Since this redirect URL is registered at
the service with the client id/secret, the malicious client does not
have a way to control where the authorization code is given to. This
means the malicious client with your client id/secret has another
obstacle to obtain the user’s authorization code.
// copy paste of hideaki answer
Concluding
OAuth2 specify that you need to inform your secret into a request if your application is a server-side based app (different than a single-page application or mobile) which does not make its source code available. However, if you can't control your base code, like in an native mobile application, you should look for another solution.
References
OAuth2 Documentation
Bear similar stack question
Simplifying OAuth2
I'm learning about O Auth 2 from here
I was wondering in the step of "Authorization server redirects user agent to client with authorization code", why doesn't the server just give the access token instead? Why give an authorization code that then is used to get the access token? Why not just give the access token directly? Is it because there there is a different access token for each resource so that you need to go through O Auth again to access a different resource?
The authorization grant code can pass through unsecured or potentially risky environments such as basic HTTP connection (not HTTPS) or a browser. But it's worthless without a client secret. The client can be a backend application. If the OAuth2 server returned a token, it could get compromised.
There is another OAuth2 flow - the Implicit flow, which returns an access token right after the authentication, but it's designed mainly for JavaScript applications or other deployments where it's safe to use it.
If a malicious app gets hold of the client id of your app(which is easily available, for example one can inspect the source), then it can use that to retrieve the token without the use of the client secret. All the malicious app needs to do is to somehow either specify the redirect URI to itself or to tap into the registered redirect URI.
That is the reason for breaking the flow as such. Note, when the client secret is not to be used as in SPA (Single Page Apps) or Mobile Apps, then PKCE comes to the rescue.
There is a reason for breaking up the authorization flow so as to keep the resource owner's interaction with the authorization server isolated from the client's interactions with the authorization server. Therefore we need to have two interactions with the authorization server. One in which the resource owner authenticates with it's credentials to the authorization server. And another where the client sends in it's client secret to the authorization server.
Please also see PKCE that deals with SPA (SinglePageApp)/Mobile apps.
I am trying to implement OpenId Connect for SSO in one of my projects. However, I am a bit struggling with the case where I would like to validate OpenId JWT token on Resource Server side to make it stateless. If user tries to logout, authorization Server will know about the user logout (Accordingly OpenId Connect Session Management spec). But how should Authorization Server tell Resource Server that the user's token is not valid anymore? It is a case when user after log out out goes to Resource Server with his OpenId token and gets access. That is weird and I could not find any solution across Internet. Please help me to organize stateless security with central logout.
You can use Token Introspection endpoint to determine whether the access token passed is valid or not. The resource server can make a call to OP's introspection endpoint to validate the token before giving access to the resource. In order to effectively validate the token, the resource server should :
Be a registered client with OP and have Same / similar Scope as SPA app (Implicit flow app) to validate the scopes passed to it and
Have access to Introspection endpoint
The are more details in the above linked Spec for further understanding.
P.S. The answer that I wrote earlier has some other relevant references.
you can use jwt bearer flow, where you can pass ID token/Assertion token to OP in order to generate access token.
Generally OAuth definition says that it is way where user gives an application access to his resources stored in other application (without exposing the actual username and password). But inside Owin, it is a way to implement token based authentication within an application. Although we can deploy the Authorisation application at different server. But crux remains the same. Could anybody shed some light. I am very confused.
Thanks in advance
If you take a look at the OAuth 2.0 spec you will find this:
The authorization process utilizes two authorization server
endpoints (HTTP resources):
o Authorization endpoint - used by the client to obtain
authorization from the resource owner via user-agent redirection.
o Token endpoint - used by the client to exchange an authorization
grant for an access token, typically with client authentication.
As well as one client endpoint:
o Redirection endpoint - used by the authorization server to
return
responses containing authorization credentials to the client via
the resource owner user-agent.
Not every authorization grant type utilizes both endpoints.
Extension grant types MAY define additional endpoints as needed.
So basically, you have 2 options:
1) Use the authorization endpoint where your end-user is redirected to a form that is handled by the authorization server
OR
2) Create your own form inside your app, get the end-user credentials and send that data to the authorization server, where it will be validated and return a token for you to use.