为什么UserDetailsS​​ervice在Spring Boot应用程序中返回null?

时间:2015-12-30 23:20:17

标签: java spring spring-mvc spring-security spring-boot

一个简单的Spring启动应用程序有一个自定义的UserDetailsS​​ervice。 Spring Boot Controller由AngularJS应用程序调用,AngularJS应用程序的身份验证请求以/user url模式发送到后端。但登录请求导致控制器日志指示控制器未找到/user url模式,并且UserDetailsS​​ervice因此返回null。 需要对下面的代码进行哪些具体更改才能启用后端/user url模式的客户端请求以查找控制器方法,从而正确实例化自定义UserDetailsService

应用程序非常简单,控制器少于200行代码。

控制器的代码是:

@SpringBootApplication
@Controller
@EnableJpaRepositories(basePackages = "demo", considerNestedRepositories = true)
public class UiApplication extends WebMvcConfigurerAdapter {

    // Match everything without a suffix (so not a static resource)
    @RequestMapping(value = "/{[path:[^\\.]*}")
    public String redirect() {
        // Forward to home page so that route is preserved.
        return "forward:/";
    }

    @RequestMapping("/user")
    @ResponseBody
    public Principal user(Principal user) {
        return user;
    }

    public static void main(String[] args) {
        SpringApplication.run(UiApplication.class, args);
    }

    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver slr = new SessionLocaleResolver();
        slr.setDefaultLocale(Locale.US);
        return slr;
    }

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
        lci.setParamName("lang");
        return lci;
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
    }


    @Order(Ordered.HIGHEST_PRECEDENCE)
    @Configuration
    protected static class AuthenticationSecurity extends
            GlobalAuthenticationConfigurerAdapter {

        @Autowired
        private Users users;

        @Override
        public void init(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(users);
        }
    }

    @SuppressWarnings("deprecation")
    @Configuration
    @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
    @EnableWebMvcSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.httpBasic().and().authorizeRequests()
                    .antMatchers("/index.html", "/", "/login", "/message", "/home")
                    .permitAll().anyRequest().authenticated().and().csrf()
                    .csrfTokenRepository(csrfTokenRepository()).and()
                    .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
        }

        private Filter csrfHeaderFilter() {
            return new OncePerRequestFilter() {
                @Override
                protected void doFilterInternal(HttpServletRequest request,
                                                HttpServletResponse response, FilterChain filterChain)
                        throws ServletException, IOException {
                    CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
                    if (csrf != null) {
                        Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
                        String token = csrf.getToken();
                        if (cookie == null || token != null
                                && !token.equals(cookie.getValue())) {
                            cookie = new Cookie("XSRF-TOKEN", token);
                            cookie.setPath("/");
                            response.addCookie(cookie);
                        }
                    }
                    filterChain.doFilter(request, response);
                }
            };
        }

        private CsrfTokenRepository csrfTokenRepository() {
            HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
            repository.setHeaderName("X-XSRF-TOKEN");
            return repository;
        }
    }

    @Service
    class Users implements UserDetailsService {

        private UserRepository repo;

        @Autowired
        public Users(UserRepository repo) {
            this.repo = repo;
        }

        @Override
        public UserDetails loadUserByUsername(String username)
                throws UsernameNotFoundException {
            User user = repo.findByName(username);
            if (user == null) {
                return null;
            }
            List<GrantedAuthority> auth = AuthorityUtils
                    .commaSeparatedStringToAuthorityList("ROLE_USER");
            if (username.equals("admin")) {
                auth = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN");
            }
            String password = user.getPassword();
            return new org.springframework.security.core.userdetails.User(username, password, auth);
        }

    }

    @Repository
    interface UserRepository extends CrudRepository<User, Long> {
        User findByName(String name);
    }

    @Entity
    class User {
        @GeneratedValue
        @Id
        private Long iduser;
        private String name;
        private String password;
        @OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
        private Collection<SessionLog> sessionLogCollection;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getPassword() {
            return password;
        }

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

    @Entity
    class SessionLog {

        @GeneratedValue
        @Id
        private Long id;
        private String sessionid;
        @ManyToOne(optional = true)
        @JoinColumn(name = "iduser")
        private User user;

        public String getSessionid() {
            return sessionid;
        }
    }

}

登录请求产生的完整堆栈跟踪是:

2015-12-30 14:27:07.628 DEBUG 4398 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy        : /js/navigation/login.html has an empty filter list
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/css/**'
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/js/**'
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/images/**'
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/**/favicon.ico'
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/error'
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/configprops']
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/configprops'
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/configprops/**']
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/configprops/**'
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/configprops.*']
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/configprops.*'
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/configprops/']
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/configprops/'
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/autoconfig']
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/autoconfig'
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/autoconfig/**']
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/autoconfig/**'
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/autoconfig.*']
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/autoconfig.*'
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/autoconfig/']
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/autoconfig/'
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/metrics']
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/metrics'
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/metrics/**']
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/metrics/**'
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/metrics.*']
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/metrics.*'
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/metrics/']
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/metrics/'
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/env']
2015-12-30 14:27:21.617 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/env'
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/env/**']
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/env/**'
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/env.*']
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/env.*'
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/env/']
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/env/'
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/trace']
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/trace'
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/trace/**']
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/trace/**'
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/trace.*']
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/trace.*'
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/trace/']
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/trace/'
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/health']
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/health'
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/health/']
2015-12-30 14:27:21.620 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/health/'
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/beans']
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/beans'
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/beans/**']
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/beans/**'
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/beans.*']
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/beans.*'
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/beans/']
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/beans/'
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/info']
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/info'
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/info/']
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/info/'
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/dump']
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/dump'
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/dump/**']
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/dump/**'
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/dump.*']
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/dump.*'
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/dump/']
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/dump/'
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/mappings']
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/mappings'
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/mappings/**']
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/mappings/**'
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/mappings.*']
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/mappings.*'
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/mappings/']
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/user'; against '/mappings/'
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.security.web.FilterChainProxy        : /user at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2015-12-30 14:27:21.621 DEBUG 4398 --- [nio-8080-exec-6] o.s.security.web.FilterChainProxy        : /user at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2015-12-30 14:27:21.622 DEBUG 4398 --- [nio-8080-exec-6] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2015-12-30 14:27:21.622 DEBUG 4398 --- [nio-8080-exec-6] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@71f7b6fe. A new one will be created.
2015-12-30 14:27:21.622 DEBUG 4398 --- [nio-8080-exec-6] o.s.security.web.FilterChainProxy        : /user at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2015-12-30 14:27:21.622 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@a3b708e
2015-12-30 14:27:21.622 DEBUG 4398 --- [nio-8080-exec-6] o.s.security.web.FilterChainProxy        : /user at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2015-12-30 14:27:21.622 DEBUG 4398 --- [nio-8080-exec-6] o.s.security.web.FilterChainProxy        : /user at position 5 of 13 in additional filter chain; firing Filter: ''
2015-12-30 14:27:21.622 DEBUG 4398 --- [nio-8080-exec-6] o.s.security.web.FilterChainProxy        : /user at position 6 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2015-12-30 14:27:21.630 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /user' doesn't match 'POST /logout
2015-12-30 14:27:21.630 DEBUG 4398 --- [nio-8080-exec-6] o.s.security.web.FilterChainProxy        : /user at position 7 of 13 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
2015-12-30 14:27:21.632 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.a.www.BasicAuthenticationFilter  : Basic Authentication Authorization header found for user 'admin'
2015-12-30 14:27:21.632 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2015-12-30 14:27:22.155 DEBUG 4398 --- [nio-8080-exec-6] .s.a.DefaultAuthenticationEventPublisher : No event was found for the exception org.springframework.security.authentication.InternalAuthenticationServiceException
2015-12-30 14:27:22.155 DEBUG 4398 --- [nio-8080-exec-6] o.s.s.w.a.www.BasicAuthenticationFilter  : Authentication request for failed: org.springframework.security.authentication.InternalAuthenticationServiceException: UserDetailsService returned null, which is an interface contract violation
2015-12-30 14:27:22.155 DEBUG 4398 --- [nio-8080-exec-6] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]
2015-12-30 14:27:22.155 DEBUG 4398 --- [nio-8080-exec-6] s.w.a.DelegatingAuthenticationEntryPoint : Match found! Executing org.springframework.security.web.authentication.HttpStatusEntryPoint@784c2ce0
2015-12-30 14:27:22.155 DEBUG 4398 --- [nio-8080-exec-6] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2015-12-30 14:27:22.155 DEBUG 4398 --- [nio-8080-exec-6] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed

1 个答案:

答案 0 :(得分:12)

找到控制器方法。问题是这段代码:

if (user == null) {
    return null;
}

正如您在日志消息中清楚地看到的那样:

Authentication request for failed: org.springframework.security.authentication.InternalAuthenticationServiceException: UserDetailsService returned null, which is an interface contract violation

UserDetailsS​​ervice实现中不允许返回null。

因此,请检查数据库中是否有管理员用户的条目,然后移除return null并抛出UsernameNotFoundException