Ldap Authentication not working with spring boot - spring-boot

I am able to get LDAP authentication working with spring boot ActiveDirectoryLdapAuthenticationProvider. Same code works in other client environments, but somehow with one client it is not working.
I am able to connect to LDAP and bind and also reach the roodn, all is working fine.
In search filter, in place of using default one i.e.:
(&(objectClass=user)(userPrincipalName={0}))
I am using:
(&(objectCategory=person)(objectClass=user)(sAMAccountName={0}))
I have tried a lot of search filters, but nothing seems to work.
Can anyone please help on this, don't have much knowledge on LDAP.

The question is really if you should match by userPrincipalName or sAMAccountName. That really depends on what your users expect.
The sAMAccountName is what you would normally think of when you say "username".
The userPrincipalName looks like an email address. It's usually the same as the sAMAccountName followed by # and the domain DNS name, but it doesn't have to be.
You can see here for more information on that: User Naming Attributes
Whatever value the user types in as the username should match the attribute you have chosen here.

#gariel user is expecting to strictly login only using sAMAccountName. I got the login working with email ID (&(objectClass=user)(userPrincipalName={0})) filter. But to make it work with sAMAccountName with their LDAP, changing it to (&(objectClass=user)(sAMAccountName={0})) just doesn't work. Their sAMAccountName and userprincipalname are not same.
As a work around, instead of completely depending on spring security for authentication,
user inputs the sAMAccoutName, and i intercept the request using a custom filter. In the custom filter, using JAVA code i query LDAP to provide me with the emailId of that sAMAccountName. Once i have the emailID of the user, i update the username field in the request from sAMAccountName to emailID and then proceed the authentication request forward(remember i already had the LDAP authentication working with emailID).
In SecurityConfig file : .addFilterBefore(new CustomFilter(), UsernamePasswordAuthenticationFilter.class)
CustomFilter is where i am doing everything mentioned above.
Now everything works fine, but i have new issue. When user successfully authenticates, if user is not present in local db and doesn't require any authority it works fine. But the user is defined to be ADMIN in local db, and post authentication we provide it with the ADMIN authority, for some reason because of the custom filter it goes into a loop.

Related

Spring Boot Security registration and logging for website with roles, how to do it?

I have a difficulty in understanding Spring Security and any tutorial I found was not tailored to my needs. So maybe I'll explain what I think and what I want to accomplish.
I want to create a website with Kotlin/Java backend and frontend in React. This website would need to have users with different roles (user, admin).
And (I think) the thing I need is some kind of backend that has 2 endpoints:
register (to create users in database)
login (to, based on username and password, fetch user info and role) - as some kind of token? This returned token would be then used by frontend to display specific options (i.e. do not display "ban user" for regular users) and it also would be sent to backend for checking if the person who requests for specific endpoint really should be able to call this endpoint (i.e. it should be forbidden for regular users to use "ban user" endpoint)
What should I read about, what keywords should I look into to achieve this?
For purely the Spring Boot part of the implementation, the following should do
(/register) Signup/Register endpoint taking all required parameters for your business logic. e.g Username , Password , Full Name as well the roles
(/login) For logging in , you need a token forwarded to the front end, which will then use this token in the header for the session. JWT tokens seems like what you need(sample below). For the other part of your requirement, you can keep the user object (with roles) in the session as well as check user role on the backend in the "ban user" endpoint and process accordingly.
JWT Authentication with Spring Boot
I found a good starting point in the following sample
https://github.com/bezkoder/spring-boot-spring-security-jwt-authentication
For a more complete example
https://www.bezkoder.com/spring-boot-react-jwt-auth/
Credits to
https://www.bezkoder.com/
I have come a cross Youtube Video that covers all the scenarios that your looking for and extra, with Email verification links as well. i hope this will definitely help you
Java Tutorial - Complete User Login and Registration Backend + Email Verification

Spring security go to different application for authentication with request parameter

I have one application(Application1) which is SSO enabled and in that URL there is one parameter passed by user which is used along with userid and password for authentication.
For ex: Andrew works in Project department, and there are lot of other departments also. To login into the application he will type URL first as: http://myapp.com/project and then this login page will ask for userid and password. To authenticate Andrew all 3 things are taken into consideration. Userid, password, and department(passed in URL).
Now I am creating another application (Application2) which has spring security. So for authentication purpose I need to go to my Application1 and pass the department from Application2 in the URL. Once the user is authenticated I need to come back in Application2.
I am able to redirect to Application1 from Application2 by using .formLogin().loginPage() but have no clue in passing the department to URL runtime and come back to Application2 after authentication.
Please help me here.

Spring Security Kerberos SSO for a REST API (Tomcat)

Here is my problem:
Context :
-Windows Server 2012 with ActiveDirectory
-Tomcat
-Rest API (Spring)
I'm currently trying to restrict REST request. I want that only specific groups of the AD could access to specific resources. I'm restricted to Kerberos authentication.
System configuration
Create a user in domain "Tomcat"
setspn -a HTTP/apirest.domain#DOMAIN
Generate a tomcat.keytab using ktpass
API rest configuration
I'm using the spring security sample on github that you can find here :
https://github.com/spring-projects/spring-security-kerberos/tree/master/spring-security-kerberos-samples/sec-server-win-auth
I know that there is an EntryPoint and this is not needed in my context (API Rest). I've chosen this sample because it seems to use the windows authentication context and use it to automatically authenticate me in the spring security context. Right after, an ldap request is send to extract all information about the user logged. In my case, I need to extract the group.
I'm also using :
https://github.com/GyllingSW/kerberos-demo
To extract the role of the user with the class "RoleStrippingLdapUserDetailsMapper.java" instead of the "ActiveDirectoryLdapAuthoritiesPopulator". This implementation also offers localhost authentication but the issue with the NTLM token seems to be fixed in last commit of spring security.
I'm not really sure if this is the right way to do what I want.
My authentication seems to fail and I only have one things going wrong in my logs..
"Property 'userDn' not set - anonymous context will be used for read-write operations"
Questions
Do I have to run my tomcat service using the tomcat account ? (Seems to be, yes)
Am I doing the right things with Kerberos security ?
How can I get rid of the anonymous context?
The anonymous context seems to be set just right after Tomcat start. I want to get a context just after that my user (For instance, user1) requests the rest API (EntryPoint or whatever)
If there is something unclear let me know, I will try to reformulate!
Thanks,
You do not need to query LDAP to get information about which groups does user belong to. Active Directory already adds this information to the Kerberos ticket which is sent from browser to Tomcat.
You just need to extract this information from the token for example using Kerb4J library. It comes with Spring integration inspired by spring-security-kerberos project so it should be pretty easy to switch to it.
If you still want to query LDAP you need to authenticate in LDAP before you can make any queries. Again there's no need to use end-user accounts for it - you can use the keytab file for Kerberos authentication in LDAP and query groups using "Tomcat" account
I found a way to fix my issue.
In a REST API context, you have no entry point. I tried to set my entry point to an unmapped URL, just to do the negociation. By doing this, you will receive an HTTP response with the error code 404 (Not found) but with the right header was added by spring security (WWW-Authenticate).
The web browser will not send the ticket service if the error code is not 401.
To solve this problem, you have to create a CustomEntryPoint class (implements AuthenticationEntryPoint) and you need to override the "commence" method to return a 401 HTTP code with the right header.
I hope that could help. If there is a better way, let me know !

Spring security - Is username and password must for creating authentication

I am using spring security to authenticate a user. The user is authenticated by a third party and will already be authenticated when he reaches my application.
To implemented this, I have simulated a Authentication object.
I don't have any username and password and instead just have identifier. I check if this identifier is valid or not using my custom code.
My query is as follows:
Do I require a username and password to create a authentication object.
I have done without providing username and password and my application works fine.
I just want to ensure that I am using spring-security correctly.
Is there any impact of not putting username and password in Authentication object. I read below in AbstractUserDetailsAuthenticationProvider:
// Ensure we return the original credentials the user supplied,
// so subsequent attempts are successful even with encoded passwords.
I have also implemented a custom provider.
What does above comments means?
Is my approach correct?
The Authentication interface in Spring Security represents a token for carrying out validations against the configured security rules and the current call context. This interface has six methods of interest - getPrincipal, getCredentials, getDetails, getAuthorities, isAuthenticated and setAuthenticated.
Since you are authenticating users on your own, you should be mostly concerned with calling setAuthenticated(true) at an appropriate stage in the flow so that isAuthenticated starts returning true to indicate an authenticated user. Additionally, you may add GrantedAuthoritys to the Authentication for any role-based checks to work correctly.
However, it will be useful to make sure that getPrincipal (username in the case of form login) returns a unique value per user or per session. This will prevent the possibility of user sessions getting interchanged due to non-unique principal, which is used by the framework to identify users uniquely.
You may leave getCredentials and getDetails unimplemented. In fact, getCredentials (password in the case of form login) should be left unimplemented in your case because your application does not have the credentials used to actually authenticate the user; plus, it is a security risk to keep the credentials around after the user has been authenticated successfully.

Spring Security REST Api for non-authorized connections

I have an application and API. I am using Spring and Spring security for both. Authentication is required to access API.
I configured RESTFUL web service only respond when authentication is successful (handling with JSESSIONID after login) which makes querying database not possible if user is not logged in or credentials are wrong. But somehow, I need to access database and make some changes for forgotten password. I need to check if requested email is on the record. Also, update the database after password change. eg; If I make 'UPDATE USER' action permitAll(), there will be a security problem.
Can you give me some ideas to handle that problem?
You can create some user with permissions to change password and later when changing password automaticly login this user -> send request ->logout user and all of that behind user view.

Resources