SSO 基于Cookie+fliter实现单点登录 实例解析(一)
接上文,SSO的理论讲解,接下来实践实践!
1、使用Cookie解决单点登录
技术点:
1、设置Cookie的路径为setPath("/").即Tomcat的目录下都有效
2、设置Cookie的域setDomain(".itcast.com");即bbs.itcast.com,或是mail.itcast.com有效。即跨域。
3、设置Cookie的时间。即使用户不选择在几天内自动登录,也应该保存Cookie以保存在当前浏览器没有关闭的情况下有效。
4、使用Filter自动登录。
实现步骤
1:首先要准备出几个虚拟主机并配置hosts文件,即本机DNS修改本机的C:\Windows\System32\drivers\etc下的hosts文件。
<span style="font-size:18px;"><span style="font-size:18px;"># localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 localhost 127.0.0.1 localhost
127.0.0.1 www.bbs.itcast.cn
127.0.0.1 www.news.itcast.cn
127.0.0.1 www.news.com
127.0.0.1 www.bbs.com
127.0.0.1 www.server.com
</span></span>
增加几个Host节点,通过Cookie实现自动登录,必须配置的虚拟主页满足xxx.itcast.cn,即主域名必须保持一致。
一般web应用中一般部署在web.xml文件中,单点退出相关配置如下:
<span style="font-size:18px;"><span style="font-size:18px;"><filter>
<filter-name>CAS Authentication Filter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<!--到哪去登录-->
<param-name>casServerLoginUrl</param-name>
<param-value>http://www.server.com:8080/login</param-value>
</init-param>
<init-param>
<!--我是谁-->
<param-name>serverName</param-name>
<param-value>http://www.bbs.com:8080</param-value>
</init-param>
<init-param>
<param-name>renew</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>gateway</param-name>
<param-value>false</param-value>
</init-param>
</filter> <filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>http://www.server.com:8080</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://www.bbs.com:8080</param-value>
</init-param> <!--
<init-param>
<param-name>proxyCallbackUrl</param-name>
<param-value>https://localhost:8443/mywebapp/proxyCallback</param-value>
</init-param>
<init-param>
<param-name>proxyReceptorUrl</param-name>
<param-value>/mywebapp/proxyCallback</param-value>
</init-param>
-->
</filter> <filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter> <filter>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter> <!-- ************************* --> <!-- Sign out not yet implemented -->
<!--
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
--> <filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<url-pattern>/protected/*</url-pattern>
</filter-mapping> <filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <filter-mapping>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/proxyCallback</url-pattern>
</filter-mapping> <!-- *********************** --> <!-- Sign out not yet implemented -->
<!--
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
--> <!-- *********************** --> <welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list></span></span>
说明:我们看到单点退出的相关类结构,web.xml配置了单点退出的相关类(1个监听器SingleSignOutHttpSessionListener,2个过滤器SingleSignOutFilter,SimpleServerLogoutHandler)。
实现利用了session存储机制,SessionStoreManager是个单例类,用于管理session的存储、删除;SessionMappingStorage是session的存储、删除的执行者,可以看到实际存储的结构是一个artifactId、sessionId为名值对的HashMap表;监听器SingleSignOutHttpSessionListener的作用是session销毁时,调用session管理单例类SessionStoreManager进行session的删除销毁;
SingleSignOutFilter的作用有2个:一个是在单点访问拦截安全资源时调用单例类SessionStoreManager存储session,另一个是在单点退出时调用单例类SessionStoreManager删除session;SimpleServerLogoutHandler的作用是将客户端的退出请求转发到SSO服务器端,集中处理做各个子系统的单点退出。
2、先在bbs(或是mail)虚拟目录下,开发一个可以自动登录的程序,使用Filter:
<span style="font-size:18px;"><span style="font-size:18px;">1、登录的主页如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
</head>
<body>
<p>在同一台服务器上,多个站点自动登录....>>:<%=session.getId()%></p>
<c:if test="${empty sessionScope.user}">
<form name="f" method="post" action="<c:url value='/login'/>">
Name:<input type="text" name="name"/><br/>
Pwd:<input type="text" name="pwd"/><br/>
<input type="checkbox" name="chk" value="7">一周内自动登录<br/>
<input type="submit" value="登录"/>
</form>
</c:if>
<c:if test="${not empty sessionScope.user}">
欢迎你:${user}。<a href="<c:url value='/loginout'/>">安全退出</a>
</c:if>
<br/>
相关站点:(只要在一边登录成功,即可以自动登录到另一个程序)<br/>
<a href="http://mail.itcast.com:7777">mail.itcast.com</a><br/>
<a href="http://bbs.itcast.com:7777">bbs.itcast.com</a><br/>
</body>
</html>
</span></span>
2、登录的Servlet程序如下:
<span style="font-size:18px;"><span style="font-size:18px;">/**
* 用户登录
*/
public class LoginServlet extends HttpServlet{
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req, resp);
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String nm = req.getParameter("name");
String pwd = req.getParameter("pwd");
String chk = req.getParameter("chk"); //是否选中了7天自动登录
String forward = "/index.jsp";
if(nm!=null && !nm.trim().equals("") && nm.startsWith("it")//用户名是it开始,且密码是pwd开始的可以登录
&& pwd !=null && !pwd.trim().equals("") &&
pwd.startsWith("pwd")){
System.err.println("登录成功。。。。。");
forward = "/jsps/welcome.jsp";
//无论如何,都要设置cookie,如果没有选择自动登录,则只在当前页面的跳转时有效,否则设置有效期间为7天。
Cookie cookie = new Cookie("autologin",nm+"@"+pwd);
cookie.setPath("/"); //如果路径为/则为整个tomcat目录有用
cookie.setDomain(".itcast.com"); //设置对所有*.itcast.com为后缀的域名效
if(chk!=null){
int time = 1*60*60*24*7; //1秒*60=1分*60分=1小时*24=1天*7=7天
cookie.setMaxAge(time);
}
resp.addCookie(cookie);
req.getSession().setAttribute("user", nm);
}else{
System.err.println("登录不成功。。。。。。");
}
req.getRequestDispatcher(forward).forward(req, resp);
}
} </span></span>
3、自动登录的Filter程序如下:
<span style="font-size:18px;"><span style="font-size:18px;">/**
* 自动登录
*/
public class AutoLogin implements Filter {
public void destroy() {}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
System.err.println("开始自动登录验证.....");//此类中应该对登录的servlet直接放行。根据判断url决定。
HttpServletRequest requ = (HttpServletRequest) req;
HttpSession s = requ.getSession();
if (s.getAttribute("user") != null) {//如果用户已经登录则直接放行
System.err.println("用户已经登录,没有必须要再做自动登录。。。。");
} else {
Cookie[] cookies = requ.getCookies();
if (cookies != null) {
for (Cookie ck : cookies) {
if (ck.getName().equals("autologin")) {// 是否是自动登录。。。。
System.err.println("自动登录成功。。。。。");
String val = ck.getValue();
String[] vals = val.split("@");
s.setAttribute("user", vals[0]);
}
}
}
}
chain.doFilter(req, resp);
}
public void init(FilterConfig filterConfig) throws ServletException {}
}
</span></span>
4、正常退出的Servlet如下
<span style="font-size:18px;"><span style="font-size:18px;">/**
* 安全退出删除Cookie
*/
public class LoginOutServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
HttpSession s = req.getSession(); //获取Session
Cookie cookie = new Cookie("autologin","");//必须声明一个完全相同名称的Cookie
cookie.setPath("/");//路径也要完全相同
cookie.setDomain(".itcast.com");//域也要完全相同
cookie.setMaxAge(0);//设置时间为0,以直接删除Cookie
resp.addCookie(cookie);
s.removeAttribute("user");
System.err.println("安全退出。。。。。");
resp.sendRedirect(req.getContextPath()+"/index.jsp");
}
}
</span></span>
这种是基于最简单的方式实现的单点登录,效果图在下篇博客中的
下下篇
基于使用Shiro 和使用Spring security控制权限的方案
SSO 基于Cookie+fliter实现单点登录 实例解析(一)的更多相关文章
- SSO 基于Cookie+fliter实现单点登录(SSO):工作原理
SSO的概念: 单点登录SSO(Single Sign-On)是身份管理中的一部分. SSO的一种较为通俗的定义是:SSO是指訪问同一server不同应用中的受保护资源的同一用户,仅仅须要登录一次,即 ...
- SSO 基于CAS实现单点登录 实例解析(二)
本文目录: 概述 演示环境 部署CAS-Server相关的Tomcat 部署CAS-Client相关的Tomcat 测试验证SSO 第一: 本demo在一个机器上实现(三个虚拟主机),来看SSO单点登 ...
- SSO单点登录、跨域重定向、跨域设置Cookie、京东单点登录实例分析
最近在研究SSO单点登录技术,其中有一种就是通过js的跨域设置cookie来达到单点登录目的的,下面就已京东商城为例来解释下跨域设置cookie的过程 涉及的关键知识点: 1.jquery ajax跨 ...
- 基于CAS的SSO(单点登录)实例
第一步 部署CAS-Server(服务端) 1.从CAS官方网站(http://developer.jasig.org/cas/)下载最新版本的CAS-Server(当前最新版本cas-server- ...
- SSO单点登录学习总结(3)—— 基于CAS实现单点登录实例
第一: 本demo在一个机器上实现(三个虚拟主机),来看SSO单点登录实例(我们可以布到多个机器上使用都是同一个道理的),一个服务器主机,和两个客户端虚拟主机 [html] view plaincop ...
- SSO之CAS单点登录实例演示
本文目录: 一.概述 二.演示环境 三.JDK安装配置 四.安全证书配置 五.部署CAS-Server相关的Tomcat 六.部署CAS-Client相关的Tomcat 七. 测试验证SSO 一.概述 ...
- .NET基于Redis缓存实现单点登录SSO的解决方案[转]
一.基本概念 最近公司的多个业务系统要统一整合使用同一个登录,这就是我们耳熟能详的单点登录,现在就NET基于Redis缓存实现单点登录做一个简单的分享. 单点登录(Single Sign On),简称 ...
- .NET基于Redis缓存实现单点登录SSO的解决方案
一.基本概念 最近公司的多个业务系统要统一整合使用同一个登录,这就是我们耳熟能详的单点登录,现在就NET基于Redis缓存实现单点登录做一个简单的分享. 单点登录(Single Sign On),简称 ...
- 单点登录(二)使用Cookie+File实现单点登录登出(附源代码)
上一篇文章<单点登录(一)使用Cookie+File实现单点登录>中,我们实现了单点登录的功能. 本文作为上一篇文章的扩展部分,加入"单点登出"功能. 源代码下载:链接 ...
随机推荐
- mser 最大稳定极值区域(文字区域定位)算法 附完整C代码
mser 的全称:Maximally Stable Extremal Regions 第一次听说这个算法时,是来自当时部门的一个同事, 提及到他的项目用它来做文字区域的定位,对这个算法做了一些优化. ...
- luogu2252 取石子游戏
题目描述 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后把石子全部取完 ...
- codefroces 612E Square Root of Permutation
A permutation of length n is an array containing each integer from 1 to n exactly once. For example, ...
- [bzoj1488][HNOI2009]图的同构——Polya定理
题目大意 求两两互不同构的含n个点的简单图有多少种. 简单图是关联一对顶点的无向边不多于一条的不含自环的图. a图与b图被认为是同构的是指a图的顶点经过一定的重新标号以后,a图的顶点集和边集能完全与b ...
- 关于快速沃尔什变换(FWT)的一点学习和思考
最近在学FWT,抽点时间出来把这个算法总结一下. 快速沃尔什变换(Fast Walsh-Hadamard Transform),简称FWT.是快速完成集合卷积运算的一种算法. 主要功能是求:,其中为集 ...
- [bzoj4813][Cqoi2017]小Q的棋盘
来自FallDream的博客,未经允许,请勿转载,谢谢. 小Q正在设计一种棋类游戏.在小Q设计的游戏中,棋子可以放在棋盘上的格点中.某些格点之间有连线,棋子只能在有连线的格点之间移动.整个棋盘上共有V ...
- mooc-python语言语法week3-6
week3 1.类型的概念:程序编程不允许有歧义的数据类型存在,所以对数据进行了划分,python语言类型分为,数字类型.字符串类型.元组类型.列表类型.文件类型.字典类型. i:数字类型: pyth ...
- Unity3d 简单的小球沿贝塞尔曲线运动(适合场景漫游使用)
简单的小球沿贝塞尔曲线运动,适合场景漫游使用 贝塞尔曲线:(贝塞尔曲线的基本想法部分摘自http://blog.csdn.net/u010019717/article/details/4768 ...
- MySQL DATE_SUB()
DATE_SUB(date,INTERVAL expr type) 函数从日期减去指定的时间间隔. date 参数是合法的日期表达式.expr 参数是您希望添加的时间间隔. type 参数可以是下列值 ...
- 浅谈Trie树(字典树)
Trie树(字典树) 一.引入 字典是干啥的?查找字的. 字典树自然也是起查找作用的.查找的是啥?单词. 看以下几个题: 1.给出n个单词和m个询问,每次询问一个单词,回答这个单词是否在单 ...