Spring Security BadCredentialsException










1















I am following this Baeldung tutorial, and I can't see any differences (except maybe the pregenerated login page template), but I still get a BadCredentialsException when trying to login with a hard-coded user/password combo, which I've already confirmed is in the DB and the password in there is encrypted.



Here's my code, let me know if more is needed:



SecurityConfig:



@Component
@EnableWebSecurity
@SuppressWarnings("unused")
public class SecurityConfig extends WebSecurityConfigurerAdapter

@Autowired
private MyUserDetailsService userDetailsService;

@Override
protected void configure(HttpSecurity http) throws Exception
http
.authorizeRequests()
.antMatchers("/css/**").permitAll()
.antMatchers("/error").permitAll()
.antMatchers("/action/**").hasRole("USER")
.antMatchers("/action_template/**").hasRole("ADMIN")
.and()
.formLogin()
.loginPage("/login").failureUrl("/login-error");


@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception
auth.authenticationProvider(authProvider());


@Bean
public DaoAuthenticationProvider authProvider()
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();

authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());

return authProvider;


@Bean
public PasswordEncoder passwordEncoder()
return new BCryptPasswordEncoder();





MyUserDetailsService:



@Service
@Transactional
@SuppressWarnings("unused")
public class MyUserDetailsService implements UserDetailsService

@Autowired
private UserRepository userRepository;

public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException

User user = userRepository.findByEmail(email);

if (user == null)
throw new UsernameNotFoundException(
"No user found with username: " + email);


final List<GrantedAuthority> authorities = new ArrayList<>();
user.getRoles().forEach((r) -> authorities.add(new SimpleGrantedAuthority(r)));

return new org.springframework.security.core.userdetails.User(
user.getEmail(),
user.getPassword().toLowerCase(),
true,
true,
true,
true,
authorities
);





EDIT:



Here's the stacktrace



2018-11-14 13:52:05.785 DEBUG 2100 --- [nio-8090-exec-5] w.a.UsernamePasswordAuthenticationFilter : Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials

org.springframework.security.authentication.BadCredentialsException: Bad credentials
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:93)
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:166)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199)
at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:124)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:770)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)


I've also edited my SecurityConfig and added .antMatchers("/error").permitAll(), but it didn't help



EDIT 2:



Here's the Github repo, it should provide more insight.
I have no clue on how to diagnose this further...










share|improve this question




























    1















    I am following this Baeldung tutorial, and I can't see any differences (except maybe the pregenerated login page template), but I still get a BadCredentialsException when trying to login with a hard-coded user/password combo, which I've already confirmed is in the DB and the password in there is encrypted.



    Here's my code, let me know if more is needed:



    SecurityConfig:



    @Component
    @EnableWebSecurity
    @SuppressWarnings("unused")
    public class SecurityConfig extends WebSecurityConfigurerAdapter

    @Autowired
    private MyUserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception
    http
    .authorizeRequests()
    .antMatchers("/css/**").permitAll()
    .antMatchers("/error").permitAll()
    .antMatchers("/action/**").hasRole("USER")
    .antMatchers("/action_template/**").hasRole("ADMIN")
    .and()
    .formLogin()
    .loginPage("/login").failureUrl("/login-error");


    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception
    auth.authenticationProvider(authProvider());


    @Bean
    public DaoAuthenticationProvider authProvider()
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();

    authProvider.setUserDetailsService(userDetailsService);
    authProvider.setPasswordEncoder(passwordEncoder());

    return authProvider;


    @Bean
    public PasswordEncoder passwordEncoder()
    return new BCryptPasswordEncoder();





    MyUserDetailsService:



    @Service
    @Transactional
    @SuppressWarnings("unused")
    public class MyUserDetailsService implements UserDetailsService

    @Autowired
    private UserRepository userRepository;

    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException

    User user = userRepository.findByEmail(email);

    if (user == null)
    throw new UsernameNotFoundException(
    "No user found with username: " + email);


    final List<GrantedAuthority> authorities = new ArrayList<>();
    user.getRoles().forEach((r) -> authorities.add(new SimpleGrantedAuthority(r)));

    return new org.springframework.security.core.userdetails.User(
    user.getEmail(),
    user.getPassword().toLowerCase(),
    true,
    true,
    true,
    true,
    authorities
    );





    EDIT:



    Here's the stacktrace



    2018-11-14 13:52:05.785 DEBUG 2100 --- [nio-8090-exec-5] w.a.UsernamePasswordAuthenticationFilter : Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials

    org.springframework.security.authentication.BadCredentialsException: Bad credentials
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:93)
    at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:166)
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199)
    at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:124)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:770)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)


    I've also edited my SecurityConfig and added .antMatchers("/error").permitAll(), but it didn't help



    EDIT 2:



    Here's the Github repo, it should provide more insight.
    I have no clue on how to diagnose this further...










    share|improve this question


























      1












      1








      1








      I am following this Baeldung tutorial, and I can't see any differences (except maybe the pregenerated login page template), but I still get a BadCredentialsException when trying to login with a hard-coded user/password combo, which I've already confirmed is in the DB and the password in there is encrypted.



      Here's my code, let me know if more is needed:



      SecurityConfig:



      @Component
      @EnableWebSecurity
      @SuppressWarnings("unused")
      public class SecurityConfig extends WebSecurityConfigurerAdapter

      @Autowired
      private MyUserDetailsService userDetailsService;

      @Override
      protected void configure(HttpSecurity http) throws Exception
      http
      .authorizeRequests()
      .antMatchers("/css/**").permitAll()
      .antMatchers("/error").permitAll()
      .antMatchers("/action/**").hasRole("USER")
      .antMatchers("/action_template/**").hasRole("ADMIN")
      .and()
      .formLogin()
      .loginPage("/login").failureUrl("/login-error");


      @Override
      public void configure(AuthenticationManagerBuilder auth) throws Exception
      auth.authenticationProvider(authProvider());


      @Bean
      public DaoAuthenticationProvider authProvider()
      DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();

      authProvider.setUserDetailsService(userDetailsService);
      authProvider.setPasswordEncoder(passwordEncoder());

      return authProvider;


      @Bean
      public PasswordEncoder passwordEncoder()
      return new BCryptPasswordEncoder();





      MyUserDetailsService:



      @Service
      @Transactional
      @SuppressWarnings("unused")
      public class MyUserDetailsService implements UserDetailsService

      @Autowired
      private UserRepository userRepository;

      public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException

      User user = userRepository.findByEmail(email);

      if (user == null)
      throw new UsernameNotFoundException(
      "No user found with username: " + email);


      final List<GrantedAuthority> authorities = new ArrayList<>();
      user.getRoles().forEach((r) -> authorities.add(new SimpleGrantedAuthority(r)));

      return new org.springframework.security.core.userdetails.User(
      user.getEmail(),
      user.getPassword().toLowerCase(),
      true,
      true,
      true,
      true,
      authorities
      );





      EDIT:



      Here's the stacktrace



      2018-11-14 13:52:05.785 DEBUG 2100 --- [nio-8090-exec-5] w.a.UsernamePasswordAuthenticationFilter : Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials

      org.springframework.security.authentication.BadCredentialsException: Bad credentials
      at org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:93)
      at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:166)
      at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
      at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199)
      at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
      at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
      at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
      at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:124)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
      at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
      at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
      at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
      at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
      at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
      at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
      at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
      at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
      at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
      at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
      at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:770)
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
      at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:748)


      I've also edited my SecurityConfig and added .antMatchers("/error").permitAll(), but it didn't help



      EDIT 2:



      Here's the Github repo, it should provide more insight.
      I have no clue on how to diagnose this further...










      share|improve this question
















      I am following this Baeldung tutorial, and I can't see any differences (except maybe the pregenerated login page template), but I still get a BadCredentialsException when trying to login with a hard-coded user/password combo, which I've already confirmed is in the DB and the password in there is encrypted.



      Here's my code, let me know if more is needed:



      SecurityConfig:



      @Component
      @EnableWebSecurity
      @SuppressWarnings("unused")
      public class SecurityConfig extends WebSecurityConfigurerAdapter

      @Autowired
      private MyUserDetailsService userDetailsService;

      @Override
      protected void configure(HttpSecurity http) throws Exception
      http
      .authorizeRequests()
      .antMatchers("/css/**").permitAll()
      .antMatchers("/error").permitAll()
      .antMatchers("/action/**").hasRole("USER")
      .antMatchers("/action_template/**").hasRole("ADMIN")
      .and()
      .formLogin()
      .loginPage("/login").failureUrl("/login-error");


      @Override
      public void configure(AuthenticationManagerBuilder auth) throws Exception
      auth.authenticationProvider(authProvider());


      @Bean
      public DaoAuthenticationProvider authProvider()
      DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();

      authProvider.setUserDetailsService(userDetailsService);
      authProvider.setPasswordEncoder(passwordEncoder());

      return authProvider;


      @Bean
      public PasswordEncoder passwordEncoder()
      return new BCryptPasswordEncoder();





      MyUserDetailsService:



      @Service
      @Transactional
      @SuppressWarnings("unused")
      public class MyUserDetailsService implements UserDetailsService

      @Autowired
      private UserRepository userRepository;

      public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException

      User user = userRepository.findByEmail(email);

      if (user == null)
      throw new UsernameNotFoundException(
      "No user found with username: " + email);


      final List<GrantedAuthority> authorities = new ArrayList<>();
      user.getRoles().forEach((r) -> authorities.add(new SimpleGrantedAuthority(r)));

      return new org.springframework.security.core.userdetails.User(
      user.getEmail(),
      user.getPassword().toLowerCase(),
      true,
      true,
      true,
      true,
      authorities
      );





      EDIT:



      Here's the stacktrace



      2018-11-14 13:52:05.785 DEBUG 2100 --- [nio-8090-exec-5] w.a.UsernamePasswordAuthenticationFilter : Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials

      org.springframework.security.authentication.BadCredentialsException: Bad credentials
      at org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:93)
      at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:166)
      at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
      at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199)
      at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
      at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
      at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
      at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:124)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
      at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
      at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
      at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
      at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
      at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
      at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
      at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
      at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
      at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
      at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
      at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:770)
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
      at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:748)


      I've also edited my SecurityConfig and added .antMatchers("/error").permitAll(), but it didn't help



      EDIT 2:



      Here's the Github repo, it should provide more insight.
      I have no clue on how to diagnose this further...







      java spring spring-mvc spring-boot spring-security






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 14 '18 at 18:33







      Vicente Rivera

















      asked Nov 14 '18 at 16:16









      Vicente RiveraVicente Rivera

      285




      285






















          3 Answers
          3






          active

          oldest

          votes


















          1














          Spring Boot can pick up/create all the necessary beans automatically, so you can simplify the SecurityConfig like this (It will find your UserDetailsService and will create a default DaoAuthenticationProvider if there is no such bean defined):



          @Component
          @EnableWebSecurity
          @SuppressWarnings("unused")
          public class SecurityConfig extends WebSecurityConfigurerAdapter

          @Override
          protected void configure(HttpSecurity http) throws Exception
          http
          .authorizeRequests()
          .antMatchers("/css/**").permitAll()
          .antMatchers("/error").permitAll()
          .antMatchers("/action/**").hasRole("USER")
          .antMatchers("/action_template/**").hasRole("ADMIN")
          .and()
          .formLogin()
          .loginPage("/login").failureUrl("/login-error");





          Also define the passwordEncoder bean in a different configuration class (However I'm not absolutely sure if it's also needed) :



          @Configuration
          public class BeanConfiguration

          @Bean
          public PasswordEncoder passwordEncoder()
          return new BCryptPasswordEncoder();








          share|improve this answer























          • I've fixed it ;) Thanks for the tip either way, I'll test what you said about the UserDetailsService!

            – Vicente Rivera
            Nov 14 '18 at 18:50


















          1














          I'm... perplexed.
          I've found the issue. I don't know why I thought it was ok to keep it and I don't know why the tutorial has it there, but even if the password is 'password', user.getPassword().toLowerCase() is lowercasing the BCrypt hash, not the actual password.
          Removing .toLowerCase() fixes it.






          share|improve this answer























          • lol, I haven't notice that. You should still consider simplifying the configuration as I suggested in my answer.

            – Selindek
            Nov 14 '18 at 18:51


















          0














          The problem looks like is related to the way you are registering your password encoded. Try to register it like this:



          @Autowired
          public BCryptPasswordEncoder bCryptPasswordEncoder()
          return new BCryptPasswordEncoder();


          protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception

          auth
          .userDetailsService(userDetailsService)
          .passwordEncoder(bCryptPasswordEncoder);






          share|improve this answer

























          • Didn't work, sadly :/

            – Vicente Rivera
            Nov 14 '18 at 16:58











          • Where did you place that ?

            – Issmeil EL.
            Nov 14 '18 at 16:59











          • In configure(HttpSecurity http), after .antMatchers("/css/**").permitAll()

            – Vicente Rivera
            Nov 14 '18 at 17:01











          • See edited if it works !

            – Issmeil EL.
            Nov 14 '18 at 17:16











          • No success yet... Should I make the Github repo public and link that?

            – Vicente Rivera
            Nov 14 '18 at 17:22










          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53304528%2fspring-security-badcredentialsexception%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          3 Answers
          3






          active

          oldest

          votes








          3 Answers
          3






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          Spring Boot can pick up/create all the necessary beans automatically, so you can simplify the SecurityConfig like this (It will find your UserDetailsService and will create a default DaoAuthenticationProvider if there is no such bean defined):



          @Component
          @EnableWebSecurity
          @SuppressWarnings("unused")
          public class SecurityConfig extends WebSecurityConfigurerAdapter

          @Override
          protected void configure(HttpSecurity http) throws Exception
          http
          .authorizeRequests()
          .antMatchers("/css/**").permitAll()
          .antMatchers("/error").permitAll()
          .antMatchers("/action/**").hasRole("USER")
          .antMatchers("/action_template/**").hasRole("ADMIN")
          .and()
          .formLogin()
          .loginPage("/login").failureUrl("/login-error");





          Also define the passwordEncoder bean in a different configuration class (However I'm not absolutely sure if it's also needed) :



          @Configuration
          public class BeanConfiguration

          @Bean
          public PasswordEncoder passwordEncoder()
          return new BCryptPasswordEncoder();








          share|improve this answer























          • I've fixed it ;) Thanks for the tip either way, I'll test what you said about the UserDetailsService!

            – Vicente Rivera
            Nov 14 '18 at 18:50















          1














          Spring Boot can pick up/create all the necessary beans automatically, so you can simplify the SecurityConfig like this (It will find your UserDetailsService and will create a default DaoAuthenticationProvider if there is no such bean defined):



          @Component
          @EnableWebSecurity
          @SuppressWarnings("unused")
          public class SecurityConfig extends WebSecurityConfigurerAdapter

          @Override
          protected void configure(HttpSecurity http) throws Exception
          http
          .authorizeRequests()
          .antMatchers("/css/**").permitAll()
          .antMatchers("/error").permitAll()
          .antMatchers("/action/**").hasRole("USER")
          .antMatchers("/action_template/**").hasRole("ADMIN")
          .and()
          .formLogin()
          .loginPage("/login").failureUrl("/login-error");





          Also define the passwordEncoder bean in a different configuration class (However I'm not absolutely sure if it's also needed) :



          @Configuration
          public class BeanConfiguration

          @Bean
          public PasswordEncoder passwordEncoder()
          return new BCryptPasswordEncoder();








          share|improve this answer























          • I've fixed it ;) Thanks for the tip either way, I'll test what you said about the UserDetailsService!

            – Vicente Rivera
            Nov 14 '18 at 18:50













          1












          1








          1







          Spring Boot can pick up/create all the necessary beans automatically, so you can simplify the SecurityConfig like this (It will find your UserDetailsService and will create a default DaoAuthenticationProvider if there is no such bean defined):



          @Component
          @EnableWebSecurity
          @SuppressWarnings("unused")
          public class SecurityConfig extends WebSecurityConfigurerAdapter

          @Override
          protected void configure(HttpSecurity http) throws Exception
          http
          .authorizeRequests()
          .antMatchers("/css/**").permitAll()
          .antMatchers("/error").permitAll()
          .antMatchers("/action/**").hasRole("USER")
          .antMatchers("/action_template/**").hasRole("ADMIN")
          .and()
          .formLogin()
          .loginPage("/login").failureUrl("/login-error");





          Also define the passwordEncoder bean in a different configuration class (However I'm not absolutely sure if it's also needed) :



          @Configuration
          public class BeanConfiguration

          @Bean
          public PasswordEncoder passwordEncoder()
          return new BCryptPasswordEncoder();








          share|improve this answer













          Spring Boot can pick up/create all the necessary beans automatically, so you can simplify the SecurityConfig like this (It will find your UserDetailsService and will create a default DaoAuthenticationProvider if there is no such bean defined):



          @Component
          @EnableWebSecurity
          @SuppressWarnings("unused")
          public class SecurityConfig extends WebSecurityConfigurerAdapter

          @Override
          protected void configure(HttpSecurity http) throws Exception
          http
          .authorizeRequests()
          .antMatchers("/css/**").permitAll()
          .antMatchers("/error").permitAll()
          .antMatchers("/action/**").hasRole("USER")
          .antMatchers("/action_template/**").hasRole("ADMIN")
          .and()
          .formLogin()
          .loginPage("/login").failureUrl("/login-error");





          Also define the passwordEncoder bean in a different configuration class (However I'm not absolutely sure if it's also needed) :



          @Configuration
          public class BeanConfiguration

          @Bean
          public PasswordEncoder passwordEncoder()
          return new BCryptPasswordEncoder();









          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 14 '18 at 18:47









          SelindekSelindek

          1,195914




          1,195914












          • I've fixed it ;) Thanks for the tip either way, I'll test what you said about the UserDetailsService!

            – Vicente Rivera
            Nov 14 '18 at 18:50

















          • I've fixed it ;) Thanks for the tip either way, I'll test what you said about the UserDetailsService!

            – Vicente Rivera
            Nov 14 '18 at 18:50
















          I've fixed it ;) Thanks for the tip either way, I'll test what you said about the UserDetailsService!

          – Vicente Rivera
          Nov 14 '18 at 18:50





          I've fixed it ;) Thanks for the tip either way, I'll test what you said about the UserDetailsService!

          – Vicente Rivera
          Nov 14 '18 at 18:50













          1














          I'm... perplexed.
          I've found the issue. I don't know why I thought it was ok to keep it and I don't know why the tutorial has it there, but even if the password is 'password', user.getPassword().toLowerCase() is lowercasing the BCrypt hash, not the actual password.
          Removing .toLowerCase() fixes it.






          share|improve this answer























          • lol, I haven't notice that. You should still consider simplifying the configuration as I suggested in my answer.

            – Selindek
            Nov 14 '18 at 18:51















          1














          I'm... perplexed.
          I've found the issue. I don't know why I thought it was ok to keep it and I don't know why the tutorial has it there, but even if the password is 'password', user.getPassword().toLowerCase() is lowercasing the BCrypt hash, not the actual password.
          Removing .toLowerCase() fixes it.






          share|improve this answer























          • lol, I haven't notice that. You should still consider simplifying the configuration as I suggested in my answer.

            – Selindek
            Nov 14 '18 at 18:51













          1












          1








          1







          I'm... perplexed.
          I've found the issue. I don't know why I thought it was ok to keep it and I don't know why the tutorial has it there, but even if the password is 'password', user.getPassword().toLowerCase() is lowercasing the BCrypt hash, not the actual password.
          Removing .toLowerCase() fixes it.






          share|improve this answer













          I'm... perplexed.
          I've found the issue. I don't know why I thought it was ok to keep it and I don't know why the tutorial has it there, but even if the password is 'password', user.getPassword().toLowerCase() is lowercasing the BCrypt hash, not the actual password.
          Removing .toLowerCase() fixes it.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 14 '18 at 18:48









          Vicente RiveraVicente Rivera

          285




          285












          • lol, I haven't notice that. You should still consider simplifying the configuration as I suggested in my answer.

            – Selindek
            Nov 14 '18 at 18:51

















          • lol, I haven't notice that. You should still consider simplifying the configuration as I suggested in my answer.

            – Selindek
            Nov 14 '18 at 18:51
















          lol, I haven't notice that. You should still consider simplifying the configuration as I suggested in my answer.

          – Selindek
          Nov 14 '18 at 18:51





          lol, I haven't notice that. You should still consider simplifying the configuration as I suggested in my answer.

          – Selindek
          Nov 14 '18 at 18:51











          0














          The problem looks like is related to the way you are registering your password encoded. Try to register it like this:



          @Autowired
          public BCryptPasswordEncoder bCryptPasswordEncoder()
          return new BCryptPasswordEncoder();


          protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception

          auth
          .userDetailsService(userDetailsService)
          .passwordEncoder(bCryptPasswordEncoder);






          share|improve this answer

























          • Didn't work, sadly :/

            – Vicente Rivera
            Nov 14 '18 at 16:58











          • Where did you place that ?

            – Issmeil EL.
            Nov 14 '18 at 16:59











          • In configure(HttpSecurity http), after .antMatchers("/css/**").permitAll()

            – Vicente Rivera
            Nov 14 '18 at 17:01











          • See edited if it works !

            – Issmeil EL.
            Nov 14 '18 at 17:16











          • No success yet... Should I make the Github repo public and link that?

            – Vicente Rivera
            Nov 14 '18 at 17:22















          0














          The problem looks like is related to the way you are registering your password encoded. Try to register it like this:



          @Autowired
          public BCryptPasswordEncoder bCryptPasswordEncoder()
          return new BCryptPasswordEncoder();


          protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception

          auth
          .userDetailsService(userDetailsService)
          .passwordEncoder(bCryptPasswordEncoder);






          share|improve this answer

























          • Didn't work, sadly :/

            – Vicente Rivera
            Nov 14 '18 at 16:58











          • Where did you place that ?

            – Issmeil EL.
            Nov 14 '18 at 16:59











          • In configure(HttpSecurity http), after .antMatchers("/css/**").permitAll()

            – Vicente Rivera
            Nov 14 '18 at 17:01











          • See edited if it works !

            – Issmeil EL.
            Nov 14 '18 at 17:16











          • No success yet... Should I make the Github repo public and link that?

            – Vicente Rivera
            Nov 14 '18 at 17:22













          0












          0








          0







          The problem looks like is related to the way you are registering your password encoded. Try to register it like this:



          @Autowired
          public BCryptPasswordEncoder bCryptPasswordEncoder()
          return new BCryptPasswordEncoder();


          protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception

          auth
          .userDetailsService(userDetailsService)
          .passwordEncoder(bCryptPasswordEncoder);






          share|improve this answer















          The problem looks like is related to the way you are registering your password encoded. Try to register it like this:



          @Autowired
          public BCryptPasswordEncoder bCryptPasswordEncoder()
          return new BCryptPasswordEncoder();


          protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception

          auth
          .userDetailsService(userDetailsService)
          .passwordEncoder(bCryptPasswordEncoder);







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 14 '18 at 17:16

























          answered Nov 14 '18 at 16:47









          Issmeil EL.Issmeil EL.

          641423




          641423












          • Didn't work, sadly :/

            – Vicente Rivera
            Nov 14 '18 at 16:58











          • Where did you place that ?

            – Issmeil EL.
            Nov 14 '18 at 16:59











          • In configure(HttpSecurity http), after .antMatchers("/css/**").permitAll()

            – Vicente Rivera
            Nov 14 '18 at 17:01











          • See edited if it works !

            – Issmeil EL.
            Nov 14 '18 at 17:16











          • No success yet... Should I make the Github repo public and link that?

            – Vicente Rivera
            Nov 14 '18 at 17:22

















          • Didn't work, sadly :/

            – Vicente Rivera
            Nov 14 '18 at 16:58











          • Where did you place that ?

            – Issmeil EL.
            Nov 14 '18 at 16:59











          • In configure(HttpSecurity http), after .antMatchers("/css/**").permitAll()

            – Vicente Rivera
            Nov 14 '18 at 17:01











          • See edited if it works !

            – Issmeil EL.
            Nov 14 '18 at 17:16











          • No success yet... Should I make the Github repo public and link that?

            – Vicente Rivera
            Nov 14 '18 at 17:22
















          Didn't work, sadly :/

          – Vicente Rivera
          Nov 14 '18 at 16:58





          Didn't work, sadly :/

          – Vicente Rivera
          Nov 14 '18 at 16:58













          Where did you place that ?

          – Issmeil EL.
          Nov 14 '18 at 16:59





          Where did you place that ?

          – Issmeil EL.
          Nov 14 '18 at 16:59













          In configure(HttpSecurity http), after .antMatchers("/css/**").permitAll()

          – Vicente Rivera
          Nov 14 '18 at 17:01





          In configure(HttpSecurity http), after .antMatchers("/css/**").permitAll()

          – Vicente Rivera
          Nov 14 '18 at 17:01













          See edited if it works !

          – Issmeil EL.
          Nov 14 '18 at 17:16





          See edited if it works !

          – Issmeil EL.
          Nov 14 '18 at 17:16













          No success yet... Should I make the Github repo public and link that?

          – Vicente Rivera
          Nov 14 '18 at 17:22





          No success yet... Should I make the Github repo public and link that?

          – Vicente Rivera
          Nov 14 '18 at 17:22

















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53304528%2fspring-security-badcredentialsexception%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          How to read a connectionString WITH PROVIDER in .NET Core?

          Node.js Script on GitHub Pages or Amazon S3

          Museum of Modern and Contemporary Art of Trento and Rovereto