Is it possible to discard Keycloak user management? - java

I have the hope to use the token generation and management abilities of Keycloak, without authenticating against Keycloak's users but instead, 3rd party systems that do not use token based authorization.
In other words, I want to create a realm that generates tokens not for Keycloak users but for that 3rd party's users, meaning that there is no need to store users in Keycloak's DB.
Is this even possible? If it is could anyone give me some pointers?
From what I've seen the closest ability that Keycloak provides is the Identity Providers option available the Administrator console. Unfortunately and as expected, it works only for OpenID Connect and SAML which of course are token based.

Related

Select Identity Provider Locally with Spring Security's SAML 2.0

I'm using Spring Security's SAML 2.0 to connect my service provider to multiple identity providers.
Everything in Spring's SAML 2.0 documentation makes sense. I have read many helpful tutorials including this one, which are similar to my existing code.
However, I am missing where and how to select an identity provider for a given user.
I understand SAMLDiscovery can be used to delegate the identity provider selection to a third party service. I also understand how to configure multiple identity providers. But I'm looking for a way to run my own code (i.e. check a database) and then trigger a SAML request for the chosen identity provider (not a third party service). I would expect this around the time SAMLEntryPoint is hit. I have seen mention of specifying EntityID in the initial request. Is this related?
I am attempting to perform SP-initiated SAML 2.0 SSO. Can someone please point me toward where I can manually specify an IdP based on the current user?
As far as I know, SAML doesn't offer any mechanism for what you want.
SAML discovery is used to find out which IdP exist for your application.
Your problem is that you don't know who the user is before it tries to log in and when he does, it means that he already know which IdP he wants to use.
So you have these options:
Most common. Use a landing page that lets the user select which IdP to use. For example, Epic games lets you select the IdP from a list of 8. Once the user selects it, then you are good to go, by directing his request to the correct IdP.
If you know in advance which user belongs to which IdP then you can have a page that lets the user enter his username only. Once he does this, you can check in your DB to which IdP this user belongs to and send a redirect message back to the browser. While this works, it will not allow the user to select which IdP it wants to use, putting this job on the shoulders of the backend.
Do step 2 once and save a cookie in the user's browser. Then, when the user tries to log again in another session from the same machine, you can automatically redirect him to the right IdP. Using this option, everything is done automatically and except for the first time.
One thing to consider. From a security standpoint giving a hacker any info is a bad practice and so option 2,3 do reveal to a hacker which IdP belongs to which user. IMO this is not such a big breach and can be implemented.
This is not really a SAML question, since any solution would happen outside of standards and involve identifying the user before asking them to authenticate.
GENERAL PATTERN
App redirects to Service Provider using Technology A, eg SAML, OpenID Connect
For this app, the Service Provider is configured to run an action, eg present a screen, to identify the user - you may have seen this in systems such as Office365
Service Provider then uses some kind of data lookup to identify the IDPs for the next step
If there is more than one then the user is prompted to select one, otherwise the default option is invoked automatically
The Service Provider then redirects to the IDP using Technology B - could be SAML / OIDC / Other
EXTENSIBILITY
Hopefully my comments above show that an IAM system is a toolbox and should be extensible. I work at Curity where we use a concept of authenticators and actions which can be combined - eg for MFA, but a common option is as follows:
Capture the user name
Run some custom logic - eg JavaScript that invokes a data lookup to set the next authenticator
Here is a recent article to show how this works - the Username Authenticator is the interesting part.
PROVIDERS
Unfortunately Spring may not provide the options you would like. This should clarify your requirements a little though.

Direct Access Grant with KeyCloak using external Identity Provider (IDP)

I would like to authenticate against KeyCloak using "Direct Access Grant": https://www.keycloak.org/docs/latest/server_admin/index.html#resource-owner-password-credentials-grant-direct-access-grants
I works like a charm when keycloak manages users and passwords on its own.
But, my scenario is different:
I would like keycloak to act a Broker to some external IDP. KeyCloak has identity brokering feature - but in only works in "Authorization Code flow" - redirecting user to external IDP login form.
I have mobile app and would like ot use "direct access grant" - so that app comunicates with keycloak to authenticate user - and keycloak, as a broker, authenticates this user (using openid-connect) in external IDP
How to achieve such scenario ? I know that it is not possible out of the box - but maybe somebody could advice how write an extension to keycloak do make this scenario possible ?
Whatever it is you are trying to achieve this way, it goes directly against what OAuth and OpenID Connect were designed for. The whole idea of using access tokens is to allow some relying party (such as a mobile app) to interact with a service on behalf of the user without ever getting to see the user's credentials (like a password).
Think of it like this. Let's say you have some app on your mobile phone. It can make use of certain services by Google. In order to do so it offers you to log in with Google and grant the app access. Now, would you want to do so by putting your Google email and password directly into the app? Of course not. That could give it complete control over your Google account, other apps and sites using your Google identity, possibly services that allow you to pay through your Google wallet... It would be insane to simply hand some phone app your Google login.
So instead with OAuth2 or OpenID Connect you can use the authorization code flow or implicit flow to have the user redirected to the identity provider (Google in our example) where they will complete their login process, and then the identity provider redirects back to the app or a site with an authorization code that can be exchanged for tokens or, for the implicit flow, the tokens themselves.
Now, when it's your own app and your own identity provider (like Keycloak) which are under your control it doesn't really matter. You can use a direct grant to simply have the user input their username and password into the app because you know it's not trying to steal user credentials to maliciously use your service. They're both under your control. In that case OAuth or OIDC are a bit overkill, but you could have separate clients for direct grants (your own app) and authorization code flows (third-party apps using your service). When you want to use Keycloak identity brokering, however, an external identity provider like Google or Facebook is not going to offer a direct grant and invite apps to steal their user's credentials. So you won't be able to interact with them this way.
Depending on what you're trying to achieve you may find some use in the token exchange process. If however the idea is that you want your user to log in with their external identity provider credentials, in your app, without a redirect... Don't.
This is a real use case, unfortunately Keycloak doesn't have a direct way of solving this issue. AWS's "IAM Roles for Service Account" feature works based on token exchange with direct access grant using external IDP. I found this discussion on how to workaround this lack of support in Keycloak but not sure if it solves all the usecases - https://lists.jboss.org/pipermail/keycloak-user/2017-January/009272.html
Do you stick with Direct Access Grant as a method of user authentication in your mobile app? In my opinion, you need to use Authorization Code Flow when the IDP is a third party service as it won't provide an API to authenticate users, and even with your own (first party) IDP, it'd be better to use Authorization Code Flow as stated in OAuth 2.0 Security Best Current Practice section 2.4.
To implement Authorization Code Flow in mobile apps, you will need to use in-app browser tab to show login screen provided by the IDP. Please refer to RFC 8252: OAuth 2.0 for Mobile and Native Apps for details.

Is possible to create a role based application with OAuth2?

What I'm trying to do is to create an application with Angular frontend and Spring Boot backend with OAuth2 authentication.
The issue is that I don't know how to get on the frontend the ROLES user has so that I'll be able, for instance, to show something role-based on the page. Yes, there are scopes that OAuth provides in the response but the problem is that these scopes are for the CLIENT but not for the specific USER itself. And that CLIENT is my frontend side (correct me if I'm wrong) which basically means that every user operating my application(client) going to have the same scopes(roles). Moreover, I can specify roles on the backend with the help of Spring and UserDetailsService and then use those roles with #PreAuthorize, etc. But not on the frontend side.
Just as an example, if I simply used single JWT then with a token itself I'd return both the username and roles to frontend. And then I could store that data and use it on the frontend side according to my needs.
So what I'm asking is if it's actually possible and if this is correct to do so?
And how can I possibly implement such behavior?
OAuth doesn't solve this problem and it is best solved via claims in your API. OAuth should deal with authentication only. My below post may help you to think about the best separation: https://authguidance.com/2017/10/03/api-tokens-claims/
In a nutshell you will have to look up user rights such as roles after the OAuth processing completes.
There is a great video from Spring developer on YouTube about OAuth2/OpenID Connect. It shows how to implement the resource server using the newest Spring Security 5 solution.
Probably the easiest and the best way to achieve this is to use an OpenID Connect server which will provide all user management stuff. On the market there are many solutions. Auth0 and Okta are Identity Clouds which provides their services for small amount of money. On the other hand you have Keycloak, which is a server which you can install in Docker or even on bare metal - it's free and open-source.

User Impersonation Using Java and Active Directory

I am developing Java application that uses Active Directory as user store. It is accessing AD using UnboundID LDAP SDK. Initially, I planned to use pool of connections that would bind to AD using service account and impersonate users as needed without requiring for user name/password to be entered again. Unfortunately, AD does not seem to support Proxied Authorization Request Control (RFC 4370). It does not seem to support SASL authzId field either "Additionally, it does not permit an authorization identity to be established on the connection that is different from the authentication identity used on the connection." from https://msdn.microsoft.com/en-us/library/cc223500.aspx
Is there a way to make my solution work without replacing AD with some other directory?
Use Case: We use Active Directory as an identity store for our users. When users log in we verify their credentials against AD by executing bind, which is followed by OpenID worklfow against our Authorization Provider. After that, user is considered authenticated and authorized and issued an access token. Everything is great until we get to self-service and delegated management part. We don't want users to see anything that they are not allowed to see/modify. We achieve that by managing permissions in AD. I.e. admin user can unlock accounts. Regular user cannot. If we use service account to perform LDAP operations we lose all of the extensive security model that AD provides. We are unable to maintain a persistent connection for each logged in user because the number of users is very large and we may potentially end up with thousands of connections. We would like to maintain a pool of connections authenticated with service account and impersonate users as needed. The easiest way to achieve it is using Proxy Authorization.

How to provide OAuth based API when application itself relies on thrid part OAuth

I have a Java web application. It relies on Google OAuth to authenticate and authorize users. I want to provide an API to my application which must also use OAuth. Is it possible to provide OAuth by myself without having a database of users and auth mechanism?
Has it been implemented by anyone?
The OAuth specification doesn't make any particular statements about how to authenticate (ie, login) users - just how to pass credentials to other servers, once the authentication succeeds. There's no particular reason that, at the step where other servers might put up a login box, you can't instead initiate an OAuth transaction with another unrelated server.
However, you will need to have some sort of database to link up the credentials you issue (ie, the credentials your clients will use to operate your API) with the credentials you receive from upstream servers - whether this data needs to be retained over server shutdowns, etc, will depend on whether you want your third-party clients to be able to use their credentials over a long period.

Categories

Resources