I'm currently using Keycloak 9.0.0. When authenticating using the code flow and exchanging this code, I'm receiving an id token without the at_hash claim.
How do I configure Keycloak to include an at_hash claim in the id token?
Background:
I'm using a "classic" server side rendered (SSR) program, a confidential client.
I'm sending requests to my local http api. But I also have an Angular client. The SSR is a Go programm using github.com/coreos/go-oidc.
Rendered pages that require authentication redirect the visitor to keycloak and back via the redirect_uri.
Since the visitor is logged in its id token is present in the session and I also pass the access token. However the id token has no at_hash claim and thus access token validation fails.
I also have a mobile web version of this site, in Angular and it sends a bearer access token once logged in. This app uses the code flow + pcke.
Both should be able to send authenticated requests, but since I'm using pretty much the only oidc client library for Go available, it requires an at_hash claim being present in the id token to be able to verify access tokens. The package currently has no support for the introspection endpoint.
Both id token and access token are returned from the IDP. But neither has an at_hash claim.
According to OIDC at_hash is mandatory only when access token is issued.
Make sure you are using response_type=id_token token and not response_type=id_token.
Related
I have an api written in GO that, at the moment, serves an authorization token based on a username and password. (Without MSAL)
I am trying to implement MSAL logins with Microsoft accounts. I have setup my angular frontend to log a user in to an Azure AD app registration. Would it be possible to authenticate that they have successfully logged in to the Azure AD, and serve them one of my tokens (unrelated to msal) from my GO API?
The username that they use to login with MSAL also exists in my backend, the flow would be something like this;
User logs in with MSAL -> my frontend makes a request to golang backend with username -> golang verifies that this username has logged in with MSAL -> backend serves a token for this user
It appears golang integration with MSAL is limited, so not sure how possible this is.
Thanks.
What you can do is acquire an access token for your API in the front-end from Azure AD. For this you will either register the API in Azure AD or use the same app registration. Either way, you should add a scope in the Expose an API page in the registration. Your front-end can then use that scope's id to get the needed token.
Your API can then have an endpoint that validates the access token, and issues the local token. The access token will contain the user's username for example, if you want to map to that. A more robust way would be to map to the user's object id (also in the token) since it is immutable, unlike the user email.
For token validation, you should be able to use a generic JWT validation library. Also remember to check for that scope in the token that you defined to properly authorize the request.
I have three applications: REST API with Resource Server, Authorization Server and javascript client on VueJs that should use REST Api. Problem in using access token that I get after authorization. First I decided to use local storage or cookie for storing access token, but as I read It's not secure. It's recommended to use cookie with httpOnly, but I can't to access from js. Addition token in url params as well not right way. So what I should to do for using my Rest Api? I'm using Authorization Code grant flow.
When you have a Javascript client, the client itself should act as an OAuth2 client.
Meaning, the server is not what gets the token. The client, the javascript application in the browser, will fetch the token from the authorization server.
You achieve this by using a grant type called implicit.
In this grant type, there is no client_secret, but you must have a valid client_id. You will also not receive a refresh token. But you can receive access tokens and id_token (if you have an OIDC server).
Your question hints at you doing a server side grant (authorization_code,password,etc) and then sending that token to the javascript client. This would be incorrect.
For a great description of OAuth2, we have published this video: https://www.youtube.com/watch?v=u4BHKcZ2rxk
Your JavaScript application would do this:
Do I have a valid token? No
Start implicit grant
Receive token from authorization server
Store token in memory var token = ....
Use the token to invoke API endpoints on the server
Repeat step 5 until token is no longer valid
Go back to step 1
Next step for you is to watch the video and learn more about implicit grant type
As you already guessed, going down the road of getting a token on the server and then sending it to a non secure client exposes your applications in ways you probably do not want.
We would like to have REST APIs with OAuth2 using our own user table for Authentication. Also, we need to allow Social Login. Below is the flow for social login,
Our OAuth
Client makes auth and access token URL for our servers to receive
the access token
Client sends access_token for further calls in the header as bearer
token
Social Login
Client makes auth and access token URL to Social Login server(For
ex,https://accounts.google.com/) to receive an access token
The client sends access_token for further calls in the header.
We have implemented our OAuth with Spring and working perfectly. We have questions on social login,
How to identify our own Oauth access token and social login access
token. We may have many social logins and we should able to identify corresponding social login.
How to validate and integrate with Spring Boot?
If the access tokens are just random strings, you probably cannot tell the issuer of the provided token and you cannot validate it.
I would suggest you to extend your OAuth2 server to accept third party providers (Google, Facebook ...) for authentication. This way would support both local and social users, but in your application, you would always deal with your own tokens. It would make the application security much easier (which usually means safer) and you could also configure your own scopes for access tokens. There are also ready to use solutions for it - e.g. Keycloak.
I'm writing an API back-end that I want to use OpenID Connect (OIDC) to secure. I've been reading the documentation but I'm still a bit confused what process applies to each and every API request. The Open ID Connect code flow appears to be:
Which I'm fine with, as a one-time process. My back-end API sees an authorization code in the HTTP headers, and sends a request to the authorization server to get the id token. Assuming this validates OK, the data requested is returned in the API response.
But assuming the same user will then be making lots of requests to this API, what happens in subsequent requests? Is there some sort of session created in this mechanism? Do I continue to receive the same authorization code? Do I have to keep sending these back channel requests to the authorization server?
Or should I even output the JWT id token as a cookie? In this way I get the self contained id token coming back in future requests, with no need of a server side session, or further round trips.
I've been reading the documentation but I'm still a bit confused what
process applies to each and every API request
It is not the API that should follow OpenID connect protocol. It's the client that should do it.
My back-end API sees an authorization code in the HTTP headers, and
sends a request to the authorization server to get the id token.
Assuming this validates OK, the data requested is returned in the API
response.
Authorization code must be used by client application and not by the API endpoint. Also, authorization code must never be exposed to other entities.
You should use id token sent with OpenID Connect to authenticate the end user from your client application. To access API, you should use access tokens.
What to do in API endpoint ?
I think this is where you struggle. Your client application should send a valid access token to get access to API endpoint. From API endpoint, you can use OAuth 2.0 introspection endpoint to validate the tokens.
RFC7662 - OAuth 2.0 Token Introspection
This specification defines a protocol that allows authorized
protected resources to query the authorization server to determine
the set of metadata for a given token that was presented to them by
an OAuth 2.0 client.
Note that, OpenID Connect is built on top of OAuth 2.0. This means you can use anything defined in OAuth 2.0, including introspection endpoint. Use this endpoint to verify the access token validity.
What if you want end user details ?
OpenID Connect defines a user info endpoint
User info endpoint
The UserInfo Endpoint is an OAuth 2.0 Protected Resource that returns Claims about the authenticated End-User. To obtain the requested Claims about the End-User, the Client makes a request to the UserInfo Endpoint using an Access Token obtained through OpenID Connect Authentication. These Claims are normally represented by a JSON object that contains a collection of name and value pairs for the Claims.
Here also, you use access tokens to get user information from this endpoint. The response will let you know the end user to which this token was issued.
Depending on your specific API requirement, you can do a token introspection or obtain user information from user info endpoint. Once that is done you may go ahead and authenticate a session. You might use both endpoints if you need all available information.
Alternatively(instead of sessions) your API can maintain an access token cache. This will remove the need to validate tokens in each an every API call. But be aware that tokens have expiration time. You must consider about token expiration if you are choosing this solution.
p.s - Client vs Resource server
In OpenID Connect and OAuth 2.0 terms, a client could be a simple web page, desktop application or could be even server hosted application.
client
An application making protected resource requests on behalf of the
resource owner and with its authorization. The term "client" does
not imply any particular implementation characteristics (e.g.,
whether the application executes on a server, a desktop, or other
devices).
Obtaining tokens and using them is the duty of the client application.
On the other hand, resource server contains protected resources,
resource server
The server hosting the protected resources, capable of accepting
and responding to protected resource requests using access tokens.
Resource server exchange it's resources to access tokens. If we match the same scenario to basic authentication, access tokens replaces username/password sent with authentication headers.
Typically you'd secure a (pure) API with OAuth 2.0, not OpenID Connect. The Client accessing your API should obtain an OAuth 2.0 access token and in order to do that it may choose to use OpenID Connect to obtain that token. That is all independent of the API, which will only see the access token. The API (or Resource Server in OAuth 2.0 terminology) is not depicted in your diagram.
I have a Spring (3.2) based web app that a user can log into. The site will also provide an API secured via OAuth 2.0. My question then, is how do I go about generating a token for a logged in user?
The underlying idea here is that there will be a mobile app that opens up a web frame to the login page, which will eventually redirect to a url schema with an oauth token that the app will catch and then use for the api calls. Looking at the code for TokenEndpoint, I see that it defers token creation to a list of TokenGranter types. Should I be creating my own TokenGranter extended class, or am I looking at this all wrong?
I ended up writing a controller like this:
OAuthClientRequest request = OAuthClientRequest
.authorizationLocation(csOauthAuthorizeUrl)
.setClientId(csClientId)
.setRedirectURI(
UrlLocator.getBaseUrlBuilder().addSubpath(AUTH_CODE_HANDLER_URL).asUnEscapedString())
.setResponseType("code")
.buildQueryMessage();
UrlUtils.temporarilyRedirect(httpResponse, request.getLocationUri());
return null;
Then handling the code returned. My big problem here was that I had the /oauth/authorize endpoint set to use client credentials. Once I realized that tokens were being issued for the client ID instead of the user, it started to make sense.
So you want to use the Authorization Flow of OAuth. Spring has already support that, if you have configured the spring-security-oauth correctly, you just have to redirect the user/your mobile apps to /oauth/authorize?client_id=xxx&response_type=code this will redirect user to authorization page, if user has not login yet, it will redirect the user to login page then to the authorization page.
After the user completed the authorization process, it will redirect the user to an already registered redirect_url parameter with the authorization_code 'yourapp.com/callback?code=xxxx'.
Your application should exchange this authorization_code with the real token access to /oauth/token?grant_type=authorization_code&code=xxxx&client_id=xxxx&client_secret=xxxx
After that you will receive the token access that can be used to access the resource server.