我们在创建 URI 时遵循特定的约定。所有与身份验证相关的 URI,例如 /login
、/logout
、/changepassword
等都属于子上下文 /auth
.
因此我们与身份验证相关的 URI 看起来像:
/auth/login
/auth/logout
/auth/changepassword
这就是我们在 Spring 安全上下文 XML 中的内容。
<http pattern="/auth/**" security="none" />
<http pattern="/resources/**" security="none" />
<http auto-config="true" access-decision-manager-ref="accessDecisionManager">
<intercept-url pattern="/admin/**" access="ADMINISTRATIVE_ACCESS"/>
<intercept-url pattern="/**" access="XYZ_ACCESS"/>
<form-login
login-page="/auth/login"
default-target-url="/content"
authentication-failure-url="/auth/loginFailed"
authentication-success-handler-ref="authenticationSuccessHandler"/>
<logout logout-url="/auth/logout" logout-success-url="/auth/login"/>
</http>
现在的问题是 /auth/logout
在访问时给我一个 404。但是,如果我将其更改为以 /auth
以外的内容开头,例如 /abcd/logout
甚至 /logout
,它就可以正常工作。
我认为这是因为我们已将 /auth/**
定义为不安全的,但仍试图将其用作注销页面。 (没有登录怎么登出?)
有什么办法可以满足我们相当严格的 URI 命名约定吗?
最佳答案
你说得对:
I am thinking this is due to the fact that we have defined
/auth/**
as unsecured and yet trying to use it as a logout page. (How can you access logout if you have not logged in?)
更精确的定义
<http pattern="/auth/**" security="none" />
表示没有 Spring Security 过滤器应用于匹配 /auth/**
的请求模式,因此 Spring Security 不控制 /auth/logout
URL 而它应该。
因为 Spring Security 从上到下匹配模式简单覆盖 /auth/logout
在你的主<http>
行不通,因此可以定义单独的模式来解决该问题:
<http pattern="/auth/login" security="none" />
<http pattern="/auth/changepassword" security="none" />
<http pattern="/resources/**" security="none" />
<http auto-config="true" use-expressions="true" access-decision-manager-ref="accessDecisionManager">
<intercept-url pattern="/auth/logout" access="permitAll"/>
<intercept-url pattern="/admin/**" access="ADMINISTRATIVE_ACCESS"/>
<intercept-url pattern="/**" access="XYZ_ACCESS"/>
<!-- rest of your config -->
</http>
如果你有很多 /auth/*
要处理的URL,可以使用<http>
的 request-matcher="regex"
,但我不认为那样可读。
关于java - 使用 Spring Security 自定义注销 URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12585343/