Single Sign On [SSO] across different domains using Java - java

We are implementing Single Sign On [SSO] across multiple applications, which are hosted on different domains and different servers.
Now as shown in the picture, We are introducing a Authenticate Server which actually interacts with LDAP and authenticate the users. The applications, which will be used/talk to Authenticate Server are hosted across different Servers and domains.
for SSO, I can't use session variables, as there are different servers and different applications, different domains, a domain level cookie/session variable is not helpful.
I am looking a better solution which can be used for SSO across them. Any demonstrated implementation is existing? If so, please post it or point me in the right direction for this.

You can achieve this by having all your log-ins happen on the auth server. The other applications can communicate to the auth server through a back channel. The general principle is like this:
User accesses application 1.
Application 1 needs the user to sign on, so it sends a token to the auth server through the back channel. Application 1 then redirects the user to the log in page on the auth server with the token as a parameter on the request.
User logs in to auth server. Auth server sets a cookie, flags the token as authenticated and associates the user details with it. Auth server then redirects user back to application 1.
Application 1 gets request from user and calls auth server over back channel to check if the token is OK. Auth server response with user details.
Application 1 now knows that the user is authorised and has some basic user details.
Now this is where the SSO bit comes in:
User accesses application 2.
Application 2 needs the user to sign on, so it sends a token to the auth server through the back channel. Application 2 then redirects the user to the login page on the auth server with the token as a parameter on the request.
Auth server sees that there is a valid log in cookie, so it can tell that the user is already authenticated, and knows who they are. Auth server flags the token as authenticated and associates the user details with it. Auth server then redirects user back to application 2.
Application 2 gets request from user and calls auth server over back channel to check if the token is OK. Auth server response with user details.
Application 2 now knows that the user is authorised and has some basic user details.
There are some existing implementations of this method, for example CAS (Central Authentication Service). Note that CAS is supported out of the box in Spring Security. I would advise you look at using an existing implementation, as writing your own will be hard. I have simplified things in my answer and there is a lot of potential for introducing security holes if you're new to this.

I will recommend you check out OAuth. It is a good Authenticaiton and Authorization protocol used by several large organizations including facebook, google, windows live and others. It may have an initial learning curve, but it is a production grade solution.
It also has libraries for Java, Ruby, PHP and a range of other programming languages.
For example, the following server side implementations are available for Java.
Apache Amber (draft 22)
Spring Security for OAuth
Apis Authorization Server (v2-31)
Restlet Framework (draft 30)
Apache CXF
Following client side Java libraries are also available:
Apache Amber (draft 22)
Spring Social
Spring Security for OAuth
Restlet Framework (draft 30)
Please refer here for more details:
http://oauth.net/2/
http://oauth.net/documentation/

The bigger question is how you are implementing single sign on. Many open source and even proprietary (IBM Tivoli) offerings worth their salt offer cross domain single sign on capability. This would be the easiest and best way to implement cross domain sso. You can configure the LDAP server you use in the sso server you choose.
Taking for instance open sso, here is an article to configure cross domain single sign on
http://docs.oracle.com/cd/E19681-01/820-5816/aeabl/index.html
To configure LDAP in open sso,
http://docs.oracle.com/cd/E19316-01/820-3886/ghtmw/index.html
Reference on the issue is presented in a neat diagram here
http://docs.oracle.com/cd/E19575-01/820-3746/gipjl/index.html
Depending on which offering you use, you can configure cross domain single sign on.
With this, your diagram will look like this, with the auth server being your utility to interact with sso server of your choice.
Having an auth server that communicates with sso is a sound architecture principle. I would suggest making calls to authenticate as REst end points which could be called via http from different applications.

You cannot use Rest Service .
You could use what i call a Refferer Url Authentication
Say you have a Authentication application running on www.AAAA.com
In the applications , where you want to authenticate , you could have a filter which looks for a authenticated cookie in its domain else redirect to www.AAAA.com for authentication
On Successfull authentication , you could pass the user profile information as encrypted GET / POST data back to the application

Since I have built a Java application, I have been looking for an SSO solution for it. I found a free Java SAML Connector using which you can achieve SSO in java based applications built using any java framework.
Here's the link to it - https://plugins.miniorange.com/java-single-sign-on-sso-connector

Related

Web app security architecture

I have a Java Spring driven REST API server connecting with PostgreSQL database and a Spring Web Server in Java that is serving content from the REST API to the client using JavaScript (now browsers, but in the future also mobile apps).
I've read a number of articles and topics how one can secure a REST API, but I haven't been able to make a final decision yet. I don't want to have Basic Authorization, because it doesn't make sense as I would need to store credentials in JavaScript that can be easily accessed and read by anyone entering the webpage and developer console. I'd like not to show any credentials to the end user so I can't keep them on the client's side.
I've read a lot about JWT and almost decided to implement it, but I've heard it has some drawbacks and haven't been so sure since then if it's the option I would like to choose. I know there is also oAuth 1.0 or oAuth 2.0 but I don't know if I want to have something this complicated. I would also like to store hashed user credentials in my own database in order not to be depended to any other credential providers like social media or Google.
Now I'm making another layer on my web server as a proxy hoping that it will allow me to authenticate user on this proxy level using Spring Security and having some kind or cookies or something to authenticate, but I'm not so sure if its doable this way and it increases the respond time, adds complexity and needs me to write controller methods for these endpoints. My architecture now is of the following:
Client (browser) -> Webserver -> REST API server -> db
I've also denied all external connections and allowed only localhost access to REST API on tomcat level so that I'd have to implement the security level only on the web server allowing free information transit between the webserver and REST API as it is not reachable anyway.
Web server and REST API are on the same server running as Tomcat instances.
I'm also not so sure if this kind of architecture will allow me to authenticate mobile app clients through the web server.
I would be very grateful for any piece of advice you would have for me in this matter. I'm not so experienced in security, so I'm a bit lost what I should do. Does this kind of architecture any sense or should I simply ask REST API directly from any type of clients, be it a webpage or a mobile app from different IPs and secure Rest API only? And if I want to secure some subpages of my webpage or parts of mobile app should that be an completely other layer?
Thank you for your help.
You have already gone through OAuth, JWT tokens etc. If you don't want to use them,then you can create your own token based authentication system.(say 'TokenHandler').
How this TokenHandler will work ?
TokenHandler will be like a gateway server i.e your every REST API request will route through this server application. So you will address your confusion of mobile and web application call with a authToken in header. Main responsibility of this server applciation is to accept the token and validate against the database where all token details are maintain. This DB will have information regarding timestamp when token was last used to validate, to decide your validation rule .
How Token will get generated ?
Token can be any random 64 digit alphanumeric string and will be generated and updated in DB during every single login activity. Login webservice returns this token in response body.
What can be rules for validation ?
It can be depending on your business logic. I preferred to keep active session window of 15 mins. Means if you access the webservice you will get active window of 15 more minutes. If you didn't access any service for 15 consecutive minutes then from 16th Minute you will need to login again to access further calls. This part can change according to requirements.
How client side will handle this ?
Client side will store this token and pass this token with every request call. Token Handler will validate and redirects it's request to the application server . So your one token handler can be used to server authentication of multiple applcation servers. This you can achieve by application end point identifer.
I will like to discuss further if you have any questions or suggestions .
Use API Gateway Architecture Pattern for your use case -
http://microservices.io/patterns/apigateway.html .
The API Gateway (The webserver in your question) can act as single entry point for all desktop/mobile clients. You can use either session cookies or jwts to authenticate clients at gateway.
With respect to authentication between gateway and micro services, and between micro services, i would suggest mutual ssl - https://www.codeproject.com/Articles/326574/An-Introduction-to-Mutual-SSL-Authentication. If you are using spring boot, this might help - http://www.opencodez.com/java/implement-2-way-authentication-using-ssl.htm
The problem with IP white-listing approach is that - it's not well suitable for cloud architecture as the IPs might change with every server reboot. Even if you are using dedicated IPs, you should be careful to secure the communication with SSL/TLS, else attackers can easily sniff your traffic.

How to build central sign architecture with spring security and angularjs applications

I have 4 single page applications with same technologies: Spring MVC, Spring Security, Angulajs.
Each application has own ldap authentication and authorization. We want to build a single sign architecture and make a central authentication application. And make the other 4 application use this central application.
When user login into one of the apps, he should not need to login the others.
What is the easy way to implent this in server side and client side?
What you want is Single Sign-On (SSO). There are two options:
Use some existed SSO server like CAS.
Do it yourself using subdomain cookie technique.
First option is exactly what you want implement. When you open URL of app1 you will be redirected to SSO server and prompted for login/password. After successful authentication you will be redirected to app1 URL. Now if you open app2 URL you will be signed in automatically. One of advantages is that user password is stored only in SSO server.
Second option is more lightweight IMHO, because instead of using existed SSO server for sharing authentication information between your apps you use HTTP cookies. From the other side you need to write some minimal authentication code which may be less secure.
Subdomain cookie technique:
Use subdomains for all your apps (app1.domain.com, app2.domain.com)
When user connects to app1, generate some token (your session id), store it in some shared DB and as a cookie for domain.com
When user opens app2, check if token is present (as a cookie for domain.com), verify that it is valid (use shared DB) and allow access.
It is very simple algorithm that do not take into account all possible security vulnerabilities (like session fixation for example). So if you do not have enough time to solve them it may be better to go with first option.

OAuth + spring security for internal REST communication

Setup
We're developing a distributed application with Java and Spring where our existing client front end (complete with its own authentication, database, accounts, etc.) uses REST calls to access our new server for additional services. We want to protect these resources with Oauth.
Access should be restricted by role or account. However we don't want the user on the client side to have to worry about any additional authentication apart from the already existing account. At the same time we need to provide a means for third party applications to access some resources from the outside after going through some kind of registration against the server (which is why we're distributing in the first place).
So we have set up spring security on the server side to provide accounts that should be used to restrict access to the resources. The user should log in on the client side and then be able to access only those server resources assigned to him. We have some kind of registration process that sets up the user on the client side to be able to access the server services so any account setup I think should be done there.
So the questions are
How can I enable the client side to obtain an access token for the protected resources without the user having to log in to his server-side account?
And how do I setup the server side account without needing any user input?
My thoughts
This won't do
I'm thinking I'll have to either tell the client about a new account created on the server side for that user (but then, how would I choose and communicate a password?) or synchronize the client side account to the server, and use those credentials to authenticate the client against the server and generate access tokens. But how save can that be? Also the server has a much higher security (one way encrypted, salted passwords) on its accounts and I don't really want to compromise this by using the less save client accounts.
Maybe this will?
Maybe the way to go will be to tell the server about the client account during the first authentication, create an account on the server side, store the generated token on the client side and then authenticate the client against the server with that token for each subsequent request..? Will the server be able to log-in the client using its server-side account via that token for each request?
I'd need a special resource for that initial (2-legged?) handshake that can only be accessed from the client server, right?
Also:
Which would be better suited for the task, OAuth 1 or 2?
I'm hoping someone understands my problem and can help me sort through possible missunderstandings and knowledge gaps (I'm reading through Oauth and spring security documentations right now, so I'll update if I come up with a clearer picture and thus clearer questions of what to do)
Thanks for any help!
So our current status is to use OAuth2 mostly for reasons of simplicity. We're also sure that the flaws it might have concerning security we can cover ourselves as needed and they will most likely be addressed in the future by the implementation vendors or the IETF.
To handle the communication between REST server and REST client (both in our control) we use the formerly known as 2-legged authentication, now client credentials grant. I've asked a few questions on SO about that including
our current spring-security context setup
the client credentials flow in particular
the use of long lived tokens versus reauthentication
and how to limit REST access by HTTP method
Concerning the use of client based user accounts for authentication against the server we didn't get any further.
For now we authenticate the user against our old client web application as before and then authenticate the client against the server 2-legged. In theory this will allow any user to access any resource using the client accesstoken but for now that's okay for us so we will not investigate further down that road.
Still, should anyone have a good idea on how this might be solved we'll pick it up, just to tighten security further. So, I'll leave this question open.
My thoughts currently are along the line of registering a new client ID for each user on the authentication server with a generated secret and then synchronize those back to the client server and use those client_id / secret combinations to access resources for a user represented by the generated client_id in a client credentials flow.
For our latest application we'll store accounts on the REST server (authentication provider) and have the user login against that server and then use the token to access the REST resources as intended by the spec.

Secured authentication in web service

I am developing a web service using Spring framework for Java and deploy on JBoss AS. This web service needs authentication and authorization and security solution so that some method user A can execute and some other user B can execute. At client side, there will be an application calling to the web service and people may log in using either user account A or B.
I have been digging out the Internet, searching for web service authentication, researching on WS-Security but all that I can see is using WS-Security. WS-Security generally supplies 4 kinds of authentication:
UsernameToken
X.509 Token
SAML Token
Kerberos Token
But all those things are usually pre-configured and I find no example that suggest I should provide login/logout methods in the web service (by using stateful web service). Note that in case we use login methods then there are security risks even if the underlying is SSL transport.
So my question is:
What should I do to satisfy my requirements?
If using UsernameToken or Kerberos Token ... and we provide some privileges per user, i.e authorization, then for each incoming request, we must get the user information and get all its privileges. This process seems take time and decrease performance of the system. Do you agree? So I guess this is not recommended?
I would thank you so much for any response and will vote for any reasonable answer.
Your scenario mirrors that of EBay Trading API's.
Basically, it works as follow.
Provide a intial WS call (Ebay case: FetchToken) which confirms user's identity and return back authorization key (unique key for each logged in user). Store the authorization key along with user profile information in a cache/distributed cache .
Any subsequent call required client to pass the authorization key along with the data for the call. You will use the authorization key to get user profile information.
Provide the log out WS call. This invalidates the authorization key.
All the WS invocations should happen over SSL for security.
If your service is point to point, ssl is enough. Mutual ssl (Mutual_authentication) is widely used for client authN and authZ.
If you concert about performance of system, looking at SAML. SAML is a signed XML document that contains authN and authZ for client, that means you do not need to loop up on the server for client authN and authZ.

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