March 2, 2014 by Siva

SpringMVC4 + Spring Data JPA + SpringSecurity configuration using JavaConfig

In this article we will see how to configure and integrate SpringMVC4, Spring Data JPA with Hibernate and SpringSecurity using JavaConfig.

1. First let’s configure all the necessary dependencies in pom.xml



  4.0.0
  com.sivalabs
  springmvc-datajpa-security-demo
  1.0
  war 
  
	
		1.7
		4.11
		1.7.5
		1.0.13
		4.0.0.RELEASE
		1.4.1.RELEASE
		3.2.0.RELEASE
		4.2.6.Final
		1.7.2
		5.1.26
		2.3.1
		1.2.2
		3.1
	
	
	
		${project.artifactId}
		
			
				org.apache.maven.plugins
				maven-compiler-plugin
				3.1
				
					${java.version}
					${java.version}
				
			
		
	

	
	
		
			org.slf4j
			jcl-over-slf4j
			${slf4j.version}
		

		
			org.slf4j
			slf4j-api
			${slf4j.version}
		
		
		
			ch.qos.logback
			logback-classic
			${logback.version}
				

				
		
			org.springframework
			spring-context-support
			
				
					commons-logging
					commons-logging
				
			
		
		
		
			org.springframework
			spring-webmvc
		
		
			org.springframework
			spring-test
		
		
		
		
			org.springframework.data
			spring-data-jpa
			${spring-data-jpa.version}
		

		
			org.hibernate
			hibernate-entitymanager
			${hibernate.version}
		
		
		
		
			org.springframework.security
			spring-security-core
			${spring-security.version}
		
		
			org.springframework.security
			spring-security-web
			${spring-security.version}
		
		
			org.springframework.security
			spring-security-config
			${spring-security.version}
		
		
			org.springframework.security
			spring-security-taglibs
			${spring-security.version}
			
		
		
			org.aspectj
			aspectjweaver
			${aspectj.version}
		
		
			org.aspectj
			aspectjrt
			${aspectj.version}
			

		
		
			junit
			junit
			${junit.version}
			test
				

		
		
			mysql
			mysql-connector-java
			${mysql.version}
		
				
		
			commons-dbcp
			commons-dbcp
			${commons-dbcp.version}
		
				
		
			com.fasterxml.jackson.core
			jackson-databind
			${jackson-json.version}
		
		
		
		    javax.mail
		    mail
		    1.4.3
	    
	    
		
		
			javax.servlet
			javax.servlet-api
			3.0.1
			provided
		

		
			taglibs
			standard
			1.1.2
			compile
		
		
			jstl
			jstl
			1.2
			compile
		
	

	
		
			
				org.springframework
				spring-framework-bom
				${spring.version}
				pom
				import
					
		
	
	


2. Configure database connection properties and email settings in application.properties


################### DataSource Configuration ##########################

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=admin

init-db=false

################### Hibernate Configuration ##########################

hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update

################### JavaMail Configuration ##########################
smtp.host=smtp.gmail.com
smtp.port=465
smtp.protocol=smtps
smtp.username=sivaprasadreddy.k@gmail.com
smtp.password=
support.email=sivaprasadreddy.k@gmail.com

3. Configure common Service Layer beans such as PropertySourcesPlaceholderConfigurer and JavaMailSender etc in com.sivalabs.springapp.config.AppConfig.java



package com.sivalabs.springapp.config;

import java.util.Properties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.scheduling.annotation.EnableScheduling;

@Configuration
@ComponentScan(basePackages={"com.sivalabs.springapp"},
		excludeFilters=@ComponentScan.Filter(type=FilterType.REGEX, pattern={"com.sivalabs.springapp.web.*"}))
@PropertySource(value = { "classpath:application.properties" })
@EnableScheduling
@EnableAspectJAutoProxy
@EnableCaching
public class AppConfig 
{
	@Autowired
	private Environment env;

	@Bean
	public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer()
	{
		return new PropertySourcesPlaceholderConfigurer();
	}
	
	@Bean
	public JavaMailSenderImpl javaMailSenderImpl() {
		JavaMailSenderImpl mailSenderImpl = new JavaMailSenderImpl();
		mailSenderImpl.setHost(env.getProperty("smtp.host"));
		mailSenderImpl.setPort(env.getProperty("smtp.port", Integer.class));
		mailSenderImpl.setProtocol(env.getProperty("smtp.protocol"));
		mailSenderImpl.setUsername(env.getProperty("smtp.username"));
		mailSenderImpl.setPassword(env.getProperty("smtp.password"));

		Properties javaMailProps = new Properties();
		javaMailProps.put("mail.smtp.auth", true);
		javaMailProps.put("mail.smtp.starttls.enable", true);

		mailSenderImpl.setJavaMailProperties(javaMailProps);

		return mailSenderImpl;
	}
		
	@Bean
	public CacheManager cacheManager()
	{
		return new ConcurrentMapCacheManager();
	}
}

Observe that we have excluded the package “com.sivalabs.springapp.web.*” from component scanning using new REGEX excludeFilter type.
If we don’t exclude web related packages and tries to run JUnit test for service layer beans we will encounter the following Exception:

java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling

Also note that we have enabled Caching using @EnableCaching, so we should declare CacheManager bean.

4. Configure Persistence Layer beans in com.sivalabs.springapp.config.PersistenceConfig.java as follows:


package com.sivalabs.springapp.config;

import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.orm.hibernate4.HibernateExceptionTranslator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages="com.sivalabs.springapp.repositories")
public class PersistenceConfig 
{
	@Autowired
	private Environment env;

	@Value("${init-db:false}")
	private String initDatabase;
	
	@Bean
	public PlatformTransactionManager transactionManager()
	{
		EntityManagerFactory factory = entityManagerFactory().getObject();
		return new JpaTransactionManager(factory);
	}

	@Bean
	public LocalContainerEntityManagerFactoryBean entityManagerFactory()
	{
		LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();

		HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
		vendorAdapter.setGenerateDdl(Boolean.TRUE);
		vendorAdapter.setShowSql(Boolean.TRUE);

		factory.setDataSource(dataSource());
		factory.setJpaVendorAdapter(vendorAdapter);
		factory.setPackagesToScan("com.sivalabs.springapp.entities");

		Properties jpaProperties = new Properties();
		jpaProperties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
		factory.setJpaProperties(jpaProperties);

		factory.afterPropertiesSet();
		factory.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
		return factory;
	}

	@Bean
	public HibernateExceptionTranslator hibernateExceptionTranslator()
	{
		return new HibernateExceptionTranslator();
	}
	
	@Bean
	public DataSource dataSource()
	{
		BasicDataSource dataSource = new BasicDataSource();
		dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
		dataSource.setUrl(env.getProperty("jdbc.url"));
		dataSource.setUsername(env.getProperty("jdbc.username"));
		dataSource.setPassword(env.getProperty("jdbc.password"));
		return dataSource;
	}
	
	@Bean
	public DataSourceInitializer dataSourceInitializer(DataSource dataSource) 
	{
		DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
		dataSourceInitializer.setDataSource(dataSource);
		ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
		databasePopulator.addScript(new ClassPathResource("db.sql"));
		dataSourceInitializer.setDatabasePopulator(databasePopulator);
		dataSourceInitializer.setEnabled(Boolean.parseBoolean(initDatabase));
		return dataSourceInitializer;
	}	
}

Here we have configured DataSource and JPA EntityManagerFactory bean using Hibernate implementation.
Also we have configured DataSourceInitializer bean to initialize and populate our tables with seed data. We can enable/disable executing this db.sql script by changing init-db property value in application.properties.
And finally we have enabled Spring Data JPA repositories scanning using @EnableJpaRepositories to scan “com.sivalabs.springapp.repositories” package for JPA repository interfaces.

5. Now let us configure Web related beans in com.sivalabs.springapp.web.config.WebMvcConfig.java


package com.sivalabs.springapp.web.config;

import java.util.Properties;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;


@Configuration
@ComponentScan(basePackages = { "com.sivalabs.springapp.web"}) 
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter
{
	@Override
	public void addViewControllers(ViewControllerRegistry registry)
	{
		super.addViewControllers(registry);
		registry.addViewController("login/form").setViewName("login");		
		registry.addViewController("welcome").setViewName("welcome");
		registry.addViewController("admin").setViewName("admin");
	}

	@Bean
	public ViewResolver resolver()
	{
		InternalResourceViewResolver url = new InternalResourceViewResolver();
		url.setPrefix("/WEB-INF/jsp/");
		url.setSuffix(".jsp");
		return url;
	}

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry)
	{
		registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
	}

	@Override
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)
	{
		configurer.enable();
	}

	@Bean(name = "messageSource")
	public MessageSource configureMessageSource()
	{
		ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
		messageSource.setBasename("classpath:messages");
		messageSource.setCacheSeconds(5);
		messageSource.setDefaultEncoding("UTF-8");
		return messageSource;
	}

	@Bean
	public SimpleMappingExceptionResolver simpleMappingExceptionResolver()
	{
		SimpleMappingExceptionResolver b = new SimpleMappingExceptionResolver();
		Properties mappings = new Properties();
		mappings.put("org.springframework.dao.DataAccessException", "error");
		b.setExceptionMappings(mappings);
		return b;
	}
}

6. Configure DispatcherService using AbstractAnnotationConfigDispatcherServletInitializer convinient class.



package com.sivalabs.springapp.web.config;

import javax.servlet.Filter;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import com.sivalabs.springapp.config.AppConfig;

public class SpringWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{

	@Override
	protected Class[] getRootConfigClasses()
	{
		return new Class[] { AppConfig.class};
	}

	@Override
	protected Class[] getServletConfigClasses()
	{
		return new Class[] { WebMvcConfig.class };
	}

	@Override
	protected String[] getServletMappings()
	{
		return new String[] { "/" };
	}

	@Override
    protected Filter[] getServletFilters() {
       return new Filter[]{ new OpenEntityManagerInViewFilter()	  };
    }

}

Here few things to note are we configured AppConfig.class as RootConfig classes and WebMvcConfig.class as ServletConfigClasses which is similar to how we configure in web.xml using ContextLoaderListener and DispatcherServlet’s contextConfigLocation .
Also we have registered OpenEntityManagerInViewFilter to enable lazy loading of JPA entity graphs in view rendering phase.

7. Let us configure SpringSecurity.

First let us create a SecurityUser class which extends our application specific User class and implements org.springframework.security.core.userdetails.UserDetails.


package com.sivalabs.springapp.web.config;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.sivalabs.springapp.entities.Role;
import com.sivalabs.springapp.entities.User;

public class SecurityUser extends User implements UserDetails
{

	private static final long serialVersionUID = 1L;
	public SecurityUser(User user) {
		if(user != null)
		{
			this.setId(user.getId());
			this.setName(user.getName());
			this.setEmail(user.getEmail());
			this.setPassword(user.getPassword());
			this.setDob(user.getDob());
			this.setRoles(user.getRoles());
		}		
	}
	
	@Override
	public Collection getAuthorities() {
		
		Collection authorities = new ArrayList<>();
		Set userRoles = this.getRoles();
		
		if(userRoles != null)
		{
			for (Role role : userRoles) {
				SimpleGrantedAuthority authority = new SimpleGrantedAuthority(role.getRoleName());
				authorities.add(authority);
			}
		}
		return authorities;
	}

	@Override
	public String getPassword() {
		return super.getPassword();
	}

	@Override
	public String getUsername() {
		return super.getEmail();
	}

	@Override
	public boolean isAccountNonExpired() {
		return true;
	}

	@Override
	public boolean isAccountNonLocked() {
		return true;
	}

	@Override
	public boolean isCredentialsNonExpired() {
		return true;
	}

	@Override
	public boolean isEnabled() {
		return true;
	}	
}

We will implement a custom UserDetailsService and use Spring Data JPA repositories to load User details.


package com.sivalabs.springapp.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import com.sivalabs.springapp.entities.User;
import com.sivalabs.springapp.services.UserService;
import com.sivalabs.springapp.web.config.SecurityUser;

@Component
public class CustomUserDetailsService implements UserDetailsService
{
	@Autowired
	private UserService userService;
	
	@Override
	public UserDetails loadUserByUsername(String userName)
			throws UsernameNotFoundException {
		User user = userService.findUserByEmail(userName);
		if(user == null){
			throw new UsernameNotFoundException("UserName "+userName+" not found");
		}
		return new SecurityUser(user);
	}
}

Now create com.sivalabs.springapp.config.SecurityConfig.java which contains SpeingSecurity related bean definitions.


package com.sivalabs.springapp.config;

import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
//import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;


@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
	@Autowired
	private DataSource dataSource;

	@Autowired
	private CustomUserDetailsService customUserDetailsService;

	@Override
    protected void configure(AuthenticationManagerBuilder registry) throws Exception {
	/*
        registry
        .inMemoryAuthentication()
        .withUser("siva")
          .password("siva")
          .roles("USER")
          .and()
        .withUser("admin")
          .password("admin")
          .roles("ADMIN","USER");
        */
        
        //registry.jdbcAuthentication().dataSource(dataSource);
	registry.userDetailsService(customUserDetailsService);
    }


	  @Override
	  public void configure(WebSecurity web) throws Exception {
	    web
	      .ignoring()
	         .antMatchers("/resources/**");
	  }

	  @Override
	  protected void configure(HttpSecurity http) throws Exception {
	    http
	    .csrf().disable()
	    .authorizeRequests()
	        .antMatchers("/login","/login/form**","/register","/logout").permitAll()
	        .antMatchers("/admin","/admin/**").hasRole("ADMIN")
	        .anyRequest().authenticated()
	        .and()
	    .formLogin()
	        .loginPage("/login/form")
	        .loginProcessingUrl("/login")
	        .failureUrl("/login/form?error")
	        .permitAll();
	  }
}

Update SpringWebAppInitializer which we created eariler to add SecurityConfig configuration class.


public class SpringWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
	@Override
	protected Class[] getRootConfigClasses()
	{
		return new Class[] { AppConfig.class};
		//As we have SecurityConfig.java in same package as AppConfig.java 
                // and enabled ComponentScan to scan "com.sivalabs.springapp.config" we don't need to explicitely configure it.
		//otherwise we should add SecurityConfig.class to getRootConfigClasses()
		//return new Class[] { AppConfig.class, SecurityConfig.class};
	}
	...
	...
	@Override
    protected Filter[] getServletFilters() {
       return new Filter[]{ 
    		   new DelegatingFilterProxy("springSecurityFilterChain"),
    		   new OpenEntityManagerInViewFilter()};
    } 

}	

As per our SpringSecurity custom Form Login configuration, we will use the following login form in login.jsp.



<%@taglib uri="http://www.springframework.org/tags"  prefix="spring"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>



Login






		
Invalid UserName and Password.
You have been logged out.

User Login Form

Once we successfully login we can obtain the authenticated use details using and secure parts of the view using as follows:


Email:

Administration

Logout

You can find the source code at github https://github.com/sivaprasadreddy/sivalabs-blog-samples-code/tree/master/springmvc-datajpa-security-demo

There are few issues while running the same application on JBoss AS 7.1. I have made few changes to run on JBossAS7.1 and published code at https://github.com/sivaprasadreddy/sivalabs-blog-samples-code/tree/master/springmvc-datajpa-security-demo-jboss7

#Hibernate#JPA#SpringMVC#SpringSecurity

Comments

  1. Mohammed Tahar BADI
    March 13, 2014 - 10:16 am

    Hi siva;
    this is a greate work, thinks a lot.

    just one thing : when accessing admin pages without ADMIN_ROLE we need to add Access Denied Page (i.e handling org.springframework.security.access.AccessDeniedException)

  2. Mohammed Tahar BADI
    March 13, 2014 - 11:14 am

    Hi siva ;
    very helpful tuto, greate work, thinks a lot.
    just one question : how to implement AccessDeniedHandler using JavaConfig ?

  3. Kudpudeen .M
    May 22, 2014 - 5:09 am

    Hi siva:
    Thanks a lot, I've question about java config, Please clarify me.
    In my organization we are using JDK 6/JROCKIT and JBOSS 7.1.1 AS for develops the application,
    We are developing Spring MVC 3 application using old style xml configuration .
    Now i planned to migrate my Spring MVC 3 + Hibernate xml configuration application to pure java config application and i followed your tutorial series.
    Unfortunately My Spring MVC 3 + Hibernate pure java config application does not works on jboss 7.1 AS, But it works on both tomcat and jetty server
    With xml configuration working fine in jboss 7.1 AS. And I'm not tested the application with new WILDFLY 8 AS.Because we are using JDK 6/JROCKIT only.

    is there any problem in JBOSS 7 AS with SPRING MVC java config ?
    and
    should i upgrade JAVA version 6 to 7 and JBOSS 7 to WILDFLY 8 ?

    Please answer me.

    Thanks & Regards

    Kudpudeen

  4. Siva Prasad Reddy
    May 22, 2014 - 5:11 am

    What issues you are facing?

  5. Kudpudeen .M
    May 23, 2014 - 7:01 am

    Hi Siva

    I compiled this springmvc4-spring-data-jpa sample application in JDK 6 with small modification in its sources.
    Unfortunately i got 404 error while deploying this springmvc4-spring-data-jpa sample application on JBOSS 7.1.1 AS. no mapping found in JBOSS log.
    But it successfully deployed and executed in tomcat 7 server

    is there problem in JBOSS 7 AS with SPRING MVC java config ?

    Please help me.

  6. Kudpudeen .M
    May 23, 2014 - 7:02 am

    I'm getting 404 error page,

    please help me

  7. Siva Prasad Reddy
    May 23, 2014 - 7:07 am

    Hi,
    I tried deploying on JBossAS71.1 and i am also facing issues.
    Still I couldn't figure out the root cause of the issue, but after few experiments I could deploy the app with few tweaks.
    Give me your email id, i will email you the code.

  8. Siva Prasad Reddy
    May 24, 2014 - 3:34 am

    Sent the updated code.

  9. Kudpudeen .M
    May 26, 2014 - 7:56 am

    This comment has been removed by the author.

  10. Kudpudeen .M
    May 26, 2014 - 7:56 am

    Thanks It works for me

  11. Nical nico
    June 17, 2014 - 6:42 am

    Hi Siva,
    Thank you for your solution.
    I would like to use it with Jboss and I have some error (as Kudpudeen .M) . if you can send me your jboss version I will be very happy.
    Thank you

  12. Nical nico
    July 24, 2014 - 7:01 am

    Hi Siva,

    It's working well !!!!
    Sorry for the delay to answer ^^
    What did you change just to know what have you done ?

    Thank you again mate !

  13. Zadith Manotas Pretel
    August 13, 2014 - 1:41 am

    Hi there

    I'm currently facing an issue with Spring Data JPA and Spring Security. When i call the getOne method from my UserDetailsService implementation, it returns a null object, i've already setup the database connection using a jndi server resource.

    Is there an additional config for Spring Data JPA and Spring Security??

  14. Siva Prasad Reddy
    August 13, 2014 - 4:59 am

    Hi,
    Please try to check whether the Spring Data JPA methods are working fine or not first, just to figure out where is the root cause.

    Sometime back I also faced this kind of issue, spending a lot of time looking into Security configuration whereas the actual issue is with my Spring Data JPA Repository query.

  15. Balarini
    November 8, 2014 - 1:30 pm

    Hello Sival,

    I want to understand why did you disable csrf() ?

    thanks

  16. Devdeep
    December 19, 2014 - 3:09 pm

    Hi Siva,
    I wanted to ask, once you have a userdetailsservice and wish to add a "Sign up new user" functionality, how do you add a new user to the repo?

  17. Sandeep
    April 6, 2015 - 5:00 am

    Good work mate. Need your help here, I'm not able to login. I have created User table and did required entries. but it's not working. On debug I found that you don't have UserRepositary implementation class. How does that work.

  18. Siva Prasad Reddy
    April 6, 2015 - 5:02 am

    Hi,
    We don't need to implement Spring Data JPA interfaces, spring will do at runtime.
    What error you are getting?

  19. Sandeep
    April 7, 2015 - 1:44 am

    Got that error and it was my mistake (in fact a very stupid one :), named USERS table as USER). This is sorted. But after I got over this, I got another issue where in it was looking for some authorities table. What was that? What is that used for. I just created a table with this name and did required entries but I'm not able to get the context here. Please guide me and yes many thanks for that prompt response.

  20. Siva Prasad Reddy
    April 7, 2015 - 1:46 am

    Hi,
    Please take a look at the Spring Security database shcema for managing users and roles. http://docs.spring.io/spring-security/site/docs/3.0.x/reference/appendix-schema.html

  21. Sandeep
    April 10, 2015 - 5:20 am

    Thanks Siva

  22. Kannan Mugundan
    April 15, 2015 - 10:55 am

    Hi,

    How to enable @EnableGlobalMethodSecurity. I imported your code and un commented @EnableGlobalMethodSecurity but I get error

    Caused by: java.lang.IllegalArgumentException: Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found
    []

  23. Chandra Sekharreddy
    November 19, 2015 - 2:39 am

    org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:943)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:822)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:807)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:129)
    com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:77)
    org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:177)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)

  24. Omar Taktak
    November 28, 2015 - 9:09 am

    Hi , good work , thanks you,
    but I got an exception: internalauthenticationserviceexception null
    How to resolve it thanks.

  25. chandu
    December 19, 2015 - 6:03 am

    hi siva plases response on this exception:
    org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException

    • Siva
      December 19, 2015 - 6:05 am

      Hi Chandu,
      With the information (error) you gave I can’t help you. Please provide more details about the error you are getting.

  26. Muhammad Fahad Zaeem
    January 31, 2016 - 8:04 pm

    Hello Author,

    I am totally beginner and started learning spring mvc , spring data jpa and spring security…

    i did not find any controller class that maps our url to some request .. in short , how can i run this project ?

    • Siva
      January 31, 2016 - 9:08 pm

      Hi,
      This project is a maven based project which you can import into any IDE like Eclipse, NetBeans or Intellij and run.
      Otherwise you can run maven goal “clean package” and take the war file and deploy in tomcat server.

      • Muhammad Fahad Zaeem
        February 1, 2016 - 10:44 am

        i have already did this step. How can i add my own controller and view pages ??
        i am getting this error when i run this project on tomcat
        org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘entityManagerFactory’ defined in class path resource [com/sivalabs/springapp/config/PersistenceConfig.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean com.sivalabs.springapp.config.PersistenceConfig.entityManagerFactory()] threw exception; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build EntityManagerFactory

        • Siva
          February 1, 2016 - 10:52 am

          Hi,
          Looking at the error I am guessing you might not have database setup correctly or does not have the tables created as specified in src/main/resources/db.sql.

          Coming to the question “How can i add my own controller and view pages ??”.

          It is a SpringMVC application, so you can create Spring Controller and create views.

          • Muhammad Fahad Zaeem
            February 1, 2016 - 11:03 am

            i have created all required database..

            Feb 01, 2016 10:32:03 AM org.apache.catalina.core.StandardContext listenerStart
            SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
            org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘entityManagerFactory’ defined in class path resource [com/sivalabs/springapp/config/PersistenceConfig.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean com.sivalabs.springapp.config.PersistenceConfig.entityManagerFactory()] threw exception; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build EntityManagerFactory
            at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:592)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1094)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:989)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
            at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
            at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
            at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
            at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
            at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:973)
            at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:750)
            at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
            at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:381)
            at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:293)
            at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
            at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4810)
            at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5255)
            at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
            at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
            at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
            at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
            at java.lang.Thread.run(Thread.java:745)
            Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean com.sivalabs.springapp.config.PersistenceConfig.entityManagerFactory()] threw exception; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build EntityManagerFactory
            at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:188)
            at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:581)
            … 23 more
            Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build EntityManagerFactory
            at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:924)
            at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:899)
            at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:76)
            at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:318)
            at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
            at com.sivalabs.springapp.config.PersistenceConfig.entityManagerFactory(PersistenceConfig.java:69)
            at com.sivalabs.springapp.config.PersistenceConfig$$EnhancerByCGLIB$$de7ca490.CGLIB$entityManagerFactory$1()
            at com.sivalabs.springapp.config.PersistenceConfig$$EnhancerByCGLIB$$de7ca490$$FastClassByCGLIB$$be4c51b4.invoke()
            at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
            at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:326)
            at com.sivalabs.springapp.config.PersistenceConfig$$EnhancerByCGLIB$$de7ca490.entityManagerFactory()
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:497)
            at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
            … 24 more
            Caused by: org.hibernate.HibernateException: Connection cannot be null when ‘hibernate.dialect’ not set
            at org.hibernate.service.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:98)
            at org.hibernate.service.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:68)
            at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:170)
            at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:76)
            at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:160)
            at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:132)
            at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1818)
            at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1776)
            at org.hibernate.ejb.EntityManagerFactoryImpl.(EntityManagerFactoryImpl.java:96)
            at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:914)
            … 39 more

            Feb 01, 2016 10:32:03 AM org.apache.catalina.core.StandardContext startInternal
            SEVERE: One or more listeners failed to start. Full details will be found in the appropriate container log file
            Feb 01, 2016 10:32:03 AM org.apache.catalina.core.StandardContext startInternal
            SEVERE: Context [/springmvc-datajpa-security-demo] startup failed due to previous errors
            Feb 01, 2016 10:32:03 AM org.apache.catalina.core.ApplicationContext log
            INFO: Closing Spring root WebApplicationContext
            Feb 01, 2016 10:32:03 AM org.apache.catalina.loader.WebappClassLoaderBase clearReferencesJdbc
            WARNING: The web application [springmvc-datajpa-security-demo] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
            Feb 01, 2016 10:32:03 AM org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
            WARNING: The web application [springmvc-datajpa-security-demo] appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
            java.lang.Object.wait(Native Method)
            java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
            com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:40)
            Feb 01, 2016 10:32:03 AM org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
            WARNING: The web application [springmvc-datajpa-security-demo] appears to have started a thread named [Timer-0] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
            java.lang.Object.wait(Native Method)
            java.lang.Object.wait(Object.java:502)
            java.util.TimerThread.mainLoop(Timer.java:526)
            java.util.TimerThread.run(Timer.java:505)
            Feb 01, 2016 10:32:03 AM org.apache.coyote.AbstractProtocol start
            INFO: Starting ProtocolHandler [“http-nio-8080”]
            Feb 01, 2016 10:32:03 AM org.apache.coyote.AbstractProtocol start
            INFO: Starting ProtocolHandler [“ajp-nio-8009”]
            Feb 01, 2016 10:32:03 AM org.apache.catalina.startup.Catalina start
            INFO: Server startup in 26833 ms

  27. Muhammad Fahad Zaeem
    February 1, 2016 - 11:04 am

    what is the index url.. ?? where are your controllers?

    you are getting only authentication provided username in controller ? but where are your controllers where we specify RequestMapping annotation..

    • Siva
      February 1, 2016 - 12:46 pm

      From the stacktrace, you are getting error

      Caused by: org.hibernate.HibernateException: Connection cannot be null when ‘hibernate.dialect’ not set

      which means your connection proeprties are wrong and cannot connect to your database.
      Please check your database properties.

      Index URL is “/” and you can find the controllers and all other code in github repo mentioned in post.

  28. Muhammad Fahad Zaeem
    February 1, 2016 - 3:32 pm

    you can see in my logs , there is nothing url mapping on server

    Feb 01, 2016 2:56:53 PM org.apache.tomcat.util.digester.SetPropertiesRule begin
    WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property ‘source’ to ‘org.eclipse.jst.jee.server:springmvc-datajpa-security-demo’ did not find a matching property.
    Feb 01, 2016 2:56:53 PM org.apache.catalina.startup.VersionLoggerListener log
    INFO: Server version: Apache Tomcat/8.0.30
    Feb 01, 2016 2:56:53 PM org.apache.catalina.startup.VersionLoggerListener log
    INFO: Server built: Dec 1 2015 22:30:46 UTC
    Feb 01, 2016 2:56:53 PM org.apache.catalina.startup.VersionLoggerListener log
    INFO: Server number: 8.0.30.0
    Feb 01, 2016 2:56:53 PM org.apache.catalina.startup.VersionLoggerListener log
    INFO: OS Name: Windows 8.1
    Feb 01, 2016 2:56:53 PM org.apache.catalina.startup.VersionLoggerListener log
    INFO: OS Version: 6.3
    Feb 01, 2016 2:56:53 PM org.apache.catalina.startup.VersionLoggerListener log
    INFO: Architecture: amd64
    Feb 01, 2016 2:56:53 PM org.apache.catalina.startup.VersionLoggerListener log
    INFO: Java Home: C:\Program Files\Java\jdk1.8.0_65\jre
    Feb 01, 2016 2:56:53 PM org.apache.catalina.startup.VersionLoggerListener log
    INFO: JVM Version: 1.8.0_65-b17
    Feb 01, 2016 2:56:53 PM org.apache.catalina.startup.VersionLoggerListener log
    INFO: JVM Vendor: Oracle Corporation
    Feb 01, 2016 2:56:53 PM org.apache.catalina.startup.VersionLoggerListener log
    INFO: CATALINA_BASE: F:\Users\User\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp1
    Feb 01, 2016 2:56:53 PM org.apache.catalina.startup.VersionLoggerListener log
    INFO: CATALINA_HOME: C:\Program Files\Apache Software Foundation\Tomcat 8.0
    Feb 01, 2016 2:56:53 PM org.apache.catalina.startup.VersionLoggerListener log
    INFO: Command line argument: -Dcatalina.base=F:\Users\User\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp1
    Feb 01, 2016 2:56:53 PM org.apache.catalina.startup.VersionLoggerListener log
    INFO: Command line argument: -Dcatalina.home=C:\Program Files\Apache Software Foundation\Tomcat 8.0
    Feb 01, 2016 2:56:53 PM org.apache.catalina.startup.VersionLoggerListener log
    INFO: Command line argument: -Dwtp.deploy=F:\Users\User\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps
    Feb 01, 2016 2:56:53 PM org.apache.catalina.startup.VersionLoggerListener log
    INFO: Command line argument: -Djava.endorsed.dirs=C:\Program Files\Apache Software Foundation\Tomcat 8.0\endorsed
    Feb 01, 2016 2:56:53 PM org.apache.catalina.startup.VersionLoggerListener log
    INFO: Command line argument: -Dfile.encoding=Cp1252
    Feb 01, 2016 2:56:53 PM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
    INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jdk1.8.0_65\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:/Program Files/Java/jre1.8.0_71/bin/server;C:/Program Files/Java/jre1.8.0_71/bin;C:/Program Files/Java/jre1.8.0_71/lib/amd64;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Skype\Phone\;C:\Program Files\Java\jdk1.8.0_65\bin;C:\Program Files\Java\apache-maven-3.3.9\bin;C:\Program Files\Java\apache-maven-3.3.9\bin;C:\Users\User\Desktop;;.
    Feb 01, 2016 2:56:53 PM org.apache.coyote.AbstractProtocol init
    INFO: Initializing ProtocolHandler [“http-nio-8080”]
    Feb 01, 2016 2:56:53 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
    INFO: Using a shared selector for servlet write/read
    Feb 01, 2016 2:56:53 PM org.apache.coyote.AbstractProtocol init
    INFO: Initializing ProtocolHandler [“ajp-nio-8009”]
    Feb 01, 2016 2:56:53 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
    INFO: Using a shared selector for servlet write/read
    Feb 01, 2016 2:56:53 PM org.apache.catalina.startup.Catalina load
    INFO: Initialization processed in 1386 ms
    Feb 01, 2016 2:56:53 PM org.apache.catalina.core.StandardService startInternal
    INFO: Starting service Catalina
    Feb 01, 2016 2:56:53 PM org.apache.catalina.core.StandardEngine startInternal
    INFO: Starting Servlet Engine: Apache Tomcat/8.0.30
    Feb 01, 2016 2:56:58 PM org.apache.jasper.servlet.TldScanner scanJars
    INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
    Feb 01, 2016 2:56:58 PM org.apache.catalina.core.ApplicationContext log
    INFO: No Spring WebApplicationInitializer types detected on classpath
    Feb 01, 2016 2:56:58 PM org.apache.coyote.AbstractProtocol start
    INFO: Starting ProtocolHandler [“http-nio-8080”]
    Feb 01, 2016 2:56:58 PM org.apache.coyote.AbstractProtocol start
    INFO: Starting ProtocolHandler [“ajp-nio-8009”]
    Feb 01, 2016 2:56:58 PM org.apache.catalina.startup.Catalina start
    INFO: Server startup in 4848 ms

    • Siva
      February 1, 2016 - 3:57 pm

      Hi,
      I suspect the maven jar files are not properly copied into yourApp/WEB-INF/lib directory in your deployment dir F:\Users\User\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps.

      Please check.

      • Muhammad Fahad Zaeem
        February 1, 2016 - 4:08 pm

        thank u .. now my logs are okay.. but when i provide credentials , it is giving me invalid username and pw error

  29. Muhammad Fahad Zaeem
    February 1, 2016 - 4:06 pm

    http://localhost:8080/springmvc-datajpa-security-demo/login/form?error
    when i provide this url … and give username : Administrator and pw: admin…. I am unable to get authenticated

    • Siva
      February 1, 2016 - 4:10 pm

      Buddy,
      see the logic little bit… we are using email and password as credentials.

      • Muhammad Fahad Zaeem
        February 1, 2016 - 4:15 pm

        Haha Sorry for teasing so much 🙂 yes it is now working .. thanku so much 🙂

  30. Edwin
    May 1, 2016 - 1:13 pm

    Siva,

    I used similar configuration as you did. My web app is working on localhost. But when I export through Eclipse to a .war file and use tomcat manager to upload and deploy, I get a 404 error.

    Help will be appreciated! Thanks for your posts.

Leave a Reply

Your email address will not be published / Required fields are marked *