使用 Spring MVC 和 Spring Security 进行 404 注销

Posted

技术标签:

【中文标题】使用 Spring MVC 和 Spring Security 进行 404 注销【英文标题】:404 logout with SpringMVC and SpringSecurity 【发布时间】:2016-01-08 11:14:46 【问题描述】:

我正在学习 spring 安全性(基于 java 的配置),但我无法使注销正常工作。当我点击注销时,我看到 URL 更改为 http://localhost:8080/logout 并获得“HTTP 404 - /logout”。登录功能工作正常(即使使用自定义登录表单)但注销是问题,我怀疑重定向的 url “localhost:8080/logout”应该像“localhost:8080/springtest/logout”

我正在关注一本书和这些示例的组合: http://docs.spring.io/spring-security/site/docs/3.2.x/guides/hellomvc.html

我正在使用:

   <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.1.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>4.0.2.RELEASE</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-core</artifactId>
        <version>4.0.2.RELEASE</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>4.0.2.RELEASE</version>
        <scope>compile</scope>
    </dependency>

这是 MVC 初始化器:

    public class MvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer 

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

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

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

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

这是安全初始化器:

    public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer 


这是网络配置:

@Configuration
@EnableWebMvc
@EnableTransactionManagement
@ComponentScan(basePackages =  "org.munilvc.springtest" )
public class WebApplicationContextConfig extends WebMvcConfigurerAdapter 

    @Bean(name = "viewResolver")
    public InternalResourceViewResolver getViewResolver() 
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    

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

    // Serve static content like <mvc:resources/> tags
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) 
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/magic/").setCachePeriod(31556926);
    


这是安全配置:

@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception 
        auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
    

还有一个 home 控制器,我不确定这是不是最好的方法,但我希望 localhost:8080/springtest 重定向到 home,Spring security 应该通过登录页面拦截它。这现在对我有用,但我想知道这是否是正确的方法?

@Controller
public class HomeController 

  @RequestMapping("/")
  public String showLoginForm(Model model) 
    return "home";
  


最后,这是我主页中的注销:

        <p class="navbar-text navbar-right">
            Signed in as <a href="#" class="navbar-link">$pageContext.request.remoteUser</a>

        <form class="navbar-form pull-right" action="/logout"
            method="post">
            <input type="hidden" name="$_csrf.parameterName"
                value="$_csrf.token" /> <input type="submit" value="Log out" />
        </form>

我需要为注销做一个明确的请求映射吗?我已经检查了 spring 文档中的示例应用程序 hellomvc-jc,但是我没有看到任何明确的请求映射,所以我相信 SpringSecurity 4 已经处理好了,不是吗?

非常感谢!非常感谢您抽出宝贵的时间,希望这对其他人有所帮助。

【问题讨论】:

【参考方案1】:

使用action="logout" 代替action="/logout"

【讨论】:

谢谢詹姆斯·吉辛,这成功了!我很确定我尝试过那个,但考虑到我尝试过的配置/组合的数量,我根本不确定。我的问题是,为什么我看到文档仍然使用“/logout”而不是“logout”?我怀疑这与视图解析器或某些请求映射有关?

以上是关于使用 Spring MVC 和 Spring Security 进行 404 注销的主要内容,如果未能解决你的问题,请参考以下文章

Spring boot、mvc、hibernate 和 mysql 配置 - sessionFactory 错误

spring mvc jsp怎么获得ModelAndView设置的值 急急急!

Spring MVC官方文档学习笔记之DispatcherServlet

MVC Java SE 应用程序使用 ActiveMQ 进行通信

在 Spring MVC 中将 Bean 放入控制器的问题

Spring框架总结——概述