导读:单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。一般分为两种,一种是同域的,一种是不同域的,本文使用Cookie作为验证媒介,实现同域的单点登录。
简介
使用Cookie作为验证媒介,原理上不算复杂(实现起来业务逻辑还是比较复杂),用户在WebApp1中登录,将凭证保存在WebApp1的Cookie中,同时在WebApp2的Cookie中也进行保存,当用户访问WebApp2时,从Cookie中拿出凭证,直接就是登录状态。
简单来讲,逻辑如下图:(来源于JC_Huang的简书文章:单点登录的三种实现方式)。
本文代码部门参考了慕课网的课程。
登录实现
登录实现流程:
本文的登录实现流程,大致如下:
首先一共有三个Web服务器,一个用于管理登录的SSO服务器,两个Web应用。橘色的线,表示首次登录的流程,红色的线,表示登录过其中一个Web应用后,再登录第二个的流程。
由于WebApp1和WebApp2是等价的,下面只展示WebApp1的代码,稍作修改就是WebApp2的代码。
接下来的代码,根据这个流程进行。
WebApp过滤器:
WebApp过滤器用来监控一切访问WebApp的请求。当Web应用启动,想进入默认index页面的时候,会被过滤器拦截。
首先设置两个属性,server表示SSO Server的地址,app表示当前Web应用的地址,然后从初始化参数里面获取。
接下来,在Cookie中搜寻,看是否有登录凭证ticket,第一次访问,肯定没有登录,ticket=null。
再从URL中获取,第一次访问,URL中没有ticket参数,依旧为空,所以跳转至登录SSO Server的/ssoLogin。
//WebApp1 Filter
@WebFilter(filterName = "UserFilter",urlPatterns = "/*",
initParams = {@WebInitParam(name="server",value="http://localhost:8080"),
@WebInitParam(name="app",value="http://localhost:8082")})
public class UserFilter implements Filter {
private String server;
private String app;
public void init(FilterConfig config) throws ServletException {
server=config.getInitParameter("server");
app=config.getInitParameter("app");
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
String ticket=null;
//如果Cookies不为空
if(null!=((HttpServletRequest)req).getCookies()){
for(Cookie cookie:((HttpServletRequest)req).getCookies()){
//看是否有我们需要的凭证Cookie
if(Objects.equals(cookie.getName(),"Ticket_Granting_Ticket")){
ticket=cookie.getValue();
break;
}
}
}
//如果Ticket不为空,就表示已经登录过了,进入到主页
if(!Objects.equals(null,ticket)){
chain.doFilter(req, resp);
return;
}
//Cookie中为空,则从URL获取
ticket=req.getParameter("ticket");
//如果能获取到,则将凭证保存至当前Web应用的Cookie
if(!Objects.equals(null,ticket)&&!Objects.equals("",ticket.trim())){
((HttpServletResponse)resp).addCookie(new Cookie("Ticket_Granting_Ticket",ticket));
chain.doFilter(req,resp);
return;
}
//不能获取,则跳转至登录页面。
else{
((HttpServletResponse)resp).sendRedirect(server+