Client side authentication without redirection to Keycloak - spring-boot

Pretty simple question, spend a lot of time searching around.
Spring Boot 1.4.x application, with Spring Security, tried to use Keycloak for user management / authentication / authorisation, all works fantastic!
How do I avoid redirecting to Keycloak login form?
How do I implement my own authentication worlflow based on username-password input?
I see that I can ask for access-token and refresh-token, but should I implement all that token magic myself or there is some famous library people use?
Any github or examples would help. Thanks!

You might have a look into the Ressource Owner Password Credentials grant. It boils down to set the "Direct Access Grants Enabled " for your Keycloak client and implement the login logic yourself.
But please, PLEASE make sure to read this first: https://www.scottbrady91.com/OAuth/Why-the-Resource-Owner-Password-Credentials-Grant-Type-is-not-Authentication-nor-Suitable-for-Modern-Applications
You could also use some openid connect - libraries and get the data you need for the endpoints from the .well-known endpoint of your realm.

Related

Make Keycloak authentication work with own JWT tokens generation

There's a Keycloak (KC) server in my company, and I'm working on some app.
The Backend is Spring Boot 2.6.6, Front-end is AngularJs.
When user presses 'Log In' button, user gets redirected to KeyCloak login page and enters
credentials. This part is implemented already and working fine.
But then comes a tricky part: I need to return to front-end JWT token with some granted authorities, and those authorities will depend of what application gets from it's DB for every particular user. All other endpoints will have #PreAuthorize with needed authority.
So, I can't get JWT from KC, because KC doesn't know anything about app's vision to user's granted authorities.
Can you please help with some ideas how to achieve this? Because I'm trying to implement this and getting doubts about possibility to achieve this.
One of the errors I'm getting is:
Found WebSecurityConfigurerAdapter as well as SecurityFilterChain. Please select just one.
Thank you
Keycloak is OAuth2 and OpenID Connect(OIDC) protocol complaint. Which means you can use already defined patterns of authorization flows in OAuth2.
Auth2 has implementation of a step by step authorization logic called Authorization Code Flow -which is one of many but I believe is the most suitable one for your use case-. RFC docs of this flow explain it pretty well and you can find them here. You should also look at how Keycloak implementations are done.
Learning and implementing this flow on your project will provide an industry standard solution.

Managing user permissions in keycloak and spring rest api

TL;DR
Objective: managing api permissions:
OIDC authorization direct grant flow
User federation and authentication source : LDAP
Permissions store : legacy database
Client management and authentication: Keycloak
Question: What are the best practices for managing user permissions on Keycloak and rest api?
Context
We are implementing a rest API with spring to be used by a mobile application and an SPA. Our users accounts, permissions, rules… and all data are stored in a custom database used by different monolithic applications. To secure our api we have decided to use Keycloak.
The keycloak server is configured with an existing LDAP for user federation and ‘Direct grand flow’ for the mobile client application. For the first use case (authentication) everything is working fine.
Now we have to manage users permissions as follow :
The client applications should know user permissions to display/hide functionalities
The api should be able to validate user permissions to use different endpoints
Users permissions are based on some rules in the database and change frequently
In my understanding keycloak can handle authorization and fine grained permissions using hardcoded or user based policies but can’t be plugged to a different authorization source natively. As a consequence, I thought of building a custom role mapper using Keycloak SPI, retrieve user permissions from a custom api that I will develop, then map them to the access token.
As a result, my access token should look like:
"resource_access": {
“My-client”: {
“permissions”: [
“Show-products”,
“Buy-something”,
“Display-prices”
]
}
},
"username": “myUser”
Then the mobile application should be able to know user permissions based on the token, and my stateless server side (API) should be able to access user permissions on every call to check them using spring annotation :
#PreAuthorize("hasRole('Show-products')")
Problem
After first experimenting my solution seem to work fine, but I still have some security concerns about this choice since it’s out of the keycloak standard and includes rest calls to a different backend inside keycloak mappers.
So I was wondering :
Is it secure to put user permissions on the access token claims?
How to secure keycloak access to an external system (rest calls) to
retrieve permissions?
Should I rely on token claims to verify user permissions on each
request in my resource server?
Is there any other clean solution / best practices to handle user
permissions from external source in keycloak ?
Complimentary Informations
I’m using :
Springboot 1.5.13.RELEASE
Keycloak-adapter-bom 3.4.3.Final
Standalone keycloak server 3.4.3.Final
regarding your questions:
- Is it secure to put user permissions on the access token claims?
Yes, capabilities can (and should be) on the access-token, and with that you can take some decisions in your business layer (based on the roles/access claims). Remember nevertheless that a token is only base 64 encoded, and could be copied by other person and looked into, so it shouldn't contain secret or particularly confidential information, usually you put there enough info regarding the user, and some of its current permissions/capabilities/claims.
How to secure keycloak access to an external system (rest calls) to retrieve permissions?
It depends if it needs to be accessed from outside your network. If not, you can leave it unprotected (and unavailbale from outside/or only available for some specific IPs). If it is going to be available from outside/or you want to protect it with keycloack anyway, you can have either a "confidential" or a "bearer only" type of client. I'd suggest you to look into CORS and token sharing, so that you can reuse your already created "access-token" for your other endpoints without the need to authenticate again.
Should I rely on token claims to verify user permissions on each request in my resource server?
Not exactly sure what you mean. In keycloak the resource server isn't doing extra resource authorization like in a typical oAuth2 dance (unless your policy enforcer is activated but I believe you didn't go with this approach, but rather a mapper SPI #auth server for getting your roles right?)
In oAuth2 the "resource server" has 2 responsibilities: 1-providing the resource and 2-doing an extra authorization step. In the keycloak world those 2 steps are done by different actors. Step 1 is done by your application, and step2 is only done when policy enforcing is activated by keycloak also (that means Keycloak is the auth server and also part of the "resource server" from the oAuth2 perspective)
Now back to your question, if by resource server you just meant your application providing the content, then yes you can use the claims there, remember that the claims (and the whole access-token) was generated and digitaly-signed by the auth server, so you can use those claims in your app with no problem (and wouldn't know how to do it otherwise either).
Is there any other clean solution / best practices to handle user permissions from external source in keycloak ?
Hard to say, as you probably noticed; documentation in the web for your specific usecase is very limited; so not a lot of work of best practices exist there, you only real alternative would have been using policies with a custom Policy SPI, and that would have brought in other challenges. I'd say your solution is fine.
Best regards.

How to implement Spring Oauth2 Resource owner password credentials flow correct?

Assume we have authorization server + resource server, also a mobile app. All applications are developed by same company (e.g all google services + official mobile apps).
In my understanding, mobile app should use Oauth2 resource owner password credentials flow, Am I correct? This is an article supports my understanding. According to Oauth2 spec its seems like not the correct approach. So what would be the correct approach? Is it the authorization code grant flow? In that case how one should cope with redirection? (there are ways but what is the best way of not leaving the app?)
Also I need to use native login screen in mobile app where resource owner need to type username/password. Could that be done via authorization code flow? how?
If I am correct about resource owner credentials flow, how we can implement that in spring without client secret embedding in the app?
Below is the required way of getting token via resource owner password credentials in spring.
curl -X POST --user 'trusted-client:client-secret' -d 'grant_type=password&username=test&password=123' http://localhost:8080/oauth/token
Here we need to have client secret in the app (which is not secure), will this approach work? Assume later on we may have different client, how custom authentication provider distinguish those two? Any answer would be great. Thanks.

Spring Security SAML extension ADFS

I've been working whit the SAML extension to connect to an ADFS server. I've hacked the sample application to use my ADFS server and everything went well, but I would like to know if there is a way to connect to an IDP without using the loging page of the IDP. I mean if there is a way to do this process in background for the end-user. I am thinking about doing a query to ADFS or something like to get the users and do authentication from the SP login page, avoiding the need for the user to authenticate in the IDP login page.
The purpose of federated authentication is to delegate it to a centralized server in such a way that the relaying parties/service providers do not have access to user's credentials. Enabling authentication directly in your application would violate this principle and for this reason is not supported by neither Spring SAML nor ADFS.
If you want to authenticate your users directly, use authentication directly against Active Directory instead of ADFS. This will fully support your use-case.

External OAuth2 integration with own OAuth2 spring server

I'm trying to integrate Facebook OAuth2 authentication with my own OAuth2 server. Just to be clear the scenario is the following:
I have a OAuth2 Server that is responsible for authenticating our users. I implemented a custom AuthenticationProvider that checks for the credentials provided and builds a UserDetails object if successful.
I also have a rest-api that is also a ResourceServer (runs in a different application). So users after being authenticated they can access our rest-api providing therefore the token.
The token information is shared using JDBC.
Everything works fine as expected, but now I want to add external authentication providers such as Facebook.
My question is: what's the best way to do this? What's the expected flow? From the top of my head I would imagine something like:
User authenticates with facebook
Facebook provides a token
User sends the token to our OAuth2 server
I check the token validity with facebook
I authenticate the user using the authentication provider
The server gets back to the user with a new token issued by my OAuth2 server which the user will use from now on to ask for resources
Is this right? If so, how can I send the facebook token to my OAuth2 server? Is there some kind of standard? Should I make up new parameters for that? For instance I will be needing some way to differentiate facebook authentications from user/password ones.
Am I suppose to use my own AuthenticationProvider to validate this facebook user? It seems strange then return a UserDetails object that doesn't have a password...
Also, how to register users and auto log them in? Do I have to expose an endpoint of my own or is there some OAuth2 magic for that as well?
Any thoughts?
Facebook has some very good documentation on this with the correct flow and how you should handle the process.
https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.2
You are on the right track, and I think the facebook documentation should help clear up any questions you may be having.
Additional Information is here:
https://developers.facebook.com/docs/facebook-login/v2.2

Resources