Spring Boot 1.3.3.,Spring Security 基本自定义配置

Posted

技术标签:

【中文标题】Spring Boot 1.3.3.,Spring Security 基本自定义配置【英文标题】:Spring Boot 1.3.3., Spring Security basic custom config 【发布时间】:2016-09-08 19:33:48 【问题描述】:

我知道这是 n。关于 Spring Security 的帖子,我确实阅读了很多关于它的内容,直到我决定发布我的问题,因为 - 我认为 - 由于 Spring Boot 的性质,引擎盖下一定隐藏着某种问题,这是特定于我正在使用的引导版本/安全类型的星座。

让我进入它。

pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jersey</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>1.2.5.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

我的基本安全配置:

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private StudentRepository studentRepository;

    @Override
    protected void configure(HttpSecurity http) throws Exception 

    http.csrf().disable()
        .authorizeRequests()
            .antMatchers("/").access("hasRole('ROLE_STUDENT')")
            .antMatchers("/**").permitAll();
        .and()
            .formLogin()
            .loginPage("/login")
            .failureUrl("/login?error=true");
    

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth
        .userDetailsService(new UserDetailsService() 
            @Override
            public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException 
                Iterable<Student> studentsWithIds = studentRepository.findAll();

                for (Student student: studentsWithIds) 
                    if (student.getName() == username) 
                        return studentRepository.findOne(student.getId());
                    
                
                  throw new UsernameNotFoundException("User '" + username + "' not found.");
            
        );     
    

我的学生类实现了 UserDetails(为简单起见,使用硬连线凭据。角色是 ROLE_STUDENT):

@Entity
public class Student implements UserDetails 

    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;

    @Column(unique=true)
    private Integer facebookId;

    @Column(unique=true)
    private Integer googleId;

    private String name = "";
    private String password = "";


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


    public String getName() 
        return this.name;
    

    public String getPassword() 
        return this.password;
    

    public void initialize(String studentName) 
        this.name = "student1";
        this.password = "password";
    

    @Override
    public String toString()
        return "Student with name " + name + "id: " + id;
    

    public Integer getId() 
        return id;
    

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

    @Override
    public String getUsername() 
        return this.name;
    

    @Override
    public boolean isAccountNonExpired() 
        // TODO Auto-generated method stub
        return true;
    

    @Override
    public boolean isAccountNonLocked() 
        // TODO Auto-generated method stub
        return true;
    

    @Override
    public boolean isCredentialsNonExpired() 
        // TODO Auto-generated method stub
        return true;
    

    @Override
    public boolean isEnabled() 
        // TODO Auto-generated method stub
        return true;
    


就是这样。我没有任何其他与安全相关的配置或注释,据我所知,我不需要其他任何东西。

问题是,当我启动应用程序时,我仍然无法使用“student1”/“password”验证自己,而只能使用默认的“user”/。

知道缺少什么吗?谢谢!

Naturally there is a user already in the database 开启调试模式后:

22:06:54.067 [http-nio-8280-exec-1] 调试 o.s.s.w.a.AnonymousAuthenticationFilter - 使用匿名令牌填充 SecurityContextHolder:'org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc:主体:anonymousUser;凭证:[受保护];已认证:真实;详细信息:org.springframework.security.web.authentication.WebAuthenticationDetails@b364:RemoteIpAddress:0:0:0:0:0:0:0:1;会话ID:空;授予权限:ROLE_ANONYMOUS' 22:06:54.067 [http-nio-8280-exec-1] 调试 org.springframework.security.web.FilterChainProxy - /students/1 在附加过滤器链中的第 11 位;触发过滤器:'SessionManagementFilter' 22:06:54.067 [http-nio-8280-exec-1] 调试 org.springframework.security.web.FilterChainProxy - /students/1 位于附加过滤器链中 11 的第 10 位;触发过滤器:'ExceptionTranslationFilter' 22:06:54.067 [http-nio-8280-exec-1] DEBUG org.springframework.security.web.FilterChainProxy - /students/1 在附加过滤器链中的第 11 位;触发过滤器:'FilterSecurityInterceptor' 22:06:54.068 [http-nio-8280-exec-1] 调试 o.s.s.w.access.intercept.FilterSecurityInterceptor - 安全对象:FilterInvocation:URL:/students/1;属性:[hasAnyRole('ROLE_USER')] 22:06:54.068 [http-nio-8280-exec-1] DEBUG o.s.s.w.access.intercept.FilterSecurityInterceptor - 先前经过身份验证:org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc:主体:anonymousUser;凭证:[受保护];已认证:真实;详细信息:org.springframework.security.web.authentication.WebAuthenticationDetails@b364:RemoteIpAddress:0:0:0:0:0:0:0:1;会话ID:空;授予权限:ROLE_ANONYMOUS 22:06:54.072 [http-nio-8280-exec-1] DEBUG o.s.security.access.vote.AffirmativeBased - 投票者:org.springframework.security.web.access.expression.WebExpressionVoter@272de199,返回:-1 22:06:54.072 [http-nio-8280-exec-1] 调试 o.s.b.factory.support.DefaultListableBeanFactory - 返回单例 bean 'delegatingApplicationListener' 的缓存实例 22:06:54.073 [http-nio-8280-exec-1] DEBUG o.s.security.web.access.ExceptionTranslationFilter - 访问被拒绝(用户是匿名的);重定向到身份验证入口点 org.springframework.security.access.AccessDeniedException:访问被拒绝 在 org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83) 在 org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:232) 在 org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:123) 在 org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213) 在 org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176) 在 org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) 在 org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 在 org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 在 org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 在 org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 在 org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522) 在 org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095) 在 org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) 在 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) 在 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(未知来源) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(未知来源) 在 org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 在 java.lang.Thread.run(未知来源) 22:06:54.073 [http-nio-8280-exec-1] 调试 o.s.security.web.access.ExceptionTranslationFilter - 调用身份验证入口点。 22:06:54.073 [http-nio-8280-exec-1] 调试 o.s.s.web.context.SecurityContextPersistenceFilter - SecurityContextHolder 现在已清除,因为请求处理已完成 22:06:54.073 [http-nio-8280-exec-1] 调试 o.s.boot.context.web.OrderedRequestContextFilter - 清除线程绑定请求上下文:org.apache.catalina.connector.RequestFacade@13a7abbc 22:06:54.077 [http-nio-8280-exec-1] 调试 org.springframework.web.servlet.DispatcherServlet - 名称为“dispatcherServlet”的 DispatcherServlet 处理 [/error] 的 GET 请求 22:06:54.080 [http-nio-8280-exec-1] 调试 o.s.w.s.m.m.a.RequestMappingHandlerMapping - 查找路径/错误的处理程序方法 22:06:54.083 [http-nio-8280-exec-1] 调试 oswsmmaRequestMappingHandlerMapping - 返回处理程序方法 [public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorhtml(javax. servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)] 22:06:54.083 [http-nio-8280-exec-1] 调试 o.s.b.factory.support.DefaultListableBeanFactory - 返回单例 bean 'basicErrorController' 的缓存实例 22:06:54.084 [http-nio-8280-exec-1] 调试 org.springframework.web.servlet.DispatcherServlet - [/error] 的上次修改值为:-1 22:06:54.084 [http-nio-8280-exec-1] 调试 o.s.o.j.support.OpenEntityManagerInViewInterceptor - 在 OpenEntityManagerInViewInterceptor 中打开 JPA EntityManager 22:06:54.104 [http-nio-8280-exec-1] 调试 oswservlet.view.ContentNegotiatingViewResolver - 请求的媒体类型是 [text/html, text/html;q=0.8] 基于 Accept 标头类型和可生产的媒体类型[文本/html]) 22:06:54.104 [http-nio-8280-exec-1] 调试 o.s.b.factory.support.DefaultListableBeanFactory - 返回单例 bean 的缓存实例“错误” 22:06:54.107 [http-nio-8280-exec-1] 调试 o.s.b.factory.support.DefaultListableBeanFactory - 在名为“错误”的 bean 上调用 afterPropertiesSet() 22:06:54.107 [http-nio-8280-exec-1] 调试 oswservlet.view.ContentNegotiatingViewResolver - 根据请求的媒体类型“text/”返回 [org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView@2fb1fefe] html' 22:06:54.107 [http-nio-8280-exec-1] 调试 org.springframework.web.servlet.DispatcherServlet - 在 DispatcherServlet 中使用名称渲染视图 [org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView@2fb1fefe] 'dispatcherServlet' 22:06:54.113 [http-nio-8280-exec-1] 调试 o.s.o.j.support.OpenEntityManagerInViewInterceptor - 在 OpenEntityManagerInViewInterceptor 中关闭 JPA EntityManager 22:06:54.113 [http-nio-8280-exec-1] 调试 o.s.orm.jpa.EntityManagerFactoryUtils - 关闭 JPA EntityManager 22:06:54.113 [http-nio-8280-exec-1] 调试 org.springframework.web.servlet.DispatcherServlet - 成功完成请求 22:06:54.114 [http-nio-8280-exec-1] 调试 o.s.b.factory.support.DefaultListableBeanFactory - 返回单例 bean 'delegatingApplicationListener' 的缓存实例 22:07:02.728 [http-nio-8280-exec-2] 调试 o.s.boot.context.web.OrderedRequestContextFilter - 将请求上下文绑定到线程:org.apache.catalina.connector.RequestFacade@13a7abbc 22:07:02.728 [http-nio-8280-exec-2] DEBUG o.s.s.web.util.matcher.AntPathRequestMatcher - 检查请求的匹配:'/students/1';反对'/css/' 22:07:02.728 [http-nio-8280-exec-2] DEBUG o.s.s.web.util.matcher.AntPathRequestMatcher - 检查请求的匹配:'/students/1';反对'/js/' 22:07:02.728 [http-nio-8280-exec-2] DEBUG o.s.s.web.util.matcher.AntPathRequestMatcher - 检查请求的匹配:'/students/1';反对 '/images/' 22:07:02.728 [http-nio-8280-exec-2] DEBUG o.s.s.web.util.matcher.AntPathRequestMatcher - 检查请求的匹配:'/students/1';反对'//favicon.ico' 22:07:02.728 [http-nio-8280-exec-2] DEBUG o.s.s.web.util.matcher.AntPathRequestMatcher - 检查请求的匹配:'/students/1';反对'/错误' 22:07:02.728 [http-nio-8280-exec-2] 调试 o.s.security.web.util.matcher.OrRequestMatcher - 尝试使用 Ant [pattern='/'] 进行匹配 22:07:02.728 [http-nio-8280-exec-2] 调试 o.s.s.web.util.matcher.AntPathRequestMatcher - 请求“/students/1”与通用模式“/”匹配 22:07:02.728 [http-nio-8280-exec-2] 调试 o.s.security.web.util.matcher.OrRequestMatcher - 匹配 22:07:02.728 [http-nio-8280-exec-2] 调试 org.springframework.security.web.FilterChainProxy - /students/1 在附加过滤器链中的第 11 位;触发过滤器:'WebAsyncManagerIntegrationFilter' 22:07:02.728 [http-nio-8280-exec-2] 调试 org.springframework.security.web.FilterChainProxy - /students/1 位于附加过滤器链中 11 的第 2 位;触发过滤器:'SecurityContextPersistenceFilter' 22:07:02.728 [http-nio-8280-exec-2] 调试 org.springframework.security.web.FilterChainProxy - /students/1 在附加过滤器链中的第 11 位;触发过滤器:'HeaderWriterFilter' 22:07:02.728 [http-nio-8280-exec-2] 调试 ossecurity.web.header.writers.HstsHeaderWriter - 不注入 HSTS 标头,因为它与 requestMatcher org.springframework.security.web.header.writers 不匹配.HstsHeaderWriter$SecureRequestMatcher@37ca7e0d 22:07:02.728 [http-nio-8280-exec-2] 调试 org.springframework.security.web.FilterChainProxy - /students/1 位于附加过滤器链中 11 的第 4 位;触发过滤器:'LogoutFilter' 22:07:02.728 [http-nio-8280-exec-2] DEBUG o.s.s.web.util.matcher.AntPathRequestMatcher - 检查请求的匹配:'/students/1';反对“/注销” 22:07:02.728 [http-nio-8280-exec-2] 调试 org.springframework.security.web.FilterChainProxy - /students/1 位于附加过滤器链中 11 的第 5 位;触发过滤器:'BasicAuthenticationFilter' 22:07:02.730 [http-nio-8280-exec-2] 调试 o.s.s.w.a.www.BasicAuthenticationFilter - 为用户“student1”找到基本身份验证授权标头 22:07:02.730 [http-nio-8280-exec-2] 调试 o.s.security.authentication.ProviderManager - 使用 org.springframework.security.authentication.dao.DaoAuthenticationProvider 进行身份验证尝试 22:07:02.731 [http-nio-8280-exec-2] 调试 o.s.s.authentication.dao.DaoAuthenticationProvider - 找不到用户“student1”

最后似乎是最有趣的,尽管其余部分也很丑:

o.s.s.authentication.dao.DaoAuthenticationProvider - 用户 'student1' 没找到

这是我在 Student 上调用初始化的地方(这是作弊,因为它应该在 POST 上调用,但同样,我作弊只是为了将 Student 放入数据库中,并将其用于身份验证。显然会有所不同稍后。当然,我只能在我暂时停用应用程序的安全性时进行此 GET):

@RequestMapping(value="/students", method=RequestMethod.GET, produces=MediaType.APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<Iterable<Student>> listStudents() 
    LOGGER.info("/students controller method call"+new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date()));
    Iterable<Student> studentsFound = studentRepository.findAll();

    Student newStudent = new Student();
    newStudent.initialize("student1");
    studentRepository.save(newStudent);

    return new ResponseEntity<Iterable<Student>>(studentsFound, HttpStatus.OK);         

您认为 Student 实例本身是否不正确?

【问题讨论】:

你在哪里调用了Studentinitialize方法? 添加了初始化部分。扩展了一些解释(我知道它在那里没有意义,但只是想将一个学生保存到数据库中,无论在哪里。那部分已经在没有身份验证的情况下工作,所以我把它放在那里。数据库处于更新模式,记录当然还在数据库中,但我也仔细检查过) 【参考方案1】:

问题是当我启动应用程序时,我仍然无法 使用“student1”/“password”验证自己,但只能使用 默认“用户”/。

表示默认用户(默认配置AuthenticationManager)仍处于启用状态。为了解决这个问题,只需注入 AuthenticationManagerBuilderconfigure 方法:

@Override
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception  ... 

基于Spring boot documentation:

要关闭身份验证管理器配置,您可以 添加一个 AuthenticationManager 类型的 bean,或者 else 配置全局 AuthenticationManager 通过自动装配 AuthenticationManagerBuilder 进入您的 @Configuration 类之一中的方法

因此,为了禁用默认的AuthenticationManager,您应该将AutowireAuthenticationManagerBuilder 设置为一个配置方法。

我知道这不是主题,但以下代码对我来说似乎效率极低:

Iterable<Student> studentsWithIds = studentRepository.findAll();
for (Student student: studentsWithIds) 
    if (student.getName() == username) 
        return studentRepository.findOne(student.getId());
    

【讨论】:

解释他为什么需要注入 AuthenticationManagerBuilder 可能会帮助 OP 了解他遇到问题的原因 @Turtle 更新了答案,感谢建议 谢谢您,我尝试了您的建议,但只是将 @Autowired 添加到受保护的 void configure(AuthenticationManagerBuilder auth) throws Exception ... 似乎没有任何改变。事情还没有结束。 (是的,这可能不是我将如何从数据库中获取用户的最终版本,此时我非常绝望,我暂时不介意这样的快速和肮脏的事情) .奇怪的是,我认为执行甚至没有到达该配置方法,因为至少我应该看到一个 UsernameNotFoundException 我不应该吗? UsernameNotFoundException 将被ExceptionTranslationFilter 捕获并转换为 HTTP 响应。因此,除非您使用 debug 日志级别,否则您不会看到该异常。 我希望调试当前能在我的 Eclipse 中工作,这会让它更容易......(这是另一个让我紧张的问题,我想我需要做一些额外的事情才能能够调试这样的应用程序(tomcat?),因为当前调试器只是在我以调试模式启动应用程序时根本不附加)。我尝试更改为调试级别。

以上是关于Spring Boot 1.3.3.,Spring Security 基本自定义配置的主要内容,如果未能解决你的问题,请参考以下文章

spring-boot 指标与 spring-cloud 指标

Spring Boot启动流程详解

Spring Boot启动流程详解

如何搭建spring boot

spring boot 怎么实现集群

使用Spring Boot Gradle插件的多模块项目