在CustomLogoutSuccessHandler中,身份验证对象始终为null。

4

我在自定义的 logoutSuccesshandler 中始终获取到 null 的 Authentication 对象,不确定问题出在哪里。:(

这是 spring-security 文件:

    <sec:http auto-config="true" entry-point-ref="ssoProcessingFilterEntryPoint"
        access-decision-manager-ref="affirmativeBased">
        <sec:intercept-url pattern="/afterAuthn/**" access="${spring.security.role}" />
        <sec:intercept-url pattern="/tenancy/**" access="${spring.security.role}" />
        <!-- Add permissions to specific URLS - i.e. IAM.User.Read for /resources/** -->
        <sec:intercept-url pattern="/**"
            access="${default.permission}" />
        <sec:logout invalidate-session="true" delete-cookies="true"
            success-handler-ref="customLogoutSuccessHandler" />
        <sec:custom-filter ref="ssoAuthenticationFilter"
            position="PRE_AUTH_FILTER" />
        <sec:session-management>
            <sec:concurrency-control max-sessions="1" />
        </sec:session-management>
    </sec:http>
..
<bean id="customLogoutSuccessHandler"
        class="usermgmt.service.CustomLogoutSuccessHandler">
         <property name="defaultLogoutSuccessUrl" value="${service.provider.logout.success.url}"/>
    </bean>

我的自定义类处理程序:

public class CustomLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException {
        if (authentication == null) {
            System.out.println("NULL");
        } else {
            System.out.println("NOT NULL");
        }
}}

在这里,认证始终为NULL,Spring安全版本为3.1.0.RELEASE。

这不是正确的行为吗?我的意思是,如果用户已经正确地注销了自己,认证对象应该为空,因为实际上没有什么可显示的。如果认证对象不为空,那就意味着你必须手动取消用户的认证。 - itachi
是的,这是正确的行为。您可以参考此网址:http://javapointers.com/tutorial/spring-custom-logoutsuccesshandler-example/。 - Waheed
我在代码中花了一些时间,发现这并不像我们想象的那么简单。请查看Spring Security WEB中的LogoutFilter类。观察doFilter()方法,你会发现认证对象被获取并传递到logout()方法,最终到达你的LogoutSuccessHandler。因此,这意味着你的SecurityContext返回null而不是一个认证对象(这里不应该出现这种情况)。你可以调试此方法,找出为什么你的Authentication为空。 - itachi
当我尝试URL示例时,它完全正常工作,但是当我尝试将其与我的应用程序集成时,我得到了空值。因此,我猜测调试是唯一剩下的选项。谢谢! - Waheed
@Waheed 你调试过了吗?结果是什么?如果你能分享一下你的发现就太好了... - Lonzak
1个回答

1
这可能是因为您在Spring Security中配置了SecurityContextLogoutHandler。SecurityContextLogoutHandler会清除安全上下文,从而清除认证对象。您的自定义处理程序在SecurityContextLogoutHandler之后被调用。为了保留认证对象,您将需要创建自定义SecurityContextLogoutHandler并在其中添加必要的逻辑。
在此类中,您有两个选项:
1. 将认证对象放入请求属性中,以便在自定义注销成功处理程序中检索
2. 或者,在您的自定义SecurityContextLogoutHandler中计算URL,并将其设置为请求属性。在自定义注销成功处理程序中检索它并将其设置为默认目标URL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接