From 03dbd93be250f1bc2bdb9dd8709828a1ae9adef1 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Wed, 5 Oct 2016 22:35:11 +0300 Subject: [PATCH] custom user repository and test --- .../WebContent/META-INF/MANIFEST.MF | 3 + spring-security-custom-permission/derby.log | 13 ++ spring-security-custom-permission/pom.xml | 42 +++++ .../baeldung/config/PersistenceConfig.java | 87 +++++++++++ .../org/baeldung/config/SecurityConfig.java | 19 +++ .../persistence/dao/MyUserRepository.java | 146 ++++++++++++++++++ .../persistence/dao/UserRepository.java | 2 + .../org/baeldung/persistence/model/User.java | 2 + .../resources/persistence-derby.properties | 12 ++ .../web/CustomUserDetailsServiceTest.java | 83 ++++++++++ 10 files changed, 409 insertions(+) create mode 100644 spring-security-custom-permission/WebContent/META-INF/MANIFEST.MF create mode 100644 spring-security-custom-permission/derby.log create mode 100644 spring-security-custom-permission/src/main/java/org/baeldung/config/PersistenceConfig.java create mode 100644 spring-security-custom-permission/src/main/java/org/baeldung/persistence/dao/MyUserRepository.java create mode 100644 spring-security-custom-permission/src/main/resources/persistence-derby.properties create mode 100644 spring-security-custom-permission/src/test/java/org/baeldung/web/CustomUserDetailsServiceTest.java diff --git a/spring-security-custom-permission/WebContent/META-INF/MANIFEST.MF b/spring-security-custom-permission/WebContent/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..254272e1c0 --- /dev/null +++ b/spring-security-custom-permission/WebContent/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/spring-security-custom-permission/derby.log b/spring-security-custom-permission/derby.log new file mode 100644 index 0000000000..3c0968fa9c --- /dev/null +++ b/spring-security-custom-permission/derby.log @@ -0,0 +1,13 @@ +---------------------------------------------------------------- +Wed Oct 05 21:59:32 EEST 2016: +Booting Derby version The Apache Software Foundation - Apache Derby - 10.12.1.1 - (1704137): instance a816c00e-0157-9637-0b63-000000c038f0 +on database directory memory:C:\Users\lore\Documents\workspace-articles\spring-security-custom-permission\spring_custom_user_service with class loader sun.misc.Launcher$AppClassLoader@6433a2 +Loaded from file:/C:/Users/lore/.m2/repository/org/apache/derby/derby/10.12.1.1/derby-10.12.1.1.jar +java.vendor=Oracle Corporation +java.runtime.version=1.8.0_77-b03 +user.dir=C:\Users\lore\Documents\workspace-articles\spring-security-custom-permission +os.name=Windows 7 +os.arch=x86 +os.version=6.1 +derby.system.home=null +Database Class Loader started - derby.database.classpath='' diff --git a/spring-security-custom-permission/pom.xml b/spring-security-custom-permission/pom.xml index 6f460f1751..d036975107 100644 --- a/spring-security-custom-permission/pom.xml +++ b/spring-security-custom-permission/pom.xml @@ -86,6 +86,48 @@ + + + org.springframework + spring-test + test + + + + org.apache.derby + derby + 10.12.1.1 + + + org.apache.derby + derbyclient + 10.12.1.1 + + + org.apache.derby + derbynet + 10.12.1.1 + + + org.apache.derby + derbytools + 10.12.1.1 + + + taglibs + standard + 1.1.2 + + + org.springframework.security + spring-security-taglibs + 4.1.3.RELEASE + + + javax.servlet.jsp.jstl + jstl-api + 1.2 + diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/config/PersistenceConfig.java b/spring-security-custom-permission/src/main/java/org/baeldung/config/PersistenceConfig.java new file mode 100644 index 0000000000..cd7caa5fd1 --- /dev/null +++ b/spring-security-custom-permission/src/main/java/org/baeldung/config/PersistenceConfig.java @@ -0,0 +1,87 @@ +package org.baeldung.config; + +import java.util.Properties; + +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; + +import org.baeldung.persistence.dao.MyUserRepository; +import org.baeldung.persistence.dao.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +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 +@PropertySource({ "classpath:persistence-derby.properties" }) +public class PersistenceConfig { + + @Autowired + private Environment env; + + public PersistenceConfig() { + super(); + } + + // beans + + @Bean + public LocalContainerEntityManagerFactoryBean myEmf() { + final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); + em.setDataSource(dataSource()); + em.setPackagesToScan(new String[] { "org.baeldung.persistence.model" }); + + final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + em.setJpaVendorAdapter(vendorAdapter); + em.setJpaProperties(additionalProperties()); + + return em; + } + + @Bean + public DataSource dataSource() { + final DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName")); + dataSource.setUrl(env.getProperty("jdbc.url")); + dataSource.setUsername(env.getProperty("jdbc.user")); + dataSource.setPassword(env.getProperty("jdbc.pass")); + + return dataSource; + } + + @Bean + public PlatformTransactionManager transactionManager(final EntityManagerFactory emf) { + final JpaTransactionManager transactionManager = new JpaTransactionManager(); + transactionManager.setEntityManagerFactory(emf); + return transactionManager; + } + + @Bean + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + final Properties additionalProperties() { + final Properties hibernateProperties = new Properties(); + hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); + hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); + hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache")); + hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache")); + // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true"); + return hibernateProperties; + } + + @Bean + public UserRepository userRepository(){ + return new MyUserRepository(); + } +} \ No newline at end of file diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/config/SecurityConfig.java b/spring-security-custom-permission/src/main/java/org/baeldung/config/SecurityConfig.java index b365744bea..21b81741ee 100644 --- a/spring-security-custom-permission/src/main/java/org/baeldung/config/SecurityConfig.java +++ b/spring-security-custom-permission/src/main/java/org/baeldung/config/SecurityConfig.java @@ -1,14 +1,20 @@ package org.baeldung.config; +import org.baeldung.persistence.dao.MyUserRepository; +import org.baeldung.persistence.dao.UserRepository; import org.baeldung.security.MyUserDetailsService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 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.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; @Configuration @EnableWebSecurity @@ -40,4 +46,17 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { ; // @formatter:on } + + @Bean + public DaoAuthenticationProvider authenticationProvider() { + final DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); + authProvider.setUserDetailsService(userDetailsService); + authProvider.setPasswordEncoder(encoder()); + return authProvider; + } + + @Bean + public PasswordEncoder encoder() { + return new BCryptPasswordEncoder(11); + } } \ No newline at end of file diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/persistence/dao/MyUserRepository.java b/spring-security-custom-permission/src/main/java/org/baeldung/persistence/dao/MyUserRepository.java new file mode 100644 index 0000000000..ee290a0c35 --- /dev/null +++ b/spring-security-custom-permission/src/main/java/org/baeldung/persistence/dao/MyUserRepository.java @@ -0,0 +1,146 @@ +package org.baeldung.persistence.dao; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; + +import org.baeldung.persistence.model.User; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +public class MyUserRepository implements UserRepository { + + @PersistenceContext + private EntityManager entityManager; + + @Override + public List findAll() { + // TODO Auto-generated method stub + return null; + } + + @Override + public List findAll(Sort sort) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List findAll(Iterable ids) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List save(Iterable entities) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void flush() { + // TODO Auto-generated method stub + + } + + @Override + public S saveAndFlush(S entity) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void deleteInBatch(Iterable entities) { + // TODO Auto-generated method stub + + } + + @Override + public void deleteAllInBatch() { + // TODO Auto-generated method stub + + } + + @Override + public User getOne(Long id) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Page findAll(Pageable arg0) { + // TODO Auto-generated method stub + return null; + } + + @Override + public long count() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void delete(Long arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void delete(User arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void delete(Iterable arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void deleteAll() { + // TODO Auto-generated method stub + + } + + @Override + public boolean exists(Long arg0) { + // TODO Auto-generated method stub + return false; + } + + @Override + public User findOne(Long arg0) { + // TODO Auto-generated method stub + return null; + } + + @Override + public S save(S user) { + entityManager.persist(user); + return user; + } + + @Override + public User findByUsername(String username) { + Query query = entityManager.createQuery("from User where username=:username", User.class); + query.setParameter("username", username); + List result = query.getResultList(); + if (result != null && result.size() > 0) { + return result.get(0); + } else + return null; + } + + public void removeUserByUsername(String username) { + final Query query = entityManager.createQuery("delete from User where username=:username"); + query.setParameter("username", username); + query.executeUpdate(); + } + +} diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/persistence/dao/UserRepository.java b/spring-security-custom-permission/src/main/java/org/baeldung/persistence/dao/UserRepository.java index 679dd6c363..8b4e20d146 100644 --- a/spring-security-custom-permission/src/main/java/org/baeldung/persistence/dao/UserRepository.java +++ b/spring-security-custom-permission/src/main/java/org/baeldung/persistence/dao/UserRepository.java @@ -6,5 +6,7 @@ import org.springframework.data.jpa.repository.JpaRepository; public interface UserRepository extends JpaRepository { User findByUsername(final String username); + + void removeUserByUsername(String username); } diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/persistence/model/User.java b/spring-security-custom-permission/src/main/java/org/baeldung/persistence/model/User.java index 112d502105..67f18c1398 100644 --- a/spring-security-custom-permission/src/main/java/org/baeldung/persistence/model/User.java +++ b/spring-security-custom-permission/src/main/java/org/baeldung/persistence/model/User.java @@ -12,8 +12,10 @@ import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; +import javax.persistence.Table; @Entity +@Table(name="user_table") public class User { @Id diff --git a/spring-security-custom-permission/src/main/resources/persistence-derby.properties b/spring-security-custom-permission/src/main/resources/persistence-derby.properties new file mode 100644 index 0000000000..e808fdc288 --- /dev/null +++ b/spring-security-custom-permission/src/main/resources/persistence-derby.properties @@ -0,0 +1,12 @@ +# jdbc.X +jdbc.driverClassName=org.apache.derby.jdbc.EmbeddedDriver +jdbc.url=jdbc:derby:memory:spring_custom_user_service;create=true +jdbc.user=tutorialuser +jdbc.pass=tutorialpass + +# hibernate.X +hibernate.dialect=org.hibernate.dialect.DerbyDialect +hibernate.show_sql=false +hibernate.hbm2ddl.auto=create +hibernate.cache.use_second_level_cache=false +hibernate.cache.use_query_cache=false \ No newline at end of file diff --git a/spring-security-custom-permission/src/test/java/org/baeldung/web/CustomUserDetailsServiceTest.java b/spring-security-custom-permission/src/test/java/org/baeldung/web/CustomUserDetailsServiceTest.java new file mode 100644 index 0000000000..390bd7c96c --- /dev/null +++ b/spring-security-custom-permission/src/test/java/org/baeldung/web/CustomUserDetailsServiceTest.java @@ -0,0 +1,83 @@ +package org.baeldung.web; + +import org.baeldung.config.MvcConfig; +import org.baeldung.config.PersistenceConfig; +import org.baeldung.config.SecurityConfig; +import org.baeldung.persistence.dao.UserRepository; +import org.baeldung.persistence.model.User; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.SpringApplicationConfiguration; +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.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import static org.junit.Assert.*; + +import java.util.logging.Level; +import java.util.logging.Logger; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = { MvcConfig.class, SecurityConfig.class, PersistenceConfig.class }) +@WebAppConfiguration +public class CustomUserDetailsServiceTest { + + private static final Logger LOG = Logger.getLogger("CustomUserDetailsServiceTest"); + + public static final String USERNAME = "user"; + public static final String PASSWORD = "pass"; + public static final String USERNAME2 = "user2"; + + @Autowired + UserRepository myUserRepository; + + @Autowired + AuthenticationProvider authenticationProvider; + + @Test + public void givenExistingUser_whenAuthenticate_thenRetrieveFromDb() { + try { + User user = new User(); + user.setUsername(USERNAME); + user.setPassword(PASSWORD); + + myUserRepository.save(user); + + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(USERNAME, PASSWORD); + Authentication authentication = authenticationProvider.authenticate(auth); + + assertEquals(authentication.getName(), USERNAME); + + } catch (Exception exc) { + LOG.log(Level.SEVERE, "Error creating account"); + } finally { + myUserRepository.removeUserByUsername(USERNAME); + } + } + + @Test (expected = BadCredentialsException.class) + public void givenIncorrectUser_whenAuthenticate_thenBadCredentialsException() { + try { + User user = new User(); + user.setUsername(USERNAME); + user.setPassword(PASSWORD); + + try { + myUserRepository.save(user); + } + catch (Exception exc) { + LOG.log(Level.SEVERE, "Error creating account"); + } + + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(USERNAME2, PASSWORD); + Authentication authentication = authenticationProvider.authenticate(auth); + } + finally { + myUserRepository.removeUserByUsername(USERNAME); + } + } + +}