Spring LdapTemplate authenticate and Heap Inspection attacks - spring-security

I am using the spring-ldap module specifically the LdapTemplate class for authentication with an LDAP Server. (authenticate methods)
http://docs.spring.io/spring-ldap/docs/current/apidocs/org/springframework/ldap/core/LdapTemplate.html
The issue I have with calling this method is that it uses a String for the password. That exposes these calls to Heap Inspection attacks because the immutable String hangs around in memory for a while until GC'ed after use.
Are there alternate ways to use this module so that we can pass a CharSequence instead that is zero'ed out after use?

Related

How to implement multiple authentication methods in Spring WebFlux Security?

I'd like to provide two ways to authenticate in my application, one is basic auth (users), and the other is some kind of token based (technical users). I understand that I need a custom ReactiveAuthenticationManager but I can't find clues on the big picture. (Actually, there are a very few insights for MVC, and none for WebFlux.)
1) How do I populate the Authentication's name and credentials in the token based approach? If I configure Spring Security to use httpBasic it's already populated. Some kind of filter needed?
2) How do I distinguish in the authentication manager where the credentials are coming from? Do I have to lookup in the userRepository and (if not found) in the technicalUserRepository too?
3) Do I have to override the SecurityContextRepository? All the tutorials do it but I don't see any reason to do so. What is it exactly? This source states that "SecurityContextRepository is similar to userDetailsService provided in regular spring security that compares the username and password of the user." but I think he means ReactiveUserDetailsService (neither UserDetailsService nor ReactiveUserDetailsService does that by the way, it's just for user lookup).
Since i am decent at Webflux and i have worked a lot with oauth2 i'll try and answer some of your questions.
1) How do I populate the Authentication's name and credentials in the
token based approach? If I configure Spring Security to use httpBasic
it's already populated. Some kind of filter needed?
A token never contains credentials. A token is something you get issued after an authentication has been done. So usually you authenticate against an issuing service. After you have authenticated yourself against that service you will be issued a token.
If its an oauth2 token the token itself is just a random string. It contains no data about the user itself. When this token is sent (using the appropriate header) to a service using spring security. Spring security has a token filter that will basically check that the token is valid, usually by sending the token to the issuer and asking "is this token valid?".
If using a jwt, its different, the jwt must contain some information like issuer, scopes, subject etc. etc. but its basically the same thing, there is a built in filter that will validate the jwt by sending it to the issuer (or using a jwk that the service fetches from the issuer so it can verify the integrity of the jwt without doing an extra request).
2) How do I distinguish in the authentication manager where the credentials are coming from? Do I have to lookup in the userRepository and (if not found) in the technicalUserRepository too?
You don't You usually define multiple SecurityWebFilterChains for different url paths. I have not done this in Webflux Spring Security, but thats how you do it in regular Spring Applications, and i don't see any difference here. Unless you are doing something crazy custom.
3) Do I have to override the SecurityContextRepository? All the tutorials do it but I don't see any reason to do so. What is it exactly? This source states that "SecurityContextRepository is similar to userDetailsService provided in regular spring security that compares the username and password of the user." but I think he means ReactiveUserDetailsService (neither UserDetailsService nor ReactiveUserDetailsService does that by the way, it's just for user lookup).
The answer here is probably no. You see Spring security 4 had very bad support for oauth2 and especially JWT. So people got accustomed to writing their own JWT parsers. When spring Security 5 came, Spring implemented a jwt filter that you can configure and use built in. But there are a lot of outdated Spring Security tutorials out there and foremost there are a lot of developers that don't read the official documentation.
They mostly google tutorials and get the wrong information and then work on that.
But easy explained:
SecurityContextRepository
If you have session based authentication (server establishes a session with a client) it will store the SecurityContext (session) in ThreadLocal during a request. But as soon as the request ends, the session will go lost unless we store it somewhere. The SecurityContextPersistenceFilter will use the SecurityContextRepository to extract the session from ThreadLocal and store it, most common is to store it in the HttpSession.
AuthenticationManager
Override this if you want to do a custom authentication process. Example if you want to validate something, call a custom LDAP, database, etc etc. It\s here you perform you authentication. But remember, most standard logins (like ldap, sql-servers, basic login etc.) already have prebuilt configurable managers implemented, when you select what login type like .httpBasic() you will get a pre-implemented AuthenticationManager.
UserDetailsManager
You override this when you want create a custom UserDetails object (also usually called Principal) In the UserDetailsManager you do you database lookup and fetch the user and then build and return a UserDetails object.
Those two interfaces are the most regular custom implementations, and are used if you need to to basic authentication/session based authentication.
If you wish to do token, you have to think about, who is the token issuer? usually the issuer is separate and all services just get tokens and validate them against the issuer.
I hope this explains some of the questions. I have written this on the bus so some things are probably wrong and not 100% correct etc. etc.

How to change password using Spring LDAP and Spring security

I'm using latest version of both Spring LDAP and Spring security. Also, I'm using annotation based configuration and I have no XML configuration files.
What I'm trying to achieve is really basic, I want to be able to allow users to change their password from my web application.
I've found that I could execute that request through DirContext.modifyAttributes. This method requires two attributes, the first one is the current userDn, which I'm not sure how to easily get through Spring. I'm pretty sure that there's a functionality to get it.
Then using a password Attribute as modification item for the second argument. Now, how can I know the password encoding that needs to be applied to the password provided by the user?
I've never used Spring LDAP / Security and a small, simple example would be awesome. Right now, I'm testing against in-memory ldap, but I'll have to switch to a real LDAP at the end of the week.
Thanks!
You need to use an instance of org.springframework.security.ldap.userdetails.LdapUserDetailsManager, it implements UserDetailsManager and has methods for changing user passwords. To instantiate it in your non-XML configuration, do something like this:
#Bean
public UserDetailsService getUserDetailsService() {
return new LdapUserDetailsManager(); // TODO give it whatever constructor params it needs
}

Getting sessionId without accessing the session

In my grails application I'm using the spring security core plugin.
Is there any method that returns me a jsessionid for a given user simply by providing username and password
Something like this jsessionid:
def myjsessionid = getJessessionidFromUser("username1", "password1")
I'm not familiar with grails, but Spring Security itself provides Concurrent Session Control that can maintain a SessionRegistry. This registry will contain info about all user sessions that you can query e.g. for getting the sessoin id(s) of a given principal.
Use SessionRegistry.getAllSessions() to obtain a list of SessionInformations related to a given principal/user, and then getSessionId() on those objects.
The concurrency control feature is normally used to limit the number of sessions a user may have, but it can be configured not to enforce such restrictions (just maintain the registry). See more about that in the Session Management chapter.

Spring Security - Is there a way to check if you're in a secured request?

I want to know if the request I am in is accessible anonymously, even if I am authenticated anyways.
I think the easiest idea is to extend AuthenticatedVoter and override its vote() method to save a flag in a thread-local whenever ConfigAttribute happens to be IS_AUTHENTICATED_ANONYMOUSLY. You can then inject your extended AuthenticatedVoter into your Spring Security stack.

Spring Security: IP Address Whitelist Before Deferring to HTTP Basic Auth

I have a single URL accessible through a servlet that I have locked down using Spring Security's DaoAuthenticationProvider. I now have the requirement that certain incoming IP addresses must be whitelisted and so are not requested to authenticate.
I can hack around this easily enough by overriding DaoAuthenticationProvider's authenticate method and bypassing the superclasses's implementation if the IP address matches a known IP address but this then only works when the sender of the request supplies a username and password (even if it's nonsense). Otherwise the provider doesn't get called.
What would be the best way to do this? Should I be using a filter to bypass the authentication procedure if a known IP address is incoming?
Could you just use the hasIpAddress() expression? We're doing that for what appears to be a similar case.
<security:intercept-url pattern="/services/**" access="hasIpAddress('192.168.1.0/24')"/>
I think the idiomatic Spring Security way to do it is to implement a pre-authentication filter that would populate security context with a valid Authentication object when client is in the whitelist. You can implement such a filter from scratch (for example, as here) or use AbstractPreAuthenticatedProcessingFilter (though it seems to be overcomplicated for your task).

Resources