For a web-application portal, which is accessed via internet through web-browser, there is a requirement to implement the following authentication flow within the WSO2 API manager.
End Users of Application (Portal-Web Thin client) must login using a user/password scheme.
The user & credential information are stored in a local application RDBMS database (eg- MySQL).
Application has user management screens to add/delete/update users and map roles.
API manager must authenticate the user against the local user store and generate a JWT/Ouath2 token.
There are custom password policies to be configured (for eg, user must be locked after 5 failure try).
End user will use the generated token to access the protected API.
API Manager should authorize the token and route the API to the appropriate micro service.
From the documentation we found that, a secondary user store shall be created to allow the end users of the application to be part of WSO2 API Manager users, and hence the authentication will be taken care by API manager itself. I would like to get a better understanding on how this can be implemented.
Changes expected in end-user database is very dynamic via user management screens in the application, does this need to be updated to API manager user store in some manner? Or can the API manager user store can be configured directly read from applicable users table.?
Can API manager performs the encrypted password validation, configured in application DB against each user?
Is there any alternate approach, for eg, my application expose a rest end-point for authentication, and the API manager invokes this end-point to perform the authentication by passing the username and password received as part of token api.?
You can plug the Application's User store as a secondary in the API Manager and achieve your requirement. Refer to the official documentation on configuring a Secondary User-store for more detail.
Further, if you are having a JDBC User store, then you can either customize the queries of the secondary user-store in the API Manager to query the user entries correctly. In addition, you can also implement a custom User-store manager and plug (if you are having more customized fields and operations).
Answering your questions
Changes expected in the end-user database are very dynamic via user management screens in the application, does this need to be updated to API manager user store in some manner? Or can the API manager user store can be configured directly read from the applicable user's table?
No, it is not required to perform any manual changes in the API Manager unless if you haven't configured the User-stores properly. However, be in note, that if you are planning to use the user's from your application user-store to create APIs and subscribe in the API platform, deletion of those users can cause inconsistent behaviors in the platform.
Can API manager performs the encrypted password validation, configured in application DB against each user?
You can write a custom User-store manager to handle the password validation as you like.
Is there any alternate approach, for eg, my application expose a rest end-point for authentication, and the API manager invokes this end-point to perform the authentication by passing the username and password received as part of token API.?
I can think of one alternate with the REST API approach. Which is to develop a custom Handler and engage it with APIs to perform the validation in addition to Token validation. In brief,
Develop a Synapse Handler
Engage the Handler with the APIs along with the default APIAuthenticationHandler
Read and extract the username and password from the Transport header in the custom handler
Call the application's REST endpoint and check the validity
If successful, continue with the API invocation (continuing with the usual token validation process and all), if not, drop and respond back with an error
But, please note that this external validation process needs to be fast enough to not to block the API Manager for a longer period.
Related
I have been trying to read through existing information about this topic. I even installed KeyCloak server locally, configured the realm, the client and used Postman to send some requests to KeyCloak, and received some json response.
My problem is that - unless I misunderstand something - none of the descriptions seem to fit my goals.
Our application already has user management and we rely on user identity and roles / access rights configured in the system. The backend runs inside Tomcat and we run a Polymer 1.0 / Javascript frontend to call the REST services of our backend. I cannot get rid of user management as our DB is highly dependant on user to object assignment when deciding the scope of the objects for which the particular user is responsible.
All we need is an extension of our system by the possibility of foreign authentications (like social logins) in the future.
We have now explicit login that delivers a session cookie, Servlet filters to check the presence of this cookie, etc. In the server we use the login token / user identity in each REST call to filter the results from the DB to those available to the particular user.
What I need is a flow like:
in the fronted we check if we have active session (existing code)
if not we redirected the user so far to our own login page, logged in, created the session cookie on server and then returned it. On client side we saved this and added to every REST request as authoriation token.
Now with OIDC I'd like to insert a new unprotected query that checks if OIDC is configured. If not, we keep the old solution. If yes, I'd like to get redirected to KeyCloak login, and - and this is the most important for me - I'd like to get back the user identity (or some role that we associate administratively to the user - using which I could identify one of our configured users.
I tried experimenting with the Tomcat solution but that simply blindly hides the authentication procedure and merely allows or blocks REST access to the backend resources. This is not enough for me, I need some kind of user identity which I can use in the server side.
Also a javascript solution only provides communication between frontend and keycloak, but we need the backend to know who has logged in.
I think this topic and all the used lingo is too complicated for me. Could anyone give me some easy advice how to solve this with best practices?
Thank you very much
I am working on a project where I need to create an application that shall act as an OIDC mediator between a client which only supports OIDC for authentication and a REST api. The REST api is able to generate tokens and give user info but does not support OIDC.
To achieve this I am thinking of using keycloak to handle the OIDC communication with the client and implement my own java application that keycloak can trigger to realize the authorization, token and userinfo endpoint (sort of a custom ownmade identity provider) handling the communication with the rest api.
I have created a realm in keycloak and configured the realm to use an Identity Provider Redirector with an Identity Provider I added in keycloak (user-defined OpenID Connect v1.0). In the identity provider configuration I have set all the URLs to point to my java application but the initial OIDC authorization call from the client just redirects to the redirect_uri with a #error=login_required without any of my endpoints in the java application beeing triggered.
I guess there is something I have missed.. I need to intervene the authorization flow so that I can pick up a query param from the authorization request that needs to be handled in my java application. I also need to map the token from the rest api into the token request (when this request comes from the backend of the client app), and finally map the userinfo object as a response to the userinfo request.
I really hope someone have time to point me in the right direction. Thank you so much in advance.
Edit:
I have added a sequence diagram to explain it better:
I need to intercept the authorization request call to pick up a custom query param (endUserString) that identifies the user. There will be no user login form. I need the param in my code that uses this towards the REST API. Both the token and the userinfo must be received from my APP and not from keycloak itself.
The Java Mediator may ask for a token in advance (A) and use this to access the Rest API (using a predefined clientId and clientsecret). Alternatively this token may be fetched for each method. To token must be used to retrieve customer info from the REST API (B). I want to wrap this with OIDC support without any login form. A browser will just redirect to the authorization flow with the endUserString identifying the end user. The customer info will be returned from the java mediator into keycloak responding this in the GetUserInfoRsp.
I think there might be a simpler solution than what you envisioned: implementing your own custom authenticator for Keycloak.
Keycloak has a notion of authentication flow which is a tree of authenticators than are provided by Keycloak or custom made. Each authenticator can be called to try to authenticate the user.
The most common one is the Username/Password Form which displays a login page to the user and authenticates the user if the provided credentials are valid. But you could imagine any type of authenticator such as an SMS authenticator or a magic link one.
You can find the existing Keycloak's authenticators on their repo and the documentation on how to create your own here.
In your case, you would need to implement your own logic where your authenticator would get the endUserString param from the request and call the REST API to validate the user's identity. You could fetch the REST API token at initialisation or for each request. You could also modify the user stored in Keycloak with data coming from the REST API's user info endpoint (common OIDC attributes or custom attributes).
Please note that the dev team announced Keycloak X, a sort of reboot of the project which will probably bring breaking changes to their APIs.
Also, please consider all the security impacts of your design as, from what you provided, it seems the authentication of a user will only rely on a simple query parameter which, if it doesn't change over time for example, feels like a big security hole.
I'm implementing an authentication and authorization mechanism to unify login mechanism's across three different websites using an external identity provider and OAuth2.
The requirements that are causing design implications.
- Users and permissions managed externally to the existing websites in an external identity provider.
- The user should only have to log in once.
- The login screen needs to be embedded in our application rather than using an identity providers.
I'm creating a login web application. I'm not sure which OAuth2 flow to use. I've used the Authorization code flow previously with Spring security, but that seems to need an external identity provider's login form.
Should I use the implicit flow directly from the login site's javascript? How concerned do I need to be that it's not as secure as the code flow.
Do I need to handroll a solution to call an idp's sdk to get tokens and then sling them into http headers for subsequent use by the other domains Presumably CORS will be an issue? I'll need to include the id token for the other domain to know which user it is - is it secure to pass around the id token via the resource user's browser.
thanks for any guidance, as you can tell its a bit of a muddle in my mind!
I am starting a new project and using javascript based UI as fronted and google cloud endpoints backed by google datastore for data storage.
I don't need to use any of the google services for user login etc. In other words, i will have my own table to store username, pwd and other profile info.
So, the questions are:
1. How will my service based frontend will hold the session?
2. How will it understand that requests are going for which user account to return user specific data?
Also to start with, I have so far created an endpoint which basically returns true or false on passing username to it. (just to mimic valid user or not).
The question is do i really need to configure any security to invoke this api from the javascript client i have?
Even if you want to use custom usernames and passwords, you'll need more than just a process to send and retrieve this data from your endpoint.
Consider using something that's there already. E.g. webapp2 has a basic auth module which allows you to have your own database with usernames and passwords but already has many required security measures in place.
A tutorial I've used to implement this in the past: https://blog.abahgat.com/2013/01/07/user-authentication-with-webapp2-on-google-app-engine/
So the basic answer is Google Cloud Endpoints is best suited for applications which users google accounts as authentication mechanism.
So if you are using cloud endpoints, and wanted to have custom authentication mechanism, you have to create your own.
How will my service based frontend will hold the session?
Upon successful authentication (by any form either user credentials, third party social login etc), you need to setup session for that user eg; by using session cookies.
How will it understand that requests are going for which user account to return user specific data?
Cloud Endpoint cannot tell that, so you have to write an custom filter or interceptor to check if valid session or cookie exists and either reject or continue the request.
To pass the current authenticated user who is requesting the api, you need to inject the user informations somehow (using DI, or request properties etc) into the ApiEndpoints, so with that you can process the request accordingly
I have to build a Centralized Authentication And Authorization Service. I am trying to use the JASIG CAS. But its mentioned that its a authentication protocol.My scenario is as follows.
My application redirect to cas server on the first access.
CAS redirect the user for google authentication
User signs in with the desired email and redirect back to CAS
At this moment i need to validate the user in my local jdbc store for user enabled or not and if not already registered user, and the email domain is abc.com i need to auto register the user.
CAS redirect to the calling service
My service do the validateService api call. I would like to get the user authorities for the requested service in the result response from the CAS
Does this scenario can be achieved by CAS, if extension possible for CAS, can someone suggest how to do that, basically the classes that i need to modify
Does this scenario can be achieved by CAS
Jasig CAS is highly customizable and because it is build with spring framework and spring security you can extend it to any your needs.
basically the classes that i need to modify
classes of your interests are:
PolicyBasedAuthenticationManager
Entry point into authentication subsystem. It accepts one or more
credentials and delegates authentication to configured
AuthenticationHandler components. It collects the results of each
attempt and determines effective security policy.
AuthenticationHandler
Authenticates a single credential and reports one of three possible
results: success, failure, not attempted.
PrincipalResolver
Converts information in the authentication credential into a security
principal that commonly contains additional metadata attributes (i.e.
user details such as affiliations, group membership, email, display
name).
Jasig CAS is well documented. you should be able to find all information that you need there.