解决Spring Security 登录(登出)成功 后置处理的业务

目前的项目使用了 Spring Security 2.0.4 权限管理框架。 登录授权都由框架直接处理,所以也就产生了登录成功后 记录登录日志的需求。
找一上午资料基本都是 Spring Security 3的配置实现。最后随手拿起Spring企业应用开发详解看了一下Acegi的章节,发现原来如此。

首先看一下关键代码 ProviderManager 类中 在 doAuthentication 授权成功的时候,
创建了授权成功事件。 触发登录成功后置业务 就是 监听该事件并做相关操作。

if (result != null) {
sessionController.registerSuccessfulAuthentication(result);
[b] publishEvent(new AuthenticationSuccessEvent(result));[/b]

return result;
}


实现 授权成功 事件监听器

public class LoginSuccessListener implements ApplicationListener {

public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof AuthenticationSuccessEvent) {
AuthenticationSuccessEvent authEvent = (AuthenticationSuccessEvent) event;
UserDetails user = (UserDetails) authEvent.getAuthentication().getPrincipal();
System.out.println("模拟输出用户登录日志:[" + java.util.Calendar.getInstance().getTime() + "] " + user.getUsername());
}

}
}


在Spring中加入 监听器。

<bean class="LoginSuccessListener"></bean>

至此成功写入登录日志


登录后置处理好了 紧接着 登出后置处理需求有来了!

看看登出 业务处理的关键代码吧!
详见 LogoutFilter
 private String filterProcessesUrl = "/j_spring_security_logout";
private String logoutSuccessUrl;
private LogoutHandler[] handlers;
private boolean useRelativeContext;

与登出过滤器有关的主要属性
登出成功后的 转向 URL 登出处理程序 接口数组
具体的登出处理代码

if (requiresLogout(request, response)) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();

if (logger.isDebugEnabled()) {
logger.debug("Logging out user '" + auth + "' and redirecting to logout page");
}

for (int i = 0; i < handlers.length; i++) {
handlers[i].logout(request, response, auth);
}

String targetUrl = determineTargetUrl(request, response);

sendRedirect(request, response, targetUrl);

return;
}

登出操作 其实就是 循环没有登出处理接口 然后在转向 目标URL. 那么登出处理接口都包括哪些 又是从哪里来的呢?

答案就在 LogoutBeanDefinitionParser 里

if (!StringUtils.hasText(logoutUrl)) {
logoutUrl = DEF_LOGOUT_URL;
}
builder.addPropertyValue("filterProcessesUrl", logoutUrl);

if (!StringUtils.hasText(logoutSuccessUrl)) {
logoutSuccessUrl = DEF_LOGOUT_SUCCESS_URL;
}
builder.addConstructorArg(logoutSuccessUrl);

if (!StringUtils.hasText(invalidateSession)) {
invalidateSession = DEF_INVALIDATE_SESSION;
}

ManagedList handlers = new ManagedList();
[b] SecurityContextLogoutHandler sclh = new SecurityContextLogoutHandler();[/b]
if ("true".equals(invalidateSession)) {
sclh.setInvalidateHttpSession(true);
} else {
sclh.setInvalidateHttpSession(false);
}
handlers.add(sclh);
if (rememberMeServices != null) {
[b] handlers.add(new RuntimeBeanReference(rememberMeServices));[/b]
}

builder.addConstructorArg(handlers);




所以 LogoutHandler 数组其实也就是 2个 固化了得数值,没有找到可以灵活配置 添加后置处理的地方。 (rememberMeServices 可以接受一个传入的bean id)

可以说 Logout 没有预备 事件的触发和扩展了, 要实现 Logout后置其实也很简单
修改 logout-success-url 属性, 指向一个自己需要做后置事情的地址,该地址判断用户是否确实 无授权了, 无授权即认为 登出了一次 做想过后置操作
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值