2014-10-29 82 views
1

我已成功配置Spring引導應用程序以使用Spring安全預認證框架,依靠Tomcat 7容器從tomcat-users.xml文件進行身份驗證。我還能夠添加一個自定義的AuthenticationUserDetailsS​​ervice來將權限映射到容器驗證的用戶(我不想管理容器中的應用程序角色)。我花了一段時間纔得到Java配置,但我把它們都像魅力一樣工作......但只有當我使用BASIC認證(如web.xml中配置)時。當我嘗試轉換爲FORM認證時,過濾器鏈中間出現問題。使用預認證爲Spring Boot/Security應用程序配置FORM身份驗證時遇到問題

在web.xml中配置的登錄表單正在渲染(使用this example中的themeleaf)。我還從日誌中看到,用戶正在成功驗證與容器按預期進行通信的意思。我還會看到J2eePreAuthenticatedProcessingFilter選取J2EE主體並調用自定義的AuthenticationUserDetailsS​​ervice來映射角色。但是,在日誌中稍微有點下降,看起來HttpSessionSecurityContextRepository爲SPRING_SECURITY_CONTEXT獲得了一個空對象(在通過過濾鏈進行'/ login'?時)。因此,似乎不再提及J2EE主體,隨後使用「匿名標記」創建SecurityContextHolder。儘管我發現它找到了我爲'/ login'url(在Spring配置中)配置的'[permitAll]',但它仍然這樣做。

這裏是我的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中有「用戶」和「用戶」角色的用戶名的用戶。我不會在'ROLE_'之前,因爲我不想將任何角色映射到應用程序中。我使用我的自定義AuthenticationUserDetailsS​​ervice。

這是我的主要配置文件。請注意,我也有一個實現了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("/"); 

     } 
    } 
} 

還有一個login.html的形式員額/ j_security_check。讓我知道你是否需要它,雖然它非常直截了當,它看起來(從日誌)它正在工作。

再一次地,所有的東西都完全可以在web.xml中配置BASIC認證。一旦我進入FORM,我就會在過濾器處理鏈中間丟棄J2EE主體。

想法?難道我需要以不同的方式配置我的web.xml安全限制嗎?

任何幫助將非常感激。

回答

0

已解決。事實證明,我還需要將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> 
相關問題