Spring security 使用预身份验证为Spring Boot/Security应用程序配置表单身份验证时出现问题

Spring security 使用预身份验证为Spring Boot/Security应用程序配置表单身份验证时出现问题,spring-security,tomcat7,spring-boot,Spring Security,Tomcat7,Spring Boot,我已经成功地配置了一个spring引导应用程序来使用spring安全预认证框架,依靠Tomcat 7容器从Tomcat-users.xml文件进行认证。我还能够添加一个自定义AuthenticationUserDetails服务,以将权限映射到容器验证的用户(我不想管理容器中的应用程序角色)。我花了一段时间才放下Java配置,但我让它像一个魔咒一样工作……但只有当我使用基本身份验证时(如web.xml中配置的)。当我试图转换成表单验证时,过滤链中间的东西出错了。 正在呈现web.xml中配置的登

我已经成功地配置了一个spring引导应用程序来使用spring安全预认证框架,依靠Tomcat 7容器从Tomcat-users.xml文件进行认证。我还能够添加一个自定义AuthenticationUserDetails服务,以将权限映射到容器验证的用户(我不想管理容器中的应用程序角色)。我花了一段时间才放下Java配置,但我让它像一个魔咒一样工作……但只有当我使用基本身份验证时(如web.xml中配置的)。当我试图转换成表单验证时,过滤链中间的东西出错了。 正在呈现web.xml中配置的登录表单(使用中的MELEAF)。我还从日志中看到,用户正在成功地进行身份验证,这意味着用户正在按预期与容器通信。我还看到J2eePreAuthenticatedProcessingFilter拾取J2EE主体并调用自定义AuthenticationUserDetails服务来映射角色。然而,在日志中再往下一点,HttpSessionSecurityContextRepository似乎为SPRING\u SECURITY\u上下文获取了一个空对象(同时通过“/login”的过滤链)。因此,似乎不再引用J2EE主体,并随后使用“匿名令牌”创建SecurityContextHolder。尽管我看到它找到了我为“/login”url(在Spring配置中)配置的“[permitAll]”,它还是这样做了

以下是my web.xml的摘录:

    <!-- Define a Security Constraint on this Application -->
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Secured (entire app)</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>USER</role-name>
        </auth-constraint>
    </security-constraint>

    <!-- Define the Login Configuration for this Application -->
    <login-config>
        <auth-method>FORM</auth-method>
        <form-login-config>
            <form-login-page>/login</form-login-page>
            <form-error-page>/login?error</form-error-page>
        </form-login-config>
    </login-config>

    <!-- Security roles referenced by this web application -->
    <security-role>
        <description>
            The role that is required to access the application
        </description>
        <role-name>USER</role-name>
    </security-role>

安全(整个应用程序)
/*
使用者
形式
/登录
/登录错误
访问应用程序所需的角色
使用者
因此,我的tomcat-users.xml有一个用户名为“user”的用户和一个角色为“user”。我没有在“角色\”前面加上,因为我没有尝试将任何角色映射到应用程序中。为此,我使用自定义AuthenticationUserDetails服务

这是我的主配置文件。注意,我还有一个实现SpringBootServletInitializer并将SpringApplicationBuilder配置为指向该类的类:

@EnableAutoConfiguration
@ComponentScan
@EnableGlobalMethodSecurity(securedEnabled = true)
public class MyApplicationConfig extends WebMvcConfigurerAdapter {

    @Controller
    protected static class HomeController {

        // ROLE_MYAPP_USER is mapped to all authenticated users by custom AuthenticationUserDetailsService
        @RequestMapping({"/", "/about", "/profile"})
        @Secured("ROLE_MYAPP_USER")
        public ModelAndView index(@CurrentUser User user) {
            Map<String, Object> model = new HashMap<>();
            model.put("currentUser", user);
            //noinspection SpringMVCViewInspection
            return new ModelAndView("index", model);
        }

    }

    public static void main(String[] args) throws Exception {
        new SpringApplicationBuilder(VodConsoleApplication.class).run(args);
    }

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

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new CurrentUserHandlerMethodArgumentResolver());
    }


    @Bean
    public ApplicationSecurity applicationSecurity() {
        return new ApplicationSecurity();
    }

    @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
    protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable();

        http
                .authorizeRequests()
                .antMatchers("/login").permitAll()
                .antMatchers("/error").permitAll()
                .antMatchers("/css/**").permitAll()
                .antMatchers("/img/**").permitAll()
                .antMatchers("/js/**").permitAll()
                .antMatchers("/partials/**").permitAll()
                .antMatchers("/vendor/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .jee()
                .authenticatedUserDetailsService(new InMemoryUserDetailsService());
        http.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/");

        }
    }
}
@EnableAutoConfiguration
@组件扫描
@EnableGlobalMethodSecurity(securedEnabled=true)
公共类MyApplicationConfig扩展了WebMVCConfigureAdapter{
@控制器
受保护的静态类HomeController{
//自定义AuthenticationUserDetailsService将角色\u MYAPP\u用户映射到所有经过身份验证的用户
@请求映射({”/“,”/about“,“/profile”})
@安全(“角色\我的应用\用户”)
公共模型和视图索引(@CurrentUser){
映射模型=新的HashMap();
model.put(“当前用户”,用户);
//无检查弹簧MVCViewInspection
返回新模型和视图(“索引”,模型);
}
}
公共静态void main(字符串[]args)引发异常{
新的SpringApplicationBuilder(VodConsoleApplication.class).run(args);
}
@凌驾
public void addViewController(ViewControllerRegistry注册表){
registry.addViewController(“/login”).setViewName(“login”);
}
@凌驾
public void addArgumentResolver(列出ArgumentResolver){
添加(新的CurrentUserHandlerMethodArgumentResolver());
}
@豆子
公共应用程序安全性应用程序安全性(){
返回新的应用程序安全性();
}
@顺序(SecurityProperty.ACCESS\u OVERRIDE\u顺序)
受保护的静态类应用程序安全性扩展了WebSecurity配置适配器{
@凌驾
受保护的无效配置(HttpSecurity http)引发异常{
http
.csrf().disable();
http
.授权请求()
.antMatchers(“/login”).permitAll()
.antMatchers(“/error”).permitAll()
.antMatchers(“/css/**”).permitAll()
.antMatchers(“/img/**”).permitAll()
.antMatchers(“/js/**”).permitAll()
.antMatchers(“/partials/**”).permitAll()
.antMatchers(“/vendor/**”).permitAll()
.anyRequest().authenticated()
.及()
.jee()
.authenticatedUserDetailsService(新的InMemoryUserDetailsService());
http.logout().logoutRequestMatcher(新的AntPathRequestMatcher(“/logout”)).logoutSuccessUrl(“/”);
}
}
}
还有一个login.html表单发布到/j_security_check。让我知道如果你需要它,虽然它是非常直接的,它似乎(从日志)是工作

同样,在web.xml中配置基本身份验证时,一切都可以完美地工作。一旦我进入了窗体,我就得到了J2EE主体在过滤器处理链中间的下降。 想法?我是否需要以不同的方式配置web.xml安全约束


任何帮助都将不胜感激。

已解决。事实证明,我还需要将所有“公共”资源的url模式添加到web.xml中。具体来说,javascript(在“vendor”和“js”目录中)、css、img等。下面是我更新的web.xml:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>Public resources</web-resource-name>
        <url-pattern>/vendor/*</url-pattern>
        <url-pattern>/js/*</url-pattern>
        <url-pattern>/css/*</url-pattern>
        <url-pattern>/img/*</url-pattern>
        <url-pattern>/partials/*</url-pattern>
    </web-resource-collection>
</security-constraint>
<security-constraint>
    <web-resource-collection>
        <web-resource-name>Secured (entire app)</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>USER</role-name>
    </auth-constraint>
</security-constraint>

<!-- Define the Login Configuration for this Application -->
<login-config>
    <auth-method>FORM</auth-method>
    <form-login-config>
        <form-login-page>/login</form-login-page>
        <form-error-page>/login?error</form-error-page>
    </form-login-config>
</login-config>
<!-- Security roles referenced by this web application -->
<security-role>
    <description>
        The role that is required to access the application
    </description>
    <role-name>USER</role-name>
</security-role>

公共资源
/卖主/*
/js/*
/css/*
/img/*
/分部/*
安全(整个应用程序)
/*
使用者
形式
/登录
/登录错误
访问应用程序所需的角色
使用者