0

I am taking a minimalist approach to learning Spring Boot. I have a H2 database in memory. I am creating/loading the schema and data through Spring. When I go to the database, I am seeing the schema, tables, and data.

Here are my properties: Properties settings

I checked the database to be sure it is created properly. H2 database with  tables and Data

Now I point my browser to the login screen. Using the data populated in the database, I login However, the login is failing.

Login Failure

When I go looking at the logs, I see the below error.

    2018-03-31 12:33:34.621 DEBUG 4190 --- [nio-8090-exec-6] 
    o.h.engine.jdbc.spi.SqlExceptionHelper   : could not prepare statement 
    [select reader0_.readerid as readerid1_1_, reader0_.fullname as 
    fullname2_1_, reader0_.password as password3_1_, reader0_.username as 
    username4_1_ from reader reader0_ where reader0_.username=?]

org.h2.jdbc.JdbcSQLException: Table "READER" not found; SQL statement:
select reader0_.readerid as readerid1_1_, reader0_.fullname as fullname2_1_, reader0_.password as password3_1_, reader0_.username as username4_1_ from reader reader0_ where reader0_.username=? [42102-196]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:345) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.message.DbException.get(DbException.java:179) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.message.DbException.get(DbException.java:155) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.command.Parser.readTableOrView(Parser.java:5552) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.command.Parser.readTableFilter(Parser.java:1266) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.command.Parser.parseSelectSimpleFromPart(Parser.java:1946) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.command.Parser.parseSelectSimple(Parser.java:2095) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.command.Parser.parseSelectSub(Parser.java:1940) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.command.Parser.parseSelectUnion(Parser.java:1755) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.command.Parser.parseSelect(Parser.java:1743) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.command.Parser.parsePrepared(Parser.java:449) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.command.Parser.parse(Parser.java:321) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.command.Parser.parse(Parser.java:293) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.command.Parser.prepareCommand(Parser.java:258) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.engine.Session.prepareLocal(Session.java:578) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.engine.Session.prepareCommand(Session.java:519) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1204) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:73) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:288) ~[h2-1.4.196.jar:1.4.196]
    at com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:318) ~[HikariCP-2.7.8.jar:na]
    at com.zaxxer.hikari.pool.HikariProxyConnection.prepareStatement(HikariProxyConnection.java) ~[HikariCP-2.7.8.jar:na]
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:146) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:172) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:148) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1985) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1915) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1893) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.loader.Loader.doQuery(Loader.java:938) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.loader.Loader.doList(Loader.java:2692) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.loader.Loader.doList(Loader.java:2675) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2507) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.loader.Loader.list(Loader.java:2502) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:502) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:392) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1489) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1445) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1414) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1463) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getSingleResult(CriteriaQueryTypeQueryAdapter.java:107) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findOne(SimpleJpaRepository.java:409) [spring-data-jpa-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_162]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_162]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_162]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_162]
    at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:377) [spring-data-commons-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200) [spring-data-commons-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:629) [spring-data-commons-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) [spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:593) [spring-data-commons-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:578) [spring-data-commons-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) [spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59) [spring-data-commons-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) [spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294) ~[spring-tx-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) [spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) [spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135) ~[spring-data-jpa-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) [spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) [spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61) ~[spring-data-commons-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) [spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at com.sun.proxy.$Proxy98.findOne(Unknown Source) ~[na:na]
    at net.clouddeveloper.spring.config.SecurityConfig$1.loadUserByUsername(SecurityConfig.java:74) ~[main/:na]
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:104) ~[spring-security-core-5.0.3.RELEASE.jar:5.0.3.RELEASE]
    at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:144) ~[spring-security-core-5.0.3.RELEASE.jar:5.0.3.RELEASE]
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174) ~[spring-security-core-5.0.3.RELEASE.jar:5.0.3.RELEASE]
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199) ~[spring-security-core-5.0.3.RELEASE.jar:5.0.3.RELEASE]
    at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94) ~[spring-security-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) ~[spring-security-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66) ~[spring-security-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) ~[spring-security-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) ~[spring-security-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_162]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_162]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
    at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_162]

2018-03-31 12:33:34.622  WARN 4190 --- [nio-8090-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 42102, SQLState: 42S02
2018-03-31 12:33:34.622 ERROR 4190 --- [nio-8090-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper   : Table "READER" not found; SQL statement:
select reader0_.readerid as readerid1_1_, reader0_.fullname as fullname2_1_, reader0_.password as password3_1_, reader0_.username as username4_1_ from reader reader0_ where reader0_.username=? [42102-196]
2018-03-31 12:33:34.627 DEBUG 4190 --- [nio-8090-exec-6] cResourceLocalTransactionCoordinatorImpl : JDBC transaction marked for rollback-only (exception provided for stack trace)

I believe the issue comes from the SecurityConf class.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);

    @Autowired
    private ReaderRepository  readerRepository;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        logger.debug("HttpSecurity:" + http);
        http
                .formLogin()
                   .loginPage("/login")
                   .failureUrl("/login?error=true")
                .and()
                   .logout()
                   .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                   .logoutSuccessUrl("/")
                .and()
                   .authorizeRequests()
                   .antMatchers("/readingList").access("hasRole('READER')")
                   .antMatchers("/**").permitAll()
                .and()
                   .authorizeRequests()
                    .antMatchers("/console/**").permitAll();

        // making H2 console working
        http.headers().frameOptions().disable();

       /*
        https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html#when-to-use-csrf-protection
        for non-browser APIs there is no need to use csrf protection
        */
        http.csrf().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        logger.debug("Authentication:" + auth.getDefaultUserDetailsService());

        auth
                .userDetailsService(new UserDetailsService() {
                    @Override
                    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{

                        logger.debug("loadUserByUsername: " + username);

                        Reader reader = new Reader();
                        reader.setUsername(username);

                        Optional userDetails = readerRepository.findOne(Example.of(reader));

                        logger.debug("UserDetails returned: " +userDetails);

                        if (userDetails != null){
                           return  ((UserDetails) userDetails.get());
                        }
                        throw new UsernameNotFoundException("User '" + username + "' not found.");
                    }
                });

    }
}

Here is the Reader Class

    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;

     import javax.persistence.*;
    import java.util.Arrays;
import java.util.Collection;

@Entity(name = "reader")
@Table(schema ="mylib", name = "reader")
public class Reader implements UserDetails {

    private static final long serialVersionUID  = 1L;


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long readerID;
    private String username;
    private String fullname;
    private String password;

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }



    public Long getReaderID() {
        return readerID;
    }

    public void setReaderID(Long readerID) {
        this.readerID = readerID;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getFullname() {
        return fullname;
    }

    public void setFullname(String fullname) {
        this.fullname = fullname;
    }

    @Override
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

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

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return Arrays.asList(new SimpleGrantedAuthority("ROLE_READER"));
    }


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

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

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

Here is the bean creation.

    @Bean
    public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();

 dataSource.setDriverClassName(env.getProperty("spring.datasource.driverClassName"));
    dataSource.setUrl(env.getProperty("spring.datasource.url"));
    dataSource.setUsername(env.getProperty("spring.datasource.username"));
    dataSource.setPassword(env.getProperty("spring.datasource.password"));

    return dataSource;
}

I have ran the two tests and they both pass. The only word of caution is ensure you wipe out the file database before running the tests. Otherwise you will get a unique constraint error. test cases

I would greatly appreciate some recommendations or suggestions.

Russ

rray
  • 470
  • 3
  • 10
  • 27
  • I’ll suggest you to review the way you implemented your UserdetailsService. In fact you’re trying to cast an optional to a UserDetails. Also it seems like your Reader table is not found – akuma8 Apr 01 '18 at 15:20
  • If you want, l’ll post you an example of codes which will work. – akuma8 Apr 01 '18 at 15:33
  • Thank you. I've searched the internet and see there are many examples on the same subject. What I am perplexed by is the fact my security configuration is not exposing the database to the process (my hypothesis). I would expect the JPA process would create the sql correctly and run the query with negative results using Spring Boot's auto configuration. I know Spring Boot can see the database because the DDL and DML were ran on the database creation. Suggestions? – rray Apr 02 '18 at 12:13
  • I suppose (I hope) the `Reader` entity implements `UserDetails`. Could you add your datasource configuration and the Reader class? – akuma8 Apr 02 '18 at 22:35
  • I added the @Table annotation to pickup the schema for the entity. Still the same issue. Now it cannot find the SCHEMA. I have also added the catalog, It finds the database but not the schema. – rray Apr 03 '18 at 00:52
  • Could you also add the datasource url? – akuma8 Apr 03 '18 at 08:55
  • @akuma8, the db url is in the properties file above. – rray Apr 03 '18 at 08:59
  • you misconfigured your datasource – akuma8 Apr 03 '18 at 09:04
  • Did the answer solve your problem? – akuma8 Apr 03 '18 at 09:51
  • No it did not. The URL recommendation only renames the database to myLib. The @Table recommendation only renames the schema to the database name. :-( – rray Apr 03 '18 at 10:53
  • Do you have several schemas in your app? If not you do not need to specify one in the @Table – akuma8 Apr 03 '18 at 11:23
  • I have looked at [this](https://stackoverflow.com/questions/5763747/h2-in-memory-database-table-not-found). I have ran the tests provided. It working for in memory and file. – rray Apr 03 '18 at 12:19
  • I don't think I am looking at the same database even thought I am keeping the database open. When I look at the tables through the H2-Console, I see my schema and tables along with the system tables. When I programmatically query the table and schema, I DO NOT see my two tables or my schema I created. This is the **URL** I am using `jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1;TRACE_LEVEL_FILE=3` – rray Apr 03 '18 at 15:28
  • I hope you also use Spring Data Jpa + Hibernate so you do not need to manage database connexion yourself. – akuma8 Apr 03 '18 at 21:47
  • Please follow this tutorial : http://www.baeldung.com/spring-security-authentication-with-a-database I advice you to separate the implementation of `UserDetails` and `UserdetailsService` as indicated there – akuma8 Apr 03 '18 at 21:59

2 Answers2

0

Set your datasource url as follow :

spring.datasource.url=jdbc:h2:mem:mylib

Or change the schema in your entity :

@Table(schema="test.mylib")
akuma8
  • 4,160
  • 5
  • 46
  • 82
0

Dont implement UserDetails from Reader Entity . Create a separate bean "SecuredReader" and extend SecuredReader from Reader entity and implement the UserDetails .

public class SecuredReader extends Reader implements UserDetails {

public SecuredReader(Reader user){
        // map all the attributes here 
}
............
............

I have done a similar use case . Please check the github link https://github.com/jokumar/task-planner