I will continue from where I’ve finished in this post. You can customize my development according to your structure. The previous actions does not necessarily have to be done for Spring Security integration. But if you do, you will have Spring + Spring Security together.
My structure will be like below:
My pom.xml for dependencies is like:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mydomain</groupId> <artifactId>SampleSpringProject</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>SampleSpringProject Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <spring.version>4.0.1.RELEASE</spring.version> <spring.security.version>3.2.0.RELEASE</spring.security.version> <jack.version>1.9.13</jack.version> <jdk.version>1.7</jdk.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>${spring.security.version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>${spring.security.version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>${spring.security.version}</version> </dependency> </dependencies> <build> <finalName>SampleSpringProject</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>${jdk.version}</source> <target>${jdk.version}</target> </configuration> </plugin> </plugins> </build> </project>
My application-servlet.xml file will be like below. mvc:resources tags are not necessary for Spring Security configuration. Serving static files from outside of the classpath is best practice for resources.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- Scan for components under this package --> <context:component-scan base-package="com.mydomain" /> <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --> <mvc:resources mapping="/js/**" location="/assets/js/" /> <mvc:resources mapping="/css/**" location="/assets/css/" /> <mvc:resources mapping="/images/**" location="/assets/images/" /> <mvc:resources mapping="/**" location="/htmls/" /> </beans>
Then my web.xml file for this structure will be like below. Spring Security related things start from the comment. The rest of the file is about Spring configuration.
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>Sample Spring Project Application</display-name> <servlet> <servlet-name>application-servlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/servlets/application-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>application-servlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/root-context.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Spring Security --> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
Then we define Spring Security resources and activate annotation base driven development style of Spring in our root-context.xml file:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- Scan for components under this package --> <context:component-scan base-package="com.mydomain" /> <!-- Enables the Spring MVC @Controller programming model --> <mvc:annotation-driven /> <!-- Import spring security configurations --> <import resource="classpath:spring/spring-security.xml" /> <!-- Import Beans --> <!-- <import resource="classpath:spring/hibernateBeans.xml" /> --> <!-- <import resource="classpath:spring/springBeans.xml" /> --> </beans>
Then one of other important configuration file is spring-security.xml. In http
tag, use-expressions property enables to use ‘hasRole’ expression inside the intercept-url
tag. In this tag we define which pages are spring secure and what is our logout url. Then we define our custom authentication provider class. We just reference it from this xml and put @Component annotation to Java file.
<beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd"> <http auto-config="true" use-expressions="true"> <intercept-url pattern="/**" access="hasRole('ROLE_USER')" /> <logout logout-url="/logout" /> </http> <authentication-manager alias="authenticationManager"> <authentication-provider ref="customAuthenticationProvider" /> </authentication-manager> </beans:beans>
Now, I will talk about necessary classes. Actually we don’t have to implement all of them but this development style provides us more flexibility which we desire. Below you will see CustomAuthenticationProvider class code. This is the main class for customization. Even if you don’t implement other classes from Spring Security interfaces, this class will be enough for custom authentication system. We must implement AuthenticationProvider interface from Spring Security. Note that @Component annotation and the name of class and name in the spring-security.xml file.
package com.mydomain.security; import java.util.Collection; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.GrantedAuthority; import org.springframework.stereotype.Component; import com.mydomain.model.User; import com.mydomain.service.UserService; @Component public class CustomAuthenticationProvider implements AuthenticationProvider { @Autowired private UserService userService; @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String username = authentication.getName(); String password = (String) authentication.getCredentials(); User user = userService.loadUserByUsername(username); if (user == null) { throw new BadCredentialsException("Username not found."); } if (!password.equals(user.getPassword())) { throw new BadCredentialsException("Wrong password."); } Collection<? extends GrantedAuthority> authorities = user.getAuthorities(); return new UsernamePasswordAuthenticationToken(user, password, authorities); } @Override public boolean supports(Class<?> arg0) { return true; } }
Below, there is a UserService which implements Spring Security UserDetailsService. We need to implement loadUserByUsername method that returns Spring Security UserDetails object. In my development, I implement both UserDetailsService and UserDetails class. I choose to return my own User object from loadUserByUsername method.
package com.mydomain.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.mydomain.dao.UserDao; import com.mydomain.service.UserService; import com.mydomain.model.User; @Service public class UserService implements UserDetailsService { @Autowired private UserDao userDao; @Override public User loadUserByUsername(final String username) throws UsernameNotFoundException { return userDao.loadUserByUsername(username); } }
In UserDao class, I will create a sample User object for test. Probably you want to access database and get user information from there.
package com.mydomain.dao; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Repository; import com.mydomain.model.Role; import com.mydomain.model.User; @Repository public class UserDao { public User loadUserByUsername(final String username) { User user = new User(); user.setFirstName("firstName"); user.setLastName("lastName"); user.setUsername("user"); user.setPassword("1111"); Role r = new Role(); r.setName("ROLE_USER"); List<Role> roles = new ArrayList<Role>(); roles.add(r); user.setAuthorities(roles); return user; } }
Below class is a custom User class which is returned by UserService loadUserByUsername method.
package com.mydomain.model; import java.util.Collection; import java.util.List; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; public class User implements UserDetails { private static final long serialVersionUID = 1L; private String username; private String password; private String email; private String firstName; private String lastName; /* Spring Security fields*/ private List<Role> authorities; private boolean accountNonExpired = true; private boolean accountNonLocked = true; private boolean credentialsNonExpired = true; private boolean enabled = true; @Override public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @Override public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return this.authorities; } public void setAuthorities(List<Role> authorities) { this.authorities = authorities; } @Override public boolean isAccountNonExpired() { return this.accountNonExpired; } public void setAccountNonExpired(boolean accountNonExpired) { this.accountNonExpired = accountNonExpired; } @Override public boolean isAccountNonLocked() { return this.accountNonLocked; } public void setAccountNonLocked(boolean accountNonLocked) { this.accountNonLocked = accountNonLocked; } @Override public boolean isCredentialsNonExpired() { return this.credentialsNonExpired; } public void setCredentialsNonExpired(boolean credentialsNonExpired) { this.credentialsNonExpired = credentialsNonExpired; } @Override public boolean isEnabled() { return this.enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("User [username="); builder.append(username); builder.append(", email="); builder.append(email); builder.append(", password="); builder.append(password); builder.append(", firstName="); builder.append(firstName); builder.append(", lastName="); builder.append(lastName); builder.append(", authorities="); builder.append(authorities); builder.append(", accountNonExpired="); builder.append(accountNonExpired); builder.append(", accountNonLocked="); builder.append(accountNonLocked); builder.append(", credentialsNonExpired="); builder.append(credentialsNonExpired); builder.append(", enabled="); builder.append(enabled); builder.append("]"); return builder.toString(); } }
This class has a Role object which will be used for authorization. Role object implements Spring Security GrantedAuthority interface. getAuthority() method must be overridden for implementation. Role object has a list of privileges. This privileges will help us to evaluate permissions in our development.
package com.mydomain.model; import java.util.List; import org.springframework.security.core.GrantedAuthority; public class Role implements GrantedAuthority { private static final long serialVersionUID = 1L; private String name; private List<Privilege> privileges; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String getAuthority() { return this.name; } public List<Privilege> getPrivileges() { return privileges; } public void setPrivileges(List<Privilege> privileges) { this.privileges = privileges; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Role [name="); builder.append(name); builder.append(", privileges="); builder.append(privileges); builder.append("]"); return builder.toString(); } }
Below there is a basic Privilige class code:
package com.dataxpert.model; public class Privilege { public String getName() { return name; } public void setName(String name) { this.name = name; } private String name; @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Privilege [name="); builder.append(name); builder.append("]"); return builder.toString(); } }
With this configuration and code, everything works fine for me. If you encounter any problem, please let me know and we’ll work together on it.
NOTE: Please consider the below comment from Stacy and cleanup toString() method from sensible information.
If you are using psi-probe to monitor a Tomcat instance (for example), the toString() method will enable the password to be visible in cleartext via the Spring session attribute SPRING_SECURITY_CONTEXT
Developers Rock!!!
Thanks for the code. This is really helpful.
Could you please send me the code. Or have you uploaded it to GitHub?
Hi,
You can able to find the code here: https://github.com/aykutakin/SampleSpringProject
Please, don’t hesitate to ask any question about the code or post
Hi,
Thanks for putting this full working example on Github!
Do you think you could add a few simple test cases in there as well, just to show us how to test our code?
Many thanks in advance!
Hi, I want to know where have you specified the code or template for Login Screen in project
Hi,
Actually, I haven’t specify any code piece for login screen. If you don’t do anything about login page, Spring will show its own default login page and this example works with this way. If you want custom login page, you can check new version on github. I put some commented out parameters to spring-security.xml file for custom login page.
https://github.com/aykutakin/SampleSpringProject
Thank you for the post.
Pingback: REBLOG: Spring Security (+Spring) Custom Authentication Provider | vrsbrazil
Thanks a lot!
but, I have a question…..
How can I get the User parameter on Web page?
Hi,
It has been a long time to check my blog. So, I am sorry for the very late answer. In my personal projects, I use Jackson for returning JSON elements to requests. You can supply user information from controller when you making requests with this way. If you are using old way jsp, you can check out this sample. In this example, Mkyong returns “Spring Security Hello World” string as a message. You can return your user information with the same way if you want.
You got it wrong aykut, I am pretty sure he knows how to transfer model to jsp.. He asks about accessing your user object.
@kihong
Go to CustomAuthenticationProvider.java, find authenticate method,
change return line as:
return new UsernamePasswordAuthenticationToken(user, password, authorities);
In one of your controller write:
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
User user=null;
if (principal instanceof User) {
user = ((User)principal);
}
modelandView.addObject(“user”,user);
Here is your user with all data of it. Use it in view (jsp) like ${user.email}
Hi,
You are right, I may have understand question a little bit wrong. Also, this post becomes a little bit old, I need some changes and put user object to security context like you do. Please keep me updated when you see something wrong at blog.
Thank you.
Hi
For this we have a spring security tag library tag this tag has access to the currently authenticated
object (principal).
Excellent. Thanks for posting this.
Thank you! Great posting, very helpful to me.
How can you have return type “User” from the “loadUserByUsername()”? Mine says it has to be “UserDetails”
Regards
Wow, nevermind. Spoke to soon. Saw that you implemented UserDetails
I’m glad you find out the case:) If you have any other problem please write me back.
You have done great Job!!!!!!!! Thanks a lot.
Very helpful post, thanks!
I have a question as a beginner in Spring Security. I wasn’t able to figure out how UserDetails and UserDetailsService interfaces are being used in this example. Put in other words, if I remove them what are the effects? Are they really necessary?
Hi,
Like I said, they are only for more customization. If you remove them and return UsernamePasswordAuthenticationToken object from authenticate method in different way, there should be no problem. In my example, I add some different variables like FirstName, Lastname, etc. to User object. In my opinion, both username and first name should be belong to same user object. With this way, I encapsulate all user information in one object.
Good example, but…did you know that your controller isn’t invoked at all?
Just like everything Spring, straightforward and meaningful examples are hard to find. I appreciate sharing the code, but I wasted lots of time trying to find out why your MVC wiring wasn’t working. Please, incorporate my changes and push them to your github, so we save someone else’s frustration. Thanks!
I had to make to following changes to get the example to work the way I guess it was intended to:
web.xml:
change
application-servlet
/
to
application-servlet
/*
application-servlet.xml:
I needed to add component-scan and its namespace – The controller wasn’t instantiated at all.
The other change was to do with mapping of the jsps so your controller can hit them as views:
changed to
Please, compare and incorporate
LoginController:
You really shouldn’t have a value of “/” at Request mapping, unless you expect people to always type that “/” after login so
@RequestMapping(method = RequestMethod.GET, value=”/”)
became
@RequestMapping(method = RequestMethod.GET)
Thanks!
The markup got eaten up by wordpress. I posted the my modifications here:
https://github.com/boyko11/SampleSpringProject-Modified
Thanks!
Hi,
Thanks for warnings. I made necessary changes to make controllers work.
Regards
I am new to spring and spring security as well. I just wanted to know how does the authentication-provider that referes to customAuthenticationProvoder knows to look into the CustomAuthenticationProvider.java to authenticate.
And what is the purpose of that text box “enter your name” ?
Thanks in advance
Hi,
In the spring-security.xml we define our custom provider. If you look at the line 20 in the spring-security.xml, you can see that we refer to ‘customAuthenticationProvider’ and Spring search for this class. And the purpose of that input is just filling the page:) There is no action about that box, I just put that box to see css is working.
Regards.
Thank you for your reply 🙂 !! Also I am actually trying to implement a 3 step process where the user 1st logs in then gets an authorization code and then with the code gets the token and finally the rest api. Do you know how /oauth/authorize is related to /oauth/confirm_access because when I use your custom log and redirect to /oauth/authorize I am getting a 404 not found I thought the configuration will handle the authorization but I am missing something that I dont understand.
Thank you for your reply. I wanted to know if there is a way in which we can pass one more information along with username and password so that it can identify which database to look into. Or is there a way to do that in configuration itself ?
Thanks in advance
Hi,
I do some researches and found this stackoverflow post. I hope it will help you.
Regards
thanks for your post!
Hello,
Great post!!
Maybe you can help me on my problem!!!
In my application, there is differents parts. And for each parts, a connected user could have different role. For example, in part1 the user is ADMIN and in part2 he is USER.
the “simple” hasRole(‘ROLE_ADMIN’) is not enough for me, I would rather a thing like
hasRole(‘ROLE_ADMIN’, partId) which help me to check if the user has the ROLE_ADMIN for these partId.
Do you think it is possible ?
I continue to search, and thank you for your return.
Regards
Maybe when the user log-in and go to the part1, i can associate his ROLE at this moment. When he changes to part2, i search his new ROLE and associate it to him.
By this way, hasROLE(‘ADMIN’) will be correct ???
Hi,
I searched a little bit, but I couldn’t find a way to use a function like hasRole(‘ROLE_ADMIN’,partId). I think the best solution for your problem is to assign two different role to the user. As you can see, user do not have to be assigned only one role. You may have PART1_ADMIN and PART2_REGULAR_USER roles and assign each role to the authenticated user. That way you don’t need to worry about anything.
And about other question: Yes you can change user’s role dynamically and with that way hasRole(‘ADMIN’) will be fine. I tried it and it worked for me.
Regards.
I’m wondering how can I put my custom error message in this setup? Preferrably using message.properties file so I can handle multiple language. In this case, the message will always be “Username not found”. thanks
Hi,
I have a post about serving messages from messages.properties file. Here is the link. You can have different messages files like: ‘messages_en.properties’ for English and ‘messages_fr.properties’ for French. When you change the locale property of Java, you will read different messages_XX.properties according to your locale. You can check java.util.Locale for different country codes. After changing static “Username not found” string with this dynamic method, you can easily handle with different languages.
Regards.
Thank you so much, i was having a hard time then i saw this post.
Thank you so much
Thank You
Hi Aykut, thank you for such a wonderful post.
But i could see one scenario which i believe you could help me .
I have created a separate index page where it has 2 links called admin and user. Now, you click on the admin and it takes you to the login screen where you type the normal user details and submit the form (not the admin’s username & password). It takes to the 403 access denied page. Now what you do is just go to the index page directly and click on the user link, you could login with out asking for the user name and password. What could be the solution for this. Please let me know.
Hi,
Sorry for very late answer. Unfortunately, I couldn’t understand your case. Can you send me a code sample please?
Regards
greate article
hi aykut akin,
Can i provide a base for grouping the functions(functional parts of an application) and authorization users/ user-groups against them. I’m new spring security and even to real time development. Any help would be much appreciated.
thanks,
nani
Why do you override User.toString()? I didn’t read anything in Spring Security documentation regarding the need to do so for objects implementing the UserDetails interface. Would this be necessary for web based applications or only for console applications?
BTW, Thank you great example.
Hi,
Overriding User.toString() is not necessary for implementing security using Spring. That is my regular development style to override toString() method for every model object. With that way, I can just pass object to logger or sysout and see the variable values of object. Otherwise you will see class name and memory reference like User@ff2413.
Regards
If you are using psi-probe to monitor a Tomcat instance (for example), the toString() method will enable the password to be visible in cleartext via the Spring session attribute SPRING_SECURITY_CONTEXT
Thanks for the catch. I believe there are now better ways to write this code piece. Therefore, I will not update the code but I’ll put a note at the end of this post.
Best regards,
Aykut
Hello Aykut:
first congratulate you on your blog. I want to ask: How can we customize the tag: , to perform a custom query about LDAP?
Thanks for you attention.
Hi,
Actually there are a lot of changes from defining ldap server to implementing LdapAuthenticationProvider. But, at the end userDetails stays the same. Main thing is to changing where to go for authentication and provider of this service. I believe you can check implementation steps from spring documentation.
If you are starting from scratch, you could follow this link. It uses Spring Boot and Spring Security. At first Spring Boot seems complicated and you may not want to include a new technology to your base. However, it makes a lot of thing easier when you get used to it.
Regards,
Aykut
Thanks for your answer. We try to authenticate with Microsoft Active Directory and have problems. I show our configuration, I appreciate you can give us some tips for this. We try to authenticate with a user that are created in a group that is not hanging directly from the domain.
configuration:
According to your reconmendación:
Class:
public class CustomAuthenticationProvider implements AuthenticationProvider {
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = (String) authentication.getCredentials();
if (username == null) {
throw new BadCredentialsException(“Username not found.”);
}
if (password == null ) {
throw new BadCredentialsException(“Wrong password.”);
}
try {
LdapContextSource ldapContextSource = new LdapContextSource();
ldapContextSource.setUrl(“ldap://****************:389/”);
ldapContextSource.setBase(“dc=***,dc=*****,dc=****”);
ldapContextSource.setUserDn(username + “@*******”);
ldapContextSource.setPassword(password);
try {
// initialize the context
ldapContextSource.afterPropertiesSet();
} catch (Exception e) {
e.printStackTrace();
}
LdapTemplate ldapTemplate = new LdapTemplate(ldapContextSource);
ldapTemplate.setIgnorePartialResultException(true); // Active Directory doesn’t transparently handle referrals. This fixes that.
AndFilter filter = new AndFilter();
filter.and(new EqualsFilter(“sAMAccountName”, username));
try {
boolean valido=ldapTemplate.authenticate(DistinguishedName.EMPTY_PATH, filter.toString(), password);
System.out.println(“valido :”+valido);
}
catch(org.springframework.ldap.AuthenticationException ee)
{
//userDisplay.setText(“Invalid Username/Password”);
}
} catch (Exception e) {
e.printStackTrace();
}
return new UsernamePasswordAuthenticationToken(username,password);
What is happening is that this class runs twice. The second time through the class “authentication” has the attribute with null password.
Can you help us please.
Hi,
I have never need to implement ldap authentication, however as my search on Spring blog and Stackoverflow you need to make your authentication trusted. To do that, either you call isAuthenticated method by yourself or add a role to UsernamePasswordAuthenticationToken. In my example, I get authorities from user object and pass it to UsernamePasswordAuthenticationToken. You can try below code just to check the problem is this.
Collection authorities = Collections.singleton(new SimpleGrantedAuthority("ROLE_USER"));
return new UsernamePasswordAuthenticationToken(username, password, authorities);
If this does not work, let me know and I will try to implement code by myself.
Regards,
Aykut
Hello I’m following your code and I need web.xml and other xml configuration into Java Config annotation.
Can you please provide use ?
Thanks
Hi,
You can find example on this link. I think all the information you need is there.
Please ask again if you need something else.
Regards
Hi,
Thanks for your code. it worked without any issues.
and it has saved lot of time for me.
Hi Ayukth, Thanks a bunch for the code and well explanations.
I tried to configure the application to login to my custom login page. But could not proceed. Please let me know what else needs to be done to achieve the custom page login when login button in a page is clicked.
My spring-security file looks like this.
Controller code.
@Controller
public class LoginController {
@Autowired
private UserService userService;
@RequestMapping(value=”/login”, method=RequestMethod.GET)
public String getLoginForm(){
return “login”;
}
@RequestMapping(value=”/logout”, method=RequestMethod.GET)
public String getLogoutForm(){
return “logout”;
}
@RequestMapping(value=”/secured/test”, method=RequestMethod.POST)
public String getData(ModelMap model){
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
User user=null;
if (principal instanceof User) {
user = ((User)principal);
}
model.addAttribute(“username”, “demouser”);
model.addAttribute(“message”, “Welcome to the secured page”);
return “home”;
}
}
Every other code is same as the original.
Gettng Null Pointer Exception on line 28 in Class CustomAuthenticationProvider.
java.lang.NullPointerException
com.treatmenttriangle.security.CustomAuthenticationProvider.authenticate(CustomAuthenticationProvider.java:28)
org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:177)
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:211)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
Best example for Spring Security….
Hey, I am working on something similar. I autowired in my CustomAuthenticationProvider but it seems not working. I am not sure what could the problem be. Any suggestions?
Hi, have you set CustomAuthenticationProvider class an authentication-provider like in the spring-security.xml?
hi aykytakin,
I need to integrate my own authentication which takes in username password and returns true or false in return.Can this be included in the the customAuthenticationProvider? I have a web app which needs spring web security integration. Please help as i am new to spring concepts. Also the roles will be provided against a usernames which will be present in a text file name=role.
Can u please give a head start to implement such requirement.
Hi Aykut
First of all thanks for this post. I am new to spring security and trying to understand use of Authentication provider, I created project as per this post.
I am trying to understand below portion from spring-security.xml file
I understand that authentication happens on first request that comes in. After the user has
been authenticated and tries to access another page, will CustomAuthenticationProvider call authenticate function all over again. If not, how does the application work until user signs out or timeout? If the information store somewhere in applications that the user has been authenticated and is used on request going back and forth
Thanks in advance!