I was previously using basic auth but I need to switch to federated auth using Ping Access. The user is already authenticated and the username along with the token are sent in the request header. How do I link the username to an ldap user principal using spring security?
-
Can you provide a little bit more detail? For example, is the token you receive from Ping Access a SAML token? If not, what kind of token is it and how would it get verified? It it's a saml token, take a look at `spring-security-saml`. As for looking up via LDAP, you should be able to query a user details service just by the principal value (e.g. the subject). Perhaps with more detail I can be more helpful. – jzheaux Aug 13 '18 at 22:09
-
@jzheaux, it's a jwt token. I'm able to validate this token with Ping Access. The username is in the 'sub' field of the header. I have extended the OncePerRequestFilter class. In the doFilterInternal method I want to map the username to the ldap principal so i can create a new Authentication object – Vibhav Agaskar Aug 13 '18 at 23:23
1 Answers
So, there are a number of things to consider as you are considering your implementation. Here is a very basic rundown of the pieces in play.
Filter Chain
The filter chain is typically for differentiating between servlets and the rest of the app. If you have extended OncePerRequestFilter
then you are likely already on the right path.
If you intend to follow the typical Spring Security model, this filter would prepare an Authentication
object that can then be authenticated in an AuthenticationManager
. You might try and use an existing Authentication
implementation like PreAuthenticatedAuthenticationToken
, or you might create your own and call it JwtAuthenticationToken
.
Authentication Manager
AuthenticationManager
is essentially a collection of providers that can authenticate a token, like your Jwt token. Their contract is separate from servlets and are therefore a bit more flexible.
You would probably create a JwtAuthenticationProvider
that would validate the token and then invoke a UserDetailsService
to get the underlying user.
Spring Security doesn't have dedicated support for JWTs, but they do have some libraries that use Nimbus. You could check out the code in spring-security-oauth2-resource-server to see how they are verifying JWTs using a JWK Set Uri. You wouldn't want to depend on that library since it is focused on OAuth, but it might give you some ideas.
User Details Service
A UserDetailsService
implementation is responsible for querying a backend and retrieving from it a user. For example, there is LdapUserDetailsService
that you could possibly use.
Summary
So, with all of that said, here is a summary of what I would probably do:
Create a
JwtAuthenticationToken
object that can house the jwt token and possibly represent a successful authentication when Spring Security completes the verification process.Create a
JwtAuthenticationFilter
that reads the token from the request and populatesJwtAuthenticationToken
, sending it to anAuthenticationManager
.Create a
JwtAuthenticationProvider
that reads aJwtAuthenticationToken
and sends it to Nimbus (or Auth0 or some other jwt library) for validation. You will need to decide how you trust that token--Nimbus is capable of checking remotely via a JWK Set Uri or locally via a pre-configured set of public or symmetric keys. (Lots to think about here, too!)Use the
LdapUserDetailsService
, passing it the name of the parsed subject. TheUserDetails
that comes back can be supplied as the principal for theAuthentication
object that your provider returns.
Alternatives
So, let's say that you don't want/need to follow the Spring Security development model, but just want to get something working asap.
The two things that you ultimately need to accomplish are
- Decide whether or not the token is valid. Spring Security has no OAuth2-free support for this yet, so you will need to roll your own using Nimbus or the like.
- Configure and invoke
LdapUserDetailsService
. From theUserDetails
this gives you, you can build anAuthentication
object that you can set on theSecurityContextHolder
.
Such would be not as flexible over time, but it might get you started a bit faster.
Other things to think about
You didn't ask about this, but I wonder what you are planning on doing if the token is somehow invalid. For those cases, you may want to look at AuthenticationEntryPoint
s and AccessDeniedHandler
s.

- 7,042
- 3
- 22
- 36