我已成功配置Spring引導應用程序以使用Spring安全預認證框架,依靠Tomcat 7容器從tomcat-users.xml文件進行身份驗證。我還能夠添加一個自定義的AuthenticationUserDetailsService來將權限映射到容器驗證的用戶(我不想管理容器中的應用程序角色)。我花了一段時間纔得到Java配置,但我把它們都像魅力一樣工作......但只有當我使用BASIC認證(如web.xml中配置)時。當我嘗試轉換爲FORM認證時,過濾器鏈中間出現問題。使用預認證爲Spring Boot/Security應用程序配置FORM身份驗證時遇到問題
在web.xml中配置的登錄表單正在渲染(使用this example中的themeleaf)。我還從日誌中看到,用戶正在成功驗證與容器按預期進行通信的意思。我還會看到J2eePreAuthenticatedProcessingFilter選取J2EE主體並調用自定義的AuthenticationUserDetailsService來映射角色。但是,在日誌中稍微有點下降,看起來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_'之前,因爲我不想將任何角色映射到應用程序中。我使用我的自定義AuthenticationUserDetailsService。
這是我的主要配置文件。請注意,我也有一個實現了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安全限制嗎?
任何幫助將非常感激。