I have a Java web app which provides a search service, and in some cases needs to check security for results. If it matters, it's implemented in Spring MVC and running under jetty.
I have a customer who would like the web app's authentication to:
It this possible, and if so, how?
(Apologies if the Windows world terminology is a bit off - it's not something I know much about, but hopefully at least the intention is clear)
A few notes on pieces of the puzzle I've already looked at:
I've seen http://blogs.objectsharp.com/post/2010/09/10/Converting-Claims-to-Windows-Tokens-and-User-Impersonation.aspx and https://msdn.microsoft.com/en-au/library/ee517278.aspx but I'm unsure:
I think the second (impersonation) part is roughly the same as Impersonating ASP.NET claims identity to windows identity, except that I want to do it from within Java rather than .Net.
You don't mention the ADFS version?
You have three choices:
In the Java world, SAML is normally used. Which implies a SAML stack.
The SO link above has an answer from me with links to a list of SAML stacks.
Since you are already using Spring, Spring Security seems a good fit.
Spring Security SAML Extension
ADFS currently does not support OpenID Connect which rules OAuth out.
Yes - Spring Security provides you with a list of the claims generated by ADFS.
ADFS does provide impersonation via Identity Delegation.
Unfortunately, this is typically done via WCF and WIF (both .NET constructs).
I have a similar application- mine is a Swing client rather than web application, but the process should be similar. It needs to submit queries under an assumed role using an AWS API after first authenticating with an on-premise ADFS server. In our environment, ADFS has been configured to give out SAML assertions and AWS has been configured to recognise these. So, this is what I do:
When required, the application prompts the user for their usual network credentials and these are used to request a SAML assertion from ADFS. I use Apache HttpClient to make the call:
private String getAdfsResponse(String username, String password) throws Exception {
log.debug("Trying to log onto ADFS server for {}", username);
// Lax redirect policy is needed so that all HTTP 302 redirects are followed after hitting the initial ADFS URL.
try (CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build()) {
HttpUriRequest login = RequestBuilder.post()
.setUri(new URI(ADFS_URL))
.addParameter("UserName", username)
.addParameter("Password", password)
.build();
CloseableHttpResponse response = httpClient.execute(login);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity responseEntity = response.getEntity();
String adfsResponse = EntityUtils.toString(responseEntity, "UTF-8");
log.debug("ADFS server responded with {}", adfsResponse);
return adfsResponse;
} else {
throw new Exception("ADFS server responded with " + response.getStatusLine());
}
}
}
If the credentials are validated, ADFS returns a SAML response that looks like an HTML form but contains a input
element with a SAMLResponse
name/value pair.
When the SAMLResponse
value
attribute is base64-decoded it will contain the SAML assertion. For AWS, I need to extract some role information and I use this, along with the full SAMLResponse
, to call the AWS STS (security token service). If all is OK with AWS, I receive a set of temporary security credentials that I can use for the queries I really want to make. The whole round trip is described in http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml.html
All this depends on ADFS and the other party being SAML-configured, and for the other party to provide a suitable API that lets you assume a particular role on their side. Is this the sort of thing you're facing?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With