使用JBoss上的Spring MVC Security Java Config时出现404错误

时间:2014-10-16 19:43:42

标签: spring-mvc ssl jboss spring-security spring-java-config

我用Java Config编写了一个小的Spring MVC应用程序,并用Spring Security 3.2.5保护它。它在Tomcat上工作得很好,但在JBoss EAP 6.2上却没有。它在JBoss上成功部署,但是当我请求Spring MVC定义的任何页面和浏览器中的404错误时,我收到此警告。

WARN [org.springframework.web.servlet.PageNotFound] (http-/127.0.0.1:8080-1) No mapping found for HTTP request with URI [/example-web/pages/login.jsp] in DispatcherServlet with name 'dispatcher'

由于使用了Spring Security,因此对于需要经过身份验证的用户的任何请求,例如http://localhost:8080/example-web/start,Spring Security重定向到https://localhost:8443/example-web/login这就是我看到警告和404错误的时候。

在这里你可以看到我的代码:

public class WebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class[] { RootConfiguration.class};
}

@Override
protected Class<?>[] getServletConfigClasses() {
    return new Class[] { WebMvcConfig.class };
}

@Override
protected String[] getServletMappings() {
    return new String[] { "/*" };
}

@Override
protected Filter[] getServletFilters() {
    return new Filter[] { new HiddenHttpMethodFilter() };
}
}

这是我的Spring MVC配置:

@EnableWebMvc
@ComponentScan("com.spring.example.w.controller")
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

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

    @Bean
    public InternalResourceViewResolver getInternalResourceViewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/pages/");
        resolver.setSuffix(".jsp");
        return resolver;
    }
}

以下是我的Spring Security配置:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception{

        http
            .addFilter(myUsernamePasswordAuthenticationFilter())
            .authorizeRequests()
                .antMatchers("/login").permitAll()
                .antMatchers("/admin/**").hasRole("Admin")
                .antMatchers("/start/**").hasRole("Viewer")
                .antMatchers("/user/**").hasRole("User")
                .antMatchers("/**").hasRole("User")
                .and()
            .httpBasic().authenticationEntryPoint(loginUrlAuthenticationEntryPoint())
                .and()
            .logout()
                .permitAll()
                .and()
            .requiresChannel()
                 .anyRequest().requiresSecure();
    }

    @Bean
    public LoginUrlAuthenticationEntryPoint loginUrlAuthenticationEntryPoint(){
        LoginUrlAuthenticationEntryPoint loginUrlAuthenticationEntryPoint = new LoginUrlAuthenticationEntryPoint("/login");
        return loginUrlAuthenticationEntryPoint;
    }


    @Bean
    public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider(){
        ActiveDirectoryLdapAuthenticationProvider authProvider = new ActiveDirectoryLdapAuthenticationProvider(my_domain, my_url);
        authProvider.setConvertSubErrorCodesToExceptions(true);
        authProvider.setUseAuthenticationRequestCredentials(true);
        authProvider.setUseAuthenticationRequestCredentials(true);
        authProvider.setUserDetailsContextMapper(userDetailsContextMapper());
        return authProvider;
    }

    @Bean
    public UserDetailsContextMapper userDetailsContextMapper(){
        CustomUserDetailsContextMapper myAuthoritiesPopulator = new CustomUserDetailsContextMapper();
        return myAuthoritiesPopulator;
    }

    @Bean
    public CustomUsernamePasswordAuthenticationFilter myUsernamePasswordAuthenticationFilter()
            throws Exception {
        CustomUsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter = new CustomUsernamePasswordAuthenticationFilter();
        usernamePasswordAuthenticationFilter.setAuthenticationManager(authenticationManager());
        usernamePasswordAuthenticationFilter.setAllowSessionCreation(true);
        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        usernamePasswordAuthenticationFilter.setAuthenticationSuccessHandler(successHandler);
        usernamePasswordAuthenticationFilter.setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler("/login?error"));
        usernamePasswordAuthenticationFilter.afterPropertiesSet();
        return usernamePasswordAuthenticationFilter;
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
        auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
    }
}

然后是SecurityWebApplicationInitializer:

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
}

和RootConfig:

@Configuration
@ComponentScan
public class RootConfiguration {
}

以下是我为JBoss配置SSL的方法:

<subsystem xmlns="urn:jboss:domain:web:1.5" default-virtual-server="default-host" native="false">
    <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http" redirect-port="8443"/>
    <connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" enable-lookups="false" secure="true">
        <ssl name="ssl" password="<my_password>" certificate-key-file="c:\mykeystore.jks" protocol="TLSv1" verify-client="false"/>
    </connector>
    <virtual-server name="default-host" enable-welcome-root="true">
        <alias name="localhost"/>
        <alias name="example.com"/>
    </virtual-server>
</subsystem>

在部署期间,我可以在日志中看到请求已映射到:

INFO  [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping] (ServerService Thread Pool -- 71) Mapped "{[/start],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView com.spring.example.w.controller.StartController.handleStart() throws javax.servlet.ServletException,java.io.IOException
INFO  [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping] (ServerService Thread Pool -- 71) Mapped URL path [/login] onto handler of type [class org.springframework.web.servlet.mvc.ParameterizableViewController]
INFO  [org.springframework.web.context.ContextLoader] (ServerService Thread Pool -- 71) Root WebApplicationContext: initialization completed in 2530 ms
INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/example-web]] (ServerService Thread Pool -- 71) Initializing Spring FrameworkServlet 'dispatcher'
INFO  [org.springframework.web.servlet.DispatcherServlet] (ServerService Thread Pool -- 71) FrameworkServlet 'dispatcher': initialization started

有关我为何会收到404错误的任何帮助,我们非常感谢此警告。我应该再一次强调它正在使用Tomcat。提前谢谢。

1 个答案:

答案 0 :(得分:0)

您可以检查连接器端口是否已启用SSL。此链接有一些细节。 Redirecting from non ssl port 8080 to ssl port 8443

希望有所帮助