Check validity of username and password before authentication process - spring-security

I am using Spring Security 3.2.5. I use ActiveDirectoryLdapAuthenticationProvider for my authentication provider. But I want to check my username and password before authenticating through Active Directory.
For example, Before authentication process starts via Active Directory, I want to check that username and password are not equal and there is no space in them or their size is not smaller than special size.
Update:
Spring Security does not allow empty username and/or password and raise this exception:
Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials.
I have looking around in different filters and I think I should do this checking in UsernamePasswordAuthenticationFilter but I am not sure and I don't know how to do it. I highly appreciate your help.
Thanks in advance.
Best Regards,
/Samaneh

By default Spring Security should error if the user attempts to submit an empty username or password. As far as testing password criteria prior to LDAP authentication attempt, that seems inherently insecure. By testing a precondition you may give an attacker insight as to what the password may be. Additionally, short circuiting the LDAP binding attempt would effectively circumvent any maximum invalid attempt threshold configured in Active Directory.
Simply put, when it comes to authentication, we don't want to give the user any specific details other than the username and password you provided were wrong.

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.

Spring Security (basic-authentication) - receiving 401 Unauthorized for correct credentials

I am trying to add a basic authentication security layer over a REST service that I developed using Spring boot 4.3.
I have essentially did two main things:
Implement UserDetailsService interface to provide user details. Here I read from a text file the usernames and the encoded (via Bcrypt) passwords.
I declare a bean as follows in my #EnableWebSecurity annotated security configuration class:
#Bean
public BCryptPasswordEncoder getPasswordEncoder () {
return new BCryptPasswordEncoder();
}
to return the specific password encoder.
I am testing the authentication using rest clients both ARC (for Chrome) and REST Client of Firefox.
The issue is as follows:
When I enter my credentials for the first time and upon successful authentication, the response is 200 OK. This is true for a bunch of users. In other words, as long as I supply correct pair of credentials I get a 200 response.
But, after a single request with incorrect credentials the authentication process breaks down. Sometimes I get 200 and other times a 401 even for correct credentials. Other users authentication is affected as well, at this point of time.
There is a curious log that appears at step 2:
WARN 6813 BCryptPasswordEncoder : Empty encoded password
To elaborate a bit on the hashing of the passwords, I ran the Bcrypt password encoder utility and encoded a bunch of passwords and saved them manually in a text file for the corresponding user names.
I am unsure where the issue lies: whether the clients caching the credentials or the Spring security context caching the incorrect principal or the user details service breaking down (no such exception in the logs though).
Any help is appreciated. If you need any further specific information, please do let me know.

HTTPURLSession digest authentication with HA1 (not password)

Simply I have scenario where digest authentication is performed using user name and HA1 value (which was calculated somewhere in the past or it was provider by authentication to other server). Password is not available.
Now how do I handle this scenario using NSURLSession?
Do I have to do it manually (calculate HA2 and response my self) or is there some solution for that? (it should be there since keeping password as plain text is a security issue).
Please note the I have scenario where HA1 comes from authentication to other server so NSURLCredential persistence with value NSURLCredentialPersistencePermanent doesn't resolve my problem.

Is oauth2 insecure?

I am implementing an oauth2 solution for an API i've created and i'm struggling with the potential insecurites (or my understanding at least).
Is it correct that only a single token is generated and used as authentication credentials for an endpoint request. What's stopping a potential brute force attack where an attacker simply submits tokens to the API in the hope that one will be valid and in use?
I've probably misunderstood something but i can't get for the life in me what it is.
Tokens should be difficult to imagine of course. They should not be simple sequential integers for example. There is also no limit on the token length. There are basically two options:
1) build a long token encrypted using your own key (note: it does not have to be long, but it will since cryptography will make it long implicitly). You can check on return the token is really yours because you're the only one that can encrypt and decrypt these tokens.
2) build tokens that are also stored in your database, and are reasonably difficult to create, so you will check the tokens exists in your database.
You can also mix the two approaches. You should also add some expiration time to the tokens (either embedded in it in the 1st case, or aside the token in the database in the 2nd case).
One of the most vulnerable grant types in OAuth 2.0 for Brute Force Attack is Resource Owner Password Credentials type. In such a case, hacker has access to client credentials (clientId and password) and he/she only requires resource owner (user) credentials (username and password).
There is an authentication implementation model described in Java - Spring Security here that would shed some light to avoid this issue.

Remember me in Spring security to remember only user-name

I am using Spring security in my application and wish to know if there is a way to "ask" spring to only remember the user-name of the user that comes to the application (by means of the remember-me checkbox).
What I could gather from the reference documentation is that Spring is able to save the userName and the password of the user, and directly log him/her in the next time. But what I want is that user be taken to the login page each time he comes back, but with his user-name already typed in.
Ofcourse if Spring doesn't have a way to do this, I would need to implement some cookie storage logic to take care of this requirement.
Many thanks for your answers as always.
So, you need to set a cookie containing the user name after authentication, and access it during rendering of the login page.
If you use Spring Security 3.x, the former can be done by subclassing AuthenticationSuccessHandler (SavedRequestAwareAuthenticationSuccessHandler is the default implementation) and setting a cookie with response.addCookie().
The latter is a regular cookie access (request.getCookies(), etc).

Resources