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.
Related
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 have a springboot application which uses usual HTTP basic authentication using spring-security-ldap.
Later I modified it to use Single Sign On (Kerberos) authentication using spring-security-kerberos-core and spring-security-kerberos-web.
Everything is working fine so far.
Now I need to use both mechanisms. The idea is to use SSO for the front-end application, so that users are logged in automatically. And to use HTTP basic (username/password) for REST interface or for testing.
Probably I need to have two entry points (e.g. '/login' for SSO and '/login-userpass' for HTTP basic). Is it a correct approach? Or are there other ways to implement it?
It seems to me a common requirement but I'm not able to find examples of how to implement this.
EDIT:
Actually, it's a duplicated question. And the accepted answer works perfectly.
I have not used Kerberos with Spring, but I have previously implemented an application with both basic, form and CA SSO. However without looking at some code, particularly WebSecurityConfigurerAdapter I can only give general guidlines.
With Spring you need a number of authentication filteres mapped to different URLs, these will intercept the login, do 401 challenge if needed, and then create an unauthenticated Authentication instance. The typical filters are BasicAuthenticationFilter and UsernamePasswordAuthenticationFilter, and you need to find the one for KerBeros.
Later the unauthenticated authentications are give to the AuthenticationProviderManager which find the appropriate AuthenticationProvider to perform the authentication. This is where you do you database query with password hash (potentially SSO callback) and if the user is authenticated you create a new Authentication, typically you would want to extend AbstractAuthenticationToken or select one of the existing authentication. Remember to copy the details for the unauthenticated Authentication.
In Spring 4 AuthenticationProvider are configured using AuthenticationManagerBuilder, this is done in the configure method of WebSecurityConfigurerAdapter which you need to override.
Remember that you can have a single filter and many AuthenticationProviders or many filters and a single AuthenticationProvider, depending on your needs.
The application I have access to at the moment has a single form login, but some additional hidden fields (and stuff in the session), controls which of the 4 available AuthenticationProviders will be responsible for authentication, and different Authentication classes are created based on which provider authenticated the user, so we can restrict some areas of the application to specific Authentication types.
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 a Restful Java Web application which is to be deployed to a number of different environments (outside of my control) which will be using a SAML 2.0 SSO solution.
My application (which I believe is the "service provider") needs to store state generated by the user, and uses internal business logic to work out which users are allowed to view or update other user's data. In order for this to work we need to know who the user is, and what groups the user is part of. But how do I get this information?
Ideally my web app will be SSO agnostic, and would look for some configurable key headers in the http requests to get this information e.g. a SAML token in a request which could be parsed, or perhaps some custom headers specific to my "service provider".
Many Thanks
You are correct, your application is the Service Provider and you will have an external Identity Provider (IdP) to authenticate to.
Basically you need to issue an Authentication Request to the IdP (via either front channel HTTP POST or back channel SOAP/whatever they support) and use the authenticationResponse from the IdP to make your decision on whether they are who they say they are. As a rule you should be able to get the subject principal (ie username) and any group memberships from the authnResponse however exactly how this works will depend on what the IdP is or isn't configured to do.
Before you do this you will need to exchange SAML metadata with the IdP (this is generally part of being registered as a SP with the IdP) which gives both parties things like the public X509 cert for signing and validating requests.
There's a good spring library for SAML SP support, http://docs.spring.io/autorepo/docs/spring-security-saml/1.0.x-SNAPSHOT/reference/htmlsingle
you could run a reverse proxy in front of the Java web application to handle the SSO protocol part and relay user identity information to the application in HTTP headers; for SAML 2.0 there is mod_auth_mellon: https://github.com/UNINETT/mod_auth_mellon
If this is done in Java and running on a webcontainer (Tomcat, JBoss, etc.), then the agent could be implemented as a web authentication (servlet) filter (add into web.xml). The user would be typically derived from the SAML Auth response's <saml:NameID> or from <saml:Attribute> matching the userid attribute (uid,email, etc.). This user should be validated against the web app's identity repository (could be LDAP, database, etc.) and corresponding groups computed. Instead of using arbitrary headers or custom representation for the authenticated user, consider using java Principal (for users and groups) in a Subject.
The filter can then run the rest of the filter chain in a Subject.doAs(). That way, the Subject can be looked up any where in the downstream code using Subject.getSubject().