I have a hopefully quick question about Spring Security.
I am looking for a solution to integrate security into our application which provides SSO but HTTP basic as well.
One of the automated pieces of our system can only support basic authentication and we are pretty locked into it. Currently we are targeting to use Kerberos for our SSO solution and then also support basic (for very restricted usage). All of this will protect RESTful web services that run through resteasy.
Does anyone see any inherent impossibilities in this solution of both Kerberos and BASIC chained together in spring security? We had problems with WildFly and undertow not being able to support multiple different authentication methods, that use HTTP response codes in their handshakes.
Thanks for the input
Since this question is a bit tough, I assume you are already familiar with the Spring Security Kerberos samples that show how to configure kerberos auth with a form auth as fallback.
I have no evidence that it'll work but I think you should be able to chain your kerberos auth with basic auth without any problems. I share my thoughts on this...
Thought 1: FilterChains
The trick to support mulitple authentication methods is to set the order of the authentication filters correctly.
If the order is wrong, the client could hang in the basic auth and might never reach the kerberos authentication filter, because the browser's basic auth dialog would pop up. This might depend a bit on how the basic auth provider and filters are implemented in Spring. Anyway, if the order is correct, the filter next in chain after the kerberos filter (the basic auth filter) will start its work.
Thought 2: Kerberos auth shouldn't break basic auth
The browser should treat the communication with the kerberos service provider different to the communication with the basic auth provider, since the protocols are different.
The SAML communication runs in it's own namespace, thus in my opinion it shouldn't affect the basic auth communication which is based on authorization element in the HTTP header.
EDIT: Even if the assumption about the namespace doesn't play any role in the browsers behavior, step 6 in the sequence diagram will be a crucial point. When the filter chaining is correct, Spring should return a 401 response like 401 - Access denied - WWW-authenticate - Basic realm = "your domain" which will force your browser into basic auth.
Thought 3: Spnego Negotiate in Spring Security Kerberos
The Spnego configuration in the Spring Security Kerberos documentation is acutally build upon those thoughts. This can be seen in the samples, too, in line 49 and 50 of this WebSecurityConfig.java
I would be surprised if you experience troubles.
One last thought
If no requirements force you to do a basic auth, I would recommend to not use it. Better stay with a token based authentication. Even if I don't fully agree on all details of this blog it explains why basic auth shouldn't be used, if you can avoid it.
I strongly recommend you read Mika's answer. It is very well done and gave me the confidence to move forward.
Ultimately this worked; but I will explain a couple sticking points I had.
I use Request matcher's to split my calls into different HTTP configuration blocks
In order 1 I configured a block to filter in requests from a specific tool, by user agent. In that block I configured basic authentication in basically the standard OOTB way. I did write and provide my own authentication provider though, this provider called to an underlying system we use to manager our users by username / password.
Then, in order 2, I configured a block to process Kerberos. After wrestling with the Kerberos provider configuration and coming up with a scheme to authenticate in our underlying system, this all processed fine. After getting the username from Kerberos for the domain user connected to my web app, I then checked to see if that username was in my system. If they are, we log them in. If not, we direct them to the login page. (Not every domain user is authorized for our web app, even if they are authenticated)
Then finally, the last block was configured for form authentication.
But there were a few sticking points.
I had to globally configure the authentication manager for both my custom basic/form and the Kerberos provider.
And also as a side note, I did have to configure my authentication manager bean like this link suggests. Probably due to the cobbled together shamble of of xml/java configuration I have created.
IE was also weird. Down my kerberos chain, I also configured a login form. This allowed users who qualified for the chain to navigate directly to the login form to authenticate; or if someone failed my Kerberos username check I could forward them to the login page. This worked fine with FireFox, but IE continues to send the Negotiate header even after my server sent a redirect. Basically the user fails kerberos, gets a redirect to the login page, but IE sends the Kerberos token along still. This causes the SpnegoAuthenticationProcessingFilter from Spring Security to fire again and validate the Kerberos token, of course this fails again, and sends the user the login page which continues the loop.
In summary Spring Security allowed for 3 nice, fairly clean blocks which all do various different authentication / authorization, and then it all works in tandem to provide the same user context object to our web app.
Related
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!
TL;DR
Objective: Java authorization server:
OAuth2.0 authorization code grant flow with fine-grained permissions (not a mere SSO server)
User management and authentication: custom database
Client management and authentication: Keycloak
Questions: What are the best practices for implementing a Java authorization server with applicative permissions handling backed on Keycloak?
What Keycloak adapter/API should I use in my development?
How should the users be managed/appear in Keycloak if they are to appear at all?
Forewarning
I am quite the beginner with Keycloak and, though I think I understand the main principles, it seems to be a rich tool and I fear I may still be mistaken about some aspects of the best ways to use it. Please do not hesitate to correct me.
Context
We are looking at implementing an API requiring our users (henceforth "users") to grant permissions to third party applications (henceforth "clients").
Our users are stored in a custom existing database-based user management system. As for our clients, we are thinking of using Keycloak.
The users consent will be given using an OAuth2.0 Authorization code grant flow. They will log in, specify which permissions they grant and which they deny, and the client then retrieves the access token it will use to access the API.
It is my understanding that Keycloak can handle the authorization token but it should not know anything applicative, which our permissions are. As a consequence, I thought of building a custom authorization server which will use Keycloak for all identity/authentication problems but will handle the applicative permissions by itself.
Then, we will use Keycloak for client authentication and authorization code/access token management, and an applicative part will check the permissions.
Problem
Besides my first experimenting, I've been roaming the Internet for a week now and I'm surprised as I thought this would be quite a standard case. Yet I found next-to-nothing, so maybe I'm not searching correctly.
I've found many Spring/Spring Boot tutorials1 on how to make a "simple authorization server". Those are mainly SSO servers though, and few do manage permissions, with the exception of those mentioned in this SO answer2. That I think we can deal with.
The real problem I have, and that none of the tutorials I have found are treating, is the following:
How do I integrate Keycloak in this authorization server?
I've been having a look at the available Java Adapters. They look OK when it comes to authenticate but I did not see hints about how to manage clients from a custom authorization server (ie administer the realm).
I therefore suppose I should use the admin API. Am I correct and is it good practice? I saw no adapter for that, so I suppose I should then use the REST API.
I also wonder how we should integrate our users in design? Should they be duplicated inside Keycloak? In this case, should we use Keycloak's admin API to push the data from the authorization server or is there a better way?
Finally, am I missing some other obvious point?
Sorry for the long message and the many questions, but it all boils down to one question in the end:
What are the best practices when building an authorization server using Keycloak as a backbone?
1. Some examples:
Spring Boot OAuth2 tutorial -
A blog post -
Another blog post
2. I've mainly focused on the sample app provided by Spring Security OAuth
Building Java OAuth2.0 authorization server with Keycloak
This is possible but is bit tricky and there is lot of thing which needs to be customised.
You can derive some motivation from below repo.
keycloak-delegate-authn-consent
Building custom Java OAuth2.0 authorization server with MITREid
If you are open to use other implementations of Oauth and OIDC,I can suggest you MITREid which is referrence implementation of OIDC and could be customized to a great deal.Below is the link to its repo and its open source.
I myself used this to requirement similar to yours and it is highly customizable and easy to implement.
https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server
MITREid Connect uses Spring Security for its authentication, so you can put whatever component you like into that space. There are lots of good resources on the web about how to write and configure Spring Security filters for custom authentication mechanisms.
You'll want to look at the user-context.xml file for where the user authentication is defined. In the core project this is a simple username/password field against a local database. In others like the LDAP overlay project, this connects to an LDAP server. In some systems, like MIT's "oidc.mit.edu" server, there are actually a handful of different authentication mechanisms that can be used in parallel: LDAP, kerberos, and certificates in that case.
Note that in all cases, you'll still need to have access to a UserInfo data store somewhere. This can be sourced from the database, from LDAP, or from something else, but it needs to be available for each logged in user.
The MITREid Connect server can function as an OpenID Connect Identity Provider (IdP) and an OAuth 2.0 Authorization Server (AS) simultaneously. The server is a Spring application and its configuration files are found in openid-connect-server-webapp/src/main/webapp/WEB-INF/ and end in .xml. The configuration has been split into multiple .xml files to facilitate overrides and custom configuration.
I'm about to implement user authentication in my app.
Since it is my first Angular + Spring project i would like to know what are the possible options for authentication. I don't wait for detailed instructions, concept level is enough, so that i know where to dig.
I consider two ways of further back-end app development:
REST like;
regular spring MVC, however i don't know how to combine angular and spring in this case. Any suggestions in this regard are also appreciated.
There are various ways to accomplish this. The general idea is that the angular clients adds a credential to every request (typically in the authorization header) which a servlet Filter on the backend verifies before executing the request.
There are various standard ways to accomplish this, ranging from simple HTTP Basic Authentication (which spring security can do easily) to full fledged single sign on protocols like OAuth 2 (and its extension OpenID Connect).
I've heard that jwt has drawbacks, one of them is impossibility to block user until his jwt token is expired, which is pretty important in my case
Not necessarily. JWT is a standard for authentication, not access control. That is, it simply describes a way to identify users, but does not constrain how you make access control decisions. In particular, it is entirely possible that an authorization framework will load user permissions for every request, though doing so may not be its default configuration.
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 looking to add single sign on (SSO) to one of my web applications. I don't want anything heavy at the moment, I just want to know the userId of the logged in user, without the need for them to enter a username.
The web app is an internal application, so I can guarantee they are coming from a Windows PC etc.
I have looked at jCIFS, but this doesn't seem to be supported any more, and recommends a commercial product.
I have also looked at WAFFLE, but I am building SSO for a playframework application, which does not use a Servlet stack, so I can't make use of the SecurityFilter. I have tried to make sense of the WindowsLoginModule, but couldn't really understand what I had to do to implement it.
Is it possible to just get the username from the HTTP header, or does it require some negotiation first before it will post the header?
You want the windows user to automagically login to your intranet webapp. So the user accounts would sit in an active directory and the usual microsoft way would be to use a protocol like NTML oder Kerberos. Applications are generally advised not to use NTLM, although there are enterprises still using NTML (and jCIFS) for SSO.
A quick search on Kerberos and Java showed this article. It seems to depend on the Java EE stack (JAAS).
For a more stripped down approach: Usually, you cannot sent the username in a http request in a portable way. With ActivX you could do:
var wshshell=new ActiveXObject("wscript.shell");
var username=wshshell.ExpandEnvironmentStrings("%username%");
On the server side, you can parse the http header and extract the username with your technology of choice.
Well, security doesn't matter in your playframework application?
Why don't you use long-living cookies?
Hope it helps!
In an intranet context with ActiveDirectory and workstations registered in the domain, the HTTP SPNEGO Negotiation support is the best option. But it requires specific skills around ActiveDirectory and Java Kerberos implementation.
Spring Security provides implementation and documentation to set it up. But Secure.Security is not designed to support token-based authentication like HTTP Negotiation. So using Spring Security will require a specific integration module.
Other options are OpenID and shibboleth but both requires a dedicated server, which can be configured to do SPNEGO itself. Thanks to available Play modules, integration in your application will be easier.
The only way to get the username in an HTTP header without client-side complex and unsecure/unreliable tweaks is to use an authentication proxy between browsers and your application server. Most of these proxies also support Kerberos SPNEGO as authentication mean.
Non-heavy answer
It sounds like it should be possible to get your ops team to implement a Group Policy which will send the logged-in username down the wire as an HTTP Header.
Otherwise, you're correct in your assumption that there is some sort of negotiation "dance" between IE and your server. See here. Perhaps you can fake this dance in your Play code.
Heavy answer
I know jCIFS and this example uses servlets and filters, but the important bits of code can be extracted and a custom Play Authenticator can be built (I can paste a Scala example override of play.api.mvc.Security.Authenticated , but your answer is tagged Java). You only need the request headers (not body) so it should be doable in an authenticator.
PS jCIFS seems to have had an update since your post, so I'm presuming you'd reconsider using hacking it. I'm wary of unmaintained libraries too, but sometimes they just reach a maturity and stability which alleviates the need for any more updates.
Active Directory uses Kerberos, so all logged in users should have a kerberos ticket.
A fast google found this:
https://blogs.oracle.com/wyllys/entry/kerberos_web_authentiation_with_apache
If you want the windows logon details, I think it's your only option.
You can try to use Shiro for enabling SSO in your application.
Shiro id independent of the servlets and since your framework does not support Servlets you can very easily go for Shiro.
You can create a Realm where you define the hashPassword.
You can configure the username and the hashPassword and ask the shiro to authenticate your user with the hashPassword.
You will then assign role for the user which will serve your purpose of SSO.
You can authenticate user for more than one application and hence when user logs into another application the shiro has already authenticated you and hence it will straight away log you inside the application..
You can go through the shiro documentation(exhaustive and you should be able to configure it on first go) from the following link:-
http://shiro.apache.org/
It provides you many out of the box functionality for authenticating and authorization along with security and Cryptography modules.
The username isn't sent in the header. Even if it was this shouldn't be relied upon as a savvy user could fake the values.
If NTLM would be a valid option for you Jespa might be a good alternative to JCIFS. Jespa (unlike JCIFS) supports NTLM v2, among other things. The limited version of it (up to 25 users) is free.
You can always get any header from filter. See javadoc for HttpServletRequest.