How to check authenticate keycloak instance A user from another keycloak instance B? - authentication

We setup a testing environment for keycloak. The environment run on GCP. It have two keycloak instances:
Instance A acts as a test login keycloak, named test-login-1
Instance B acts as a test external identity provider, named test-login-2
We need to use the instance A to connect the instance B.
So instance A user can able to login via instance B.
Is there any way to do this? How can we implement this logic?

You need to configure the test-login-2 as an identity provider for the test-login-1. You can read about identity brokering here. I will be calling internal realm to the realm that will be used from the internal Keycloak (test-login-1), and external realm to the realm that will be used from the external Keycloak (test-login-2).
For that go to the Admin Console and:
select your Realm from test-login-1, and click on Identity Providers
On the right side of the page select Keycloak OpenID Connect from the Add provider ... dropdown menu. It will popup the Add Identity Provider form, from there set:
the alias
the Authorization URL, Token URL, Logout URL, User Info URL and Issuer to the correspondent endpoints that can be found on the realm of test-login-2 on the .well-known endpoint (i.e., <KEYCLOAK_IP>/auth/realms/<External Realm Name>/.well-known/openid-configuration)
For the Client Authentication you can select Client secret send as post
For the Client ID and Client Secret first you need to create a new client in your external realm (of test-login-2) and use its Client ID and Client Secret here.
This client:
can have Access Type Confidential
Standard Flow Enabled : ON
Valid Redirect URIs set it to your Keycloak IP followed by "*", for instance <KEYCLOAK_IP>*
Web Origins : +
Save
Bear in mind that some of those configurations might have to be adapted to your own needs.
Now if everything was set correctly, at the keycloak (test-login-1) internal realm login page will show up a new button that the users stored on the external realm (of test-login-2) can click on to authenticate against the external realm.
Now you configure your app to lend at the Internal Realm Login page, the users from your internal realm authenticate immediately there, the users from the external realm click on the new button to explicitly authenticate against the external realm.

Related

oAuth2 SSO without Cookie

We're having a native iOS and Android app that has a custom login form to authenticate a user directly via an authentication endpoint of an oAuth2 enabled indentity provider (the app sends the user credentials via HTTP request to the identity provider and gets a JWT as response).
The app does not have the possibility to open a browser with callback url or an in-app-browser to open the login form of the identity provider directly - so there is no possibility to set a cookie for SSO.
The app does sometimes redirect the user to other services (in the web browser) that are using the same identitiy provider. Until now, the user is forced to enter his credentials again to signin.
We're now looking for a (secure) way to implement SSO with the app, without the need of using a cookie enabled (in-app-)browser for the app login.
A solution we thought about:
sending a valid access_token to the identity provider together with the target url of the service
the identity provider validates the token and the target url
the identity provider authenticates the user after successfull validation and redirects the user to the service
Can this be considered as a secure solution? Is there a standardized way we don't know about to do something like that?

How to use oauth with 1st party client-side js app?

The model for our product is like this:
Api backend (headless)
I already have oauth set up and ready to use with a resource owner credentials grant. Anyone who wants to use our api can do so using either an API key or their username/password. Of course they also need their client ID and secret.
SPA frontend that accesses the Api
I have built an SPA that will uses the api to provide a portal GUI for our clients. Given that this client-side app is owned and administrated by us (so it's a trusted app) how can I safely authenticate users using only username/password with oauth?
Originally it was using a JWT auth system that only required username/pass but now that we've implemented oauth I'd like to consolidate. It's unreasonable to make every user need to also have their client id and secret on hand to login, but I want users to have full access to the api from the GUI.
I've looking at using CSRF tokens but how would that work with my app when nothing is generated server-side?
I'm not sure how to proceed.
EDIT: very similar to the problem here.
I have decided to use the solution described here.
And here is a snippet of my implementation
The TL;DR version is
Create a proxy between the app and the api
Store the client ID and secret in the proxy
App logs in using password grant type -- proxy intercepts login request and inserts client id and secret
On login response proxy returns access token as an encrypted cookie
Client stores cookie and sends with api requests (to proxy)
Proxy decrypts cookie and inserts access token into Authorization header before forwarding to api endpoint
For me this has several advantages over implementing something custom on the api itself:
No need for custom grant on oauth server
ID/secret is hidden from app securely and can still use password grant
oauth server can identify client (no need for separate client ids for each user)
You should not use the resource owner credential grant from a JavaScript application. The fact that you own and administer the application does not make it a trusted application.
A trusted client is an application that can keep a secret. SPAs or any JavaScript app cannot keep a secret.
You should use the implicit grant for non-trusted clients.

Access Requested Client from IUserService

I have an existing database that holds user credentials as well a map of what applications those user credentials have access to. In identity server I have each application setup as a client and users can authenticate successful. However, any user gets authorized for any application. I am wondering if there is a way that I can access which client is being requested from my implementation of IUserService? This way I can check if they are authorized for that app.
IdentityServer allows for custom validation of the requests via the ICustomRequestValidator interface. You can implement this and return an error to prevent a user from getting a token for a client.
Let us know on the github issue tracker if you have more feedback on this.

How does SE's single signon work?

Basically I just want to know how does StackExchange's single signon system work?
In the SE network you need to login only once in one of the websites to be automatically logged in to the other sites upon visiting.
How should I implement such a feature in my own network of sites?
I assume it uses the cookie which resides on the user's browser and then authenticates it with the originating site. If it is legit then it logs the user in automatically.
You have to implement SAML or oauth2 to allow sso on your network.
In case of SAML your child websites will be service providers or resource servers.
While you need to setup and identity provider.
The sequence of events will be like this.
1. User hits a url of songs website, this site is resource server and does not handle authentication.
2.To authenticate resource server will construct a SAML authrequest and redirects to identity provider after signing it.
Idp verifies the signature after receiving authrequest.
3. User will be presented with a login form, user has to end login credentials.
4. After user authentication idp will generate a SAMl token and redirect back to resource server.
5. Resource server will extract identity information from SAML token, resource server will login the user with session or cookie.
Depends upon which technology you are working in i have implemented it in php using simplesamlphp.

How to get user's First and Last Name from SSO login?

I am using a Oracle SSO server to authenticate users of my APEX app. I wish to display user's first name and last name on my app, I don't want to ask the users for this info. How can I get this info from SSO server ? Do I have to read cookies?
When using SSO, this information is typically passed in to your application through a custom header. You should be able to configure the SSO provider to pass the user name back to your application through the header, and the client side of your application should have an API for withdrawing it from there.
It depends how your Identity Provider (IP) is configured - in our case, the encrypted artifact passed to our application (via a cookie in our case, but could be passed in the querystring or posted to your app) contains the information about the logged in user that our IP has configured to send to us.