记一次手写单点登录
系统流程设计
学习单点登录首推:
极客分布式系统单点登陆入门到基础到原理实战
以下是我的学习心得
关于Cookie信息跨域共享的实现:
- 利用HTML Script标签跨域写Cookie
- P3P协议
- 通过URL参数实现跨域信息的传递
单点登录的核心问题就是如何解决Cookie跨域的读写,这里我们采用的是通过URL参数实现跨域信息的传递。
记关闭浏览器为一次会话,浏览器关闭后vt失效
SSO服务器登录入口:
/**
* 登录入口
*
* @param request
* @param backUrl
* @param response
* @param map
* @return
* @throws Exception
*/
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String login(HttpServletRequest request, String backUrl,
HttpServletResponse response, ModelMap map, Boolean notLogin) throws Exception {
String vt = CookieUtil.getCookie("VT", request);
if (vt == null) {
// VT不存在
String lt = CookieUtil.getCookie("LT", request);
if (lt == null) {
// VT不存在,LT也不存在
return authFailed(notLogin, response, backUrl);
} else {
// VT不存在, LT存在
LoginUser loginUser =config.getAuthenticationHandler().autoLogin(lt);
if (loginUser == null) {
return authFailed(notLogin, response, backUrl);
} else {
vt = authSuccess(response, loginUser, true);
return validateSuccess
(backUrl, vt, loginUser, response,map);
}
}
} else {
// 跳转到登录页
LoginUser loginUser = TokenManager.validate(vt);
if (loginUser != null) {
// VT有效
return validateSuccess(backUrl, vt, loginUser, response, map);
// 验证成功后操作
} else {
// VT 失效,转入登录页
// return config.getLoginViewName();
return authFailed(notLogin, response, backUrl);
}
}
}
VT不存在,LT也不存在,并且允许授权登录 跳转到登录页,不允许则跳转403
VT不存在,LT存在,并且验证用户通过,无需输入登录信息;未通过,跳转到登录页,未授权跳转403。
VT存在且有效,无需输入登录信息;无效跳转到登录页,未授权跳转403。
Vt存在但失效,跳转到登录页,未授权跳转403
登录校验:
@RequestMapping(method = RequestMethod.POST, value = "/login")
public String login(String backUrl, Boolean rememberMe,
HttpServletRequest request, HttpSession session,
HttpServletResponse response, ModelMap map) throws Exception {
final Map<String, String[]> params = request.getParameterMap();
//"login_session_attr_name"
final Object sessionVal = session.
getAttribute(IPreLoginHandler.SESSION_ATTR_NAME);
Credential credential = new Credential() {
@Override
public String getParameter(String name) {
String[] tmp = params.get(name);
return tmp != null && tmp.length > 0 ? tmp[0] : null;
}
@Override
public String[] getParameterValue(String name) {
return params.get(name);
}
@Override
public Object getSettedSessionValue() {
return sessionVal;
}
};
LoginUser loginUser = config.getAuthenticationHandler()
.