I used this curl command to retrieve session details for a user in keycloak:
curl -X GET \
-H 'Authorization: Bearer $TOKEN' \
http://192.168.X.X:8080/auth/admin/realms/$REALM_NAME/users/$ID_OF_CLIENT/sessions
and in response we have:
[{
"id":"194d6b10-5b94-42c3-86d8-4d1780f70f52",
"username":"admin",
"userId":"e258f775-3597-4a72-a490-7bgd7c1cdfdb",
"ipAddress":"192.168.X.X",
"start":1589006511000,
"lastAccess":1589007060000,
"clients" :
{
"53d98bf8-fffd-484c-aae8-500a7cf7a8b6":"authz-servlet",
"9bc56128-972e-41fe-8946-3ce4b5660e24":"authz-client-app3"
}
}]
now I need to add some more details in the session information such as browser version for the logged-in user. Is there any way to add these details?
I suggest you to take a look at userinfo OIDC endpoint. Comparing to you current approach (utilizing Admin REST Api with administrative token) it accepts token issued for end user. If it ok for you, you will be able to customize endpoint output as you want. Customization available at Client Scopes and Mappers tabs in client settings.
Set of mappers available by default is quite wide but
i'm afraid by default Keycloak is not preserve information about UA, so you have to develop your own logic to extract it during login flow and than to store it in user session. If you are not familiar with implementing Keycloak Java SPI you can try to do implement your logic via JS mapper.
https://www.keycloak.org/docs/latest/server_admin/index.html#_protocol-mappers_oidc-user-session-note-mappers
https://www.keycloak.org/docs/latest/server_development/#_script_providers
AFAIK some examples should be in keycloak github
Related
I have an existing spring boot application which provides Rest API's and it doen't do authentication. Authentication is being handled by FrontEnd applcation and for evert API request from FrontEnd, we receive token in the Request Headers(authorization) and we validate this token by calling below 2 service provider endpoints using org.springframework.web.client.RestTemplate before proceed with the API requests. For this we have written an interceptor to intercept every request and validate the token.
Token Info end point to validate token and User Info endpoint to get User Details.
UserInfo: https://dev-login.iam.organisation.com/organisationsso/oauth2/userinfo
TokenInfo: https://dev-login.iam.organisation.com/organisationsso/oauth2/tokeninfo?access_token=
User Info Sample request:
curl -X GET \
https://dev-login.iam.organisation.com/organisationsso/oauth2/userinfo \
-H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6Il…' \
-H 'cache-control: no-cache'
Token Info Sample request:
curl -X GET \
'https://dev-login.iam.organisation.com/organisationsso/oauth2/tokeninfo?access_token=eyJ0eXAiOiJKV1QiLCJub25jZSI6Il..' \
-H 'Cache-Control: no-cache'
Now we are changing the IAM service provider to Azure Active Directory B2C and I don't have much idea on how to validate tokeninfo and userinfo with Azure AD using existing org.springframework.web.client.RestTemplate or different approach.
I have found docs for userinfo and it seems we can use RestTemplate to call the endpoint to get the user information but could not find the Rest Template approach for Token info.
Can someone guide me to the correct and simple approach to avoid the multiple changes in the existing code.
ACCESS TOKENS
For access tokens you will use JWT validation in memory - here is a Spring Boot API Example.
USER INFO
To get user info in an API is tricky - not sure if you need to do that? If so you may need to get a different (graph) token using the On Behalf Of Flow.
RESOURCES OF MINE
I remember struggling with some of this a couple of years ago, so my links below may provide a useful hint or two:
Code
Blog Post
Is it possible to have user access control on file level of HDFS?
Currently, everyone can access the data when clicking on the link like http://<domain>/webhdfs/v1/xxx.txt?op=OPEN.
Can I set certain groups of people and they can only access certain files or directories? The purpose is, not letting others access files which don't belong to them.
If this cannot be set on HDFS, is there any suggestion?
When security is off, the authenticated user is the username specified in the user.name query parameter. If the user.name parameter is not set, the server may either set the authenticated user to a default web user, if there is any, or return an error response.
When security is on, authentication is performed by either Hadoop delegation token or Kerberos SPNEGO. If a token is set in the delegation query parameter, the authenticated user is the user encoded in the token. If the delegation parameter is not set, the user is authenticated by Kerberos SPNEGO.
Below are examples using the curl command tool.
Authentication when security is off:
curl -i "http://<HOST>:<PORT>/webhdfs/v1/<PATH>?[user.name=<USER>&]op=..."
Authentication using Kerberos SPNEGO when security is on:
curl -i --negotiate -u : "http://<HOST>:<PORT>/webhdfs/v1/<PATH>?op=..."
Authentication using Hadoop delegation token when security is on:
curl -i "http://<HOST>:<PORT>/webhdfs/v1/<PATH>?delegation=<TOKEN>&op=..."
Ref: https://hadoop.apache.org/docs/r2.9.0/hadoop-project-dist/hadoop-hdfs/WebHDFS.html#Authentication
How might I authenticate GET requests to an elasticsearch API using Jmeter GUI. I know using curl I can authenticate using something like
curl -u user:password http://www.example.com
but Jmeter only has the following options
The Authorization Manager lets you specify one or more user logins for web pages that are restricted using server authentication. You see this type of authentication when you use your browser to access a restricted page, and your browser displays a login dialog box. JMeter transmits the login information when it encounters this type of page.
Some developer posted an example of basic auth here.
What I Did
First I accept that I am lacking in spring security knowledge.
I am trying secure rest services for one of our product. I am using spring security OAuth2 JWT. I want to allow anonymous as well as registered users to access my resources.
Suppose I have one service "http://localhost:8282/melayer/articles" and when I run following command
(1). curl -X POST -vu melayer:12345 http://localhost:8282/melayer/oauth/token -H "Accept: application/json" -d "password=melayer&username=melayer&grant_type=password&scope=write&client_secret=12345&client_id=melayer"
I am able to receive access_token, refresh_token etc. Everything works fantastic, even I can access url http://localhost:8282/melayer/articles with received acces_token
(2). curl http://localhost:8282/melayer/articles -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0NjA3NzY5NDIsInVzZXJfbmFtZSI6ImVjb2tyeXB0IiwianRpIjoiNWI5ZmE4NjYtMTBlNS00NDA2LTgxYmMtYjM3NWVmNGE0ZmQ1IiwiY2xpZW50X2lkIjoiZWNva3J5cHQiLCJzY29wZSI6WyJ3cml0ZSJdfQ.4jO9euBz4TSSNh7M3l2YBD1QPblE0ZyOfGm4VtyFMFY"
What I want to understand
I want to receive access_token anonymously i.e. I dont want to pass user name, password or client secret, I want to run curl command in following way
curl -X POST http://localhost:8282/melayer/oauth/token -H "Accept: application/json"
My one of the concern is, I want access_token with or without user credentials I am trying to achieve this from last week, Am I missing something ? is it possible ? what is correct way to do this ?
It is kind request to help me on this :)
If anyone want to see my code please refer Git repo https://github.com/aniruddhha/spring-security-oauth2-jwt
I think you Misunderstood the access token concept, access tokens are meant to be used on behalf of authenticated user.
OAuth2 supports different grants types (password, authorization_code, etc) , check the spec Oauth2 Spec
In order to authenticate used you can use any one of those grants or could create your own (eg: login with Google token ) but you must send some form of user credentials to identify the user and the client credentials to identify the client.
Access token cannot be used as some kind of ApiKey used to access public api
I am using spring boot for backend and Android device for frontend of my system.
Right now I am facing the challenge to use Spring-OAuth2 to secure my resource server.
I have some questions, which I want to discuss with you:
My knowledge + this tutorial are saying that I should use the OAuth2.0 "password" grant type for my mobile app to obtain an access token. The official spring tutorial for security gives an example how to obtain the access token using password grant type:
$ curl client:secret#localhost:8080/oauth/token -d grant_type=password -d username=user -d password=pwd
And here comes my first question: Is there any possibility to obtain access token using the password grant type without sending the "client secret" ?
Since the client secret could be "reverse engineered" by decompiling the client app. The obtaining access token without secret should be somehow possible, because Facebook SDK for Android also does not need the client_secret in the mobile app.
I think here I have a little trouble understanding why the clientID + clientSecret needs to be included in the request above, because, since there are already username + password included, it should be possible to generate the access token, so does this brings a next level of security ? and does it implies the following (example): I am logged in as Filip in my Android client and I am sending the access token A with each request to the server. Then I log in as Filip into web client and I try to access the resource server from web client using the access token A, which is not possible because access token A was issued only for Android client ?
The next question is how can I refresh the obtained access token ?
I was trying to do so using the command below, but I got "Full authentication is required to access this resource." After I got the new refreshed token, can I use the refresh token to refresh my new access token again ?
curl -v --data "grant_type=refresh_token&client_id=acme&client_secret=acmesecret&refresh_token=REFRESH_TOKEN" http://localhost:9999/uaa/oauth/token
Thank you
The OAuth 2.0 spec allows for so-called public clients i.e. clients that don't authenticate themselves. So it is possible to use the Resource Owner Password Credentials grant with a public client, i.e. one that does not need to send a client secret. It does mean that the Authorization Server cannot assume anything about the client since a client_id is not a secret and there's no way to prevent a malicious client using this grant type or clients from impersonating each other. So using it in this way comes at the cost of reduced security although one may argue that in your case there's no way to use confidential clients anyhow, so there's no difference.
In general the Resource Owner Password Credentials grant is an anti-pattern for OAuth and only meant for migration purposes because it defeats most of the goals of OAuth in itself.
Access tokens are issued on a per-client basis.
You refresh token request seems OK but the Authorization Server may require basic authentication instead of providing the client_id/client_secret as post parameters, considering that you did the same for the original access token request.