使用独立 Tomcat 的 Spring Boot 容器身份验证

Posted

技术标签:

【中文标题】使用独立 Tomcat 的 Spring Boot 容器身份验证【英文标题】:Spring Boot container authentication with standalone Tomcat 【发布时间】:2017-10-24 10:33:09 【问题描述】:

我有一个独立的 Tomcat 服务器,它应该运行我的 Spring Boot 应用程序(部署为 .war 文件)。此应用程序需要使用来自 Tomcat 的容器身份验证来保护。首先它应该在开发环境中使用tomcat-users.xml。在生产环境中,此领域将被另一种身份验证方法替换。

我的配置:

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.httpBasic().disable()
            .authorizeRequests()
                .antMatchers("/test/test2").permitAll()
                .anyRequest().authenticated()
            .and()
                .formLogin().permitAll()
            .and()
                .logout().permitAll()
            .and()
                .jee().mappableRoles("USER");
    


Tomcat 用户:

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users xmlns="http://tomcat.apache.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd" version="1.0">
    <user username="testuser" password="pw" roles="user" />
</tomcat-users>

在安全页面上,表单登录显示与预期一样,但身份验证不起作用(您的登录尝试不成功,请重试。)。

配置中是否缺少其他内容?

日志:

09:53:40 DEBUG o.s.security.web.FilterChainProxy        : /login at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
09:53:40 DEBUG o.s.security.web.FilterChainProxy        : /login at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
09:53:40 DEBUG w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
09:53:40 DEBUG w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@22ea93f6. A new one will be created.
09:53:40 DEBUG o.s.security.web.FilterChainProxy        : /login at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
09:53:40 DEBUG 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@738151d2
09:53:40 DEBUG o.s.security.web.FilterChainProxy        : /login at position 4 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
09:53:40 DEBUG o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', GET]
09:53:40 DEBUG o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'POST /login' doesn't match 'GET /logout
09:53:40 DEBUG o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', POST]
09:53:40 DEBUG o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/logout'
09:53:40 DEBUG o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', PUT]
09:53:40 DEBUG o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'POST /login' doesn't match 'PUT /logout
09:53:40 DEBUG o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', DELETE]
09:53:40 DEBUG o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'POST /login' doesn't match 'DELETE /logout
09:53:40 DEBUG o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
09:53:40 DEBUG o.s.security.web.FilterChainProxy        : /login at position 5 of 13 in additional filter chain; firing Filter: 'J2eePreAuthenticatedProcessingFilter'
09:53:40 DEBUG p.j.J2eePreAuthenticatedProcessingFilter : Checking secure context token: null
09:53:40 DEBUG p.j.J2eePreAuthenticatedProcessingFilter : PreAuthenticated J2EE principal: null
09:53:40 DEBUG p.j.J2eePreAuthenticatedProcessingFilter : No pre-authenticated principal found in request
09:53:40 DEBUG o.s.security.web.FilterChainProxy        : /login at position 6 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
09:53:40 DEBUG o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/login'
09:53:40 DEBUG w.a.UsernamePasswordAuthenticationFilter : Request is to process authentication
09:53:40 DEBUG o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
09:53:40 DEBUG o.s.s.a.dao.DaoAuthenticationProvider    : User 'testuser' not found
09:53:40 DEBUG o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'delegatingApplicationListener'
09:53:40 DEBUG w.a.UsernamePasswordAuthenticationFilter : Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials

【问题讨论】:

首先,您需要选择是使用 httpBasic 还是 formLogin,如果您使用自己的表单登录,则摆脱 httpBasic,然后摆脱 .jee() 让我们从它开始. 还有一点需要提一下,您并没有具体说明您的身份验证内容,我的意思是,如果您使用数据库并且针对它对用户进行身份验证,那么您需要提及它。跨度> 您似乎缺少对 Spring Security 的基本了解,请尝试更好地学习它,然后再回到您的项目中。祝你好运 我没有指定它,因为身份验证应该在容器(tomcat)上进行。这就是我添加.jee() 的原因。 docs.spring.io/spring-security/site/docs/current/reference/html/… 【参考方案1】:

我找不到任何最终解决方案,但 this hint helped me 让它完全可用。似乎至少需要web.xml 才能“激活”容器身份验证。然后 Spring Security 可以将其作为预身份验证处理。

不幸的是,在此解决方案中,来自容器身份验证的权限(角色)不存在。因此我不得不完全移除 Spring Security 并且只使用web.xml(和context.xml)。

【讨论】:

我实际上也使用了带有spring security的容器认证,在web.xml中我添加了带有角色名称的'security-role'标签,以及带有 里面就是这样

以上是关于使用独立 Tomcat 的 Spring Boot 容器身份验证的主要内容,如果未能解决你的问题,请参考以下文章

独立使用时 spring-boot-starter-jdbc 的问题

Spring Boot - 独立 Tomcat / 外部 logback 文件被忽略

部署在 Tomcat 上的 Spring Boot Rest API 提供 404 但独立工作一切正常

在 Tomcat 中部署的 Spring Boot 提供 404 但可以独立运行

Spring Boot YML 和独立 Tomcat 8 服务器

spring boot 嵌入式 tomcat 不以 jcifs smb 库开头