使用带有 Java 配置的 Spring Security 注销

Posted

技术标签:

【中文标题】使用带有 Java 配置的 Spring Security 注销【英文标题】:Logout with Spring Security with Java configuration 【发布时间】:2015-12-10 01:48:15 【问题描述】:

我正在使用 Spring Security 4.0.2.RELEASE 和 Spring 4.2.0.RELEASE。

我无法创建注销链接(我知道 href 属性的值必须是什么)。

考虑:

使用 WebApplicationInitializer 在 Java 中配置 DelegatingFilterProxy

public class SecurityWebInitializer
    extends AbstractSecurityWebApplicationInitializer 


为 Spring MVC 启用 Web 安全性的简单配置类

@Configuration
@EnableWebSecurity
public class SecurityConfig
    extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(HttpSecurity http) throws Exception 

        http.formLogin().and()
            .authorizeRequests()
            .antMatchers("/spitter/").authenticated()   
            .antMatchers(HttpMethod.GET, "/spitter/register").authenticated().and()

            .logout().deleteCookies("remove")
            .invalidateHttpSession(true).logoutUrl("/logout")
            .logoutSuccessUrl("/");

    

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
        throws Exception 

        auth.inMemoryAuthentication().withUser("user").password("password")
            .roles("USER").and().withUser("admin").password("password")
            .roles("USER", "ADMIN");
    


控制器:

@Controller
@RequestMapping(value = "/spitter")
public class SpittrController 

    private SpittleRepository spittleRepository;

    @Autowired
    public SpittrController(SpittleRepository spittleRepository) 

        this.spittleRepository = spittleRepository;
    

    @RequestMapping(value = "/register", method = RequestMethod.GET)
    public String showRegistrationForm() 

        return "registerForm";
    

    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public String processingRegistration(@Valid Spitter spitter, Errors errors) 

        if (errors.hasErrors()) 
            return "registerForm";
        

        spittleRepository.save(spitter);
        return "redirect:/spitter/" + spitter.getUserName();

    

    @RequestMapping(value = "/username", method = RequestMethod.GET)
    public String showSpitterProfile(@PathVariable("username") String username,
                                     Model model) 

        Spitter spitter = spittleRepository.findByUsername(username);
        if(spitter != null)
            model.addAttribute(spitter);
        

        return "profile";
    

registerForm.jsp:

<form method="post">
        <table>
            <tr>
                <td>First Name:</td>
                <td><input type="text" name="firstName" /></td>
            </tr>
            <tr>
                <td>Last Name:</td>
                <td><input type="text" name="lastName" /></td>
            </tr>
            <tr>
                <td>User Name:</td>
                <td><input type="text" name="userName" /></td>
            </tr>
            <tr>
                <td>Password:</td>
                <td><input type="password" name="password" /></td>
            </tr>
            <tr>

                <td><input type="submit" value="Register" /></td>
            </tr>
        </table>
        <input type="hidden" name="$_csrf.parameterName" value="$_csrf.token">
    </form>

registerForm.jsp 提交后,profile.jsp 会显示给用户: p>

profile.jsp:

<body>
    <h1>Hello world!</h1>

    <p>The time on the server is $serverTime.</p>

    <h1>Your Profile</h1>
    <h1><a href="/logout">Logout</a></h1>


    <table>
        <tr>
            <td>First Name:</td>
            <td><c:out value="$spitter.firstName" /></td>
        </tr>
        <tr>
            <td>Last Name:</td>
            <td><c:out value="$spitter.lastName" /></td>
        </tr>
        <tr>
            <td>User Name:</td>
            <td><c:out value="$spitter.userName" /></td>
        </tr>
    </table>    
</body>

当我击球时

http://localhost:8080/web/spitter/register

我被重定向到登录页面。登录并提交表单后,会显示 profile.jsp,其中包含一个 Logout 链接。点击后,HTTP 404 出现。

我已经通过Spring Security docs,但他们已将 thymeleaf 考虑在内。我的是一个简单的 JSP 页面。

此外,我也考虑到了这一点,

默认情况下,注销 url 需要 POST 请求。去表演 注销您需要的 GET 请求:

http 。登出() .logoutRequestMatcher(new AntPathRequestMatcher("/logout"));

1: http://docs.spring.io/spring-security/site/docs/3.2.x/guides/hellomvc.html

有什么建议吗?

【问题讨论】:

/logout as URL 或表单中的操作仅在您的应用程序以 root 身份部署时才有效。您需要包含context-root。使用&lt;c:url value="/logout" /&gt; 的 URL 标记应该可以解决问题。 @Denium:你的意思是 web/spitter/logout。 如果/web/spitter 是您的应用程序的上下文根,是的,否则不是...如上所述,使用为您执行此操作的 URL 标记。 (同样在答案中,这基本上是正确的,但包含错误的 URL)。 @Deinum:谢谢 Denium。无需包含上下文根,因为默认情况下会考虑它。 【参考方案1】:

将 profile.jsp 中的代码更新为

<h1><a href="#" onclick="javascript:logoutForm.submit();">logout</a></h1>

        <c:url var="logoutUrl" value="/logout" />
        <form action="$logoutUrl" method="post" id="logoutForm">
            <input type="hidden" name="$_csrf.parameterName"
                value="$_csrf.token" />
        </form>

【讨论】:

虽然这个答案是正确的,但您可能会详细说明为什么应该这样做并指出参考指南的相关部分。链接也错了,应该是/logout @Balwinder:不,它没有帮助。我得到了 HTTP 状态 404 - /web/j_spring_security_logout @ShirgillAnsari 网址链接错误。刚刚编辑了我的答案。 @ShirgillAnsari 您现在遇到的错误是什么? @BalwinderSingh:非常感谢。再次感谢您。

以上是关于使用带有 Java 配置的 Spring Security 注销的主要内容,如果未能解决你的问题,请参考以下文章

spring security 1

如何在带有注解配置的spring mvc中使用spring数据

如何在不使用带有java配置的spring的orm.xml中注册实体监听器?

带有 Java 11、HTTPS 和 HTTP 2.0 的 Spring Boot 2

Spring之基于Java配置

重试不使用带有 Java Config 的 Spring Batch