单点登录(两种单点登录类型:SSO/CAS、相同一级域名的SSO)
单点登录:SSO(Single Sign On)
什么是单点登录:大白话就是多个网站共享一个用户名和密码的技术,对于普通用户来说,只需要登录其中任意一个网站,登录其他网站的时候就能够自动登陆,不需要再输入
用户名和密码了。
单点登录类型:
1.具有相同一级域名的多个网站,以新浪为例,新浪首页实际上是一个导航页面,它提供了很多很多的旗下网站地址,比如
(1)新浪新闻: http://news.sina.com.cn/
(2)新浪科技:http://tech.sina.com.cn/
(3)新浪博客:http://blog.sina.com.cn/
等等,它们都有相同的一级域名.sina.com.cn
使用Cookie将登陆信息写到本地,域名指定为.sina.com.cn,那么在访问新浪博客http://blog.sina.com.cn/的时候就会带有登陆信息,使用过滤器即可实现自动登陆。
2.没有相同域名的多个网站,比如淘宝和天猫
(1)淘宝:https://www.taobao.com/
(2)天猫:https://www.tmall.com/
虽然是两个不同的网站,而且没有相同的域名,但是在登陆淘宝之后,再访问天猫页面就会自动登陆,这种实现的技术就不仅仅是1.中具有相同一级域名的时候那么简单了。在java中,使用CAS技术解决这种情况比较常见。
一、使用过滤器和Cookie技术具有相同一级域名的多个网站实现单点登录
项目练习地址:https://github.com/kdyzm/day68_SSO
1.在Tomcat中配置多个站点的方法
(1)首先修改C:\Windows\System32\drivers\etc\hosts配置文件
添加的内容如下:
#有相同的一级域名的单点登录测试
127.0.0.1 www.bbs.kdyzm.com
127.0.0.1 www.news.kdyzm.com
(2)修改%Tomcat_Home%/conf/server.xml配置文件,在<Host></Host>标签后面添加下面的配置:
<!--有相同一级域名的单点登录测试-->
</Host>
<Host name="www.news.kdyzm.com" appBase="news">
</Host>
<Host name="www.bbs.kdyzm.com" appBase="bbs">
</Host>
(3)上面的appBase指的是%Tomcat_Home%路径下的文件夹,所以创建两个同名的文件夹(news、bbs)分别对应appBase中的内容,这两个文件夹和webapps文件夹同级。

这样就有了三个站点,分别是bbs、news、webapps
2.新建Jsp文件,使用jsp语法进行判断是否已经登陆,针对是否已经登录显示不同的内容:已经登陆的显示欢迎话语;没有登陆过的显示登录表单。
/index.jsp内容如下:

1 <body>
2 <c:choose>
3 <c:when test="${not empty sessionScope.user}">
4 欢迎你,${sessionScope.user.userName}
5 </c:when>
6 <c:otherwise>
7 <form method="post"
8 action="${pageContext.servletContext.contextPath}/loginServlet">
9 <table>
10 <tr>
11 <td>用户名</td>
12 <td><input type="text" name="userName"></td>
13 </tr>
14 <tr>
15 <td>密码</td>
16 <td><input type="text" name="password"></td>
17 </tr>
18 <tr>
19 <td><input type="submit" value="登陆"></td>
20 <td><input type="reset" value="重置"></td>
21 </tr>
22 </table>
23 </form>
24 </c:otherwise>
25 </c:choose>
26 </body>

3.书写Servlet类
/loginServlet 中的内容如下

1 package com.kdyzm.servlet;
2
3 import java.io.IOException;
4
5 import javax.servlet.ServletException;
6 import javax.servlet.http.Cookie;
7 import javax.servlet.http.HttpServlet;
8 import javax.servlet.http.HttpServletRequest;
9 import javax.servlet.http.HttpServletResponse;
10
11 import com.kdyzm.domain.User;
12
13 public class LoginServlet extends HttpServlet {
14 private static final long serialVersionUID = -7472135565931819576L;
15 @Override
16 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
17 throws ServletException, IOException {
18 this.doPost(req, resp);
19 }
20 @Override
21 protected void doPost(HttpServletRequest request, HttpServletResponse response)
22 throws ServletException, IOException {
23 request.setCharacterEncoding("utf-8");
24 response.setContentType("text/html;charset=utf-8");
25
26 String userName=request.getParameter("userName");
27 String password=request.getParameter("password");
28 if(userName.equals(password)){
29 User user=new User();
30 user.setUserName(userName);
31 user.setPassword(password);
32 //保存到Session
33 request.getSession().setAttribute("user", user);
34 //保存到Cookie
35 Cookie cookie=new Cookie("userName",user.getUserName());
36 cookie.setMaxAge(3600); //设置生命周期为一个小时
37 cookie.setDomain(".kdyzm.com"); //设置域名
38 cookie.setPath("/"); //设置路径为根路径
39 response.addCookie(cookie);
40 }
41 response.sendRedirect(request.getContextPath()+"/index.jsp");
42 }
43 }

到此为止已经实现了登陆的功能,并且将内容写入到了Cookie和Session中。
下一步实现自动登录功能,这时候就需要一个过滤器进行判断请求的信息中是否带有登录信息。
4.AutoLoginFilter过滤器的书写如下:

1 package com.kdyzm.filter;
2
3 import java.io.IOException;
4
5 import javax.servlet.Filter;
6 import javax.servlet.FilterChain;
7 import javax.servlet.FilterConfig;
8 import javax.servlet.ServletException;
9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 import javax.servlet.http.Cookie;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14 import javax.servlet.http.HttpSession;
15
16 import com.kdyzm.domain.User;
17
18 /**
19 * 不做登录验证,只做自动登录
20 * @author kdyzm
21 *
22 */
23 public class AutoLoginFilter implements Filter{
24
25 @Override
26 public void init(FilterConfig filterConfig) throws ServletException {
27 System.out.println("过滤器初始化!");
28 }
29
30 @Override
31 public void doFilter(ServletRequest req, ServletResponse resp,
32 FilterChain chain) throws IOException, ServletException {
33 HttpServletRequest request=(HttpServletRequest) req;
34 HttpServletResponse response=(HttpServletResponse) resp;
35 HttpSession session=request.getSession();
36 System.out.println("被拦截器过滤!");
37 //先判断是否已经登陆再做其他的判断比较高效
38 if(session.getAttribute("user")==null){
39 System.out.println("还没有登陆!");
40 Cookie [] cookies=request.getCookies();
41 if(cookies!=null){
42 for(Cookie cookie:cookies){
43 String name=cookie.getName();
44 if(name.equals("userName")){
45 System.out.println("还没有登录,但是存在登录信息!");
46 User user=new User();
47 String userName=cookie.getValue();
48 String password=userName;
49 user.setUserName(userName);
50 user.setPassword(password);
51 session.setAttribute("user", user);
52 }
53 System.out.println(cookie.getName()+":"+cookie.getValue());
54 }
55 }
56 }
57 chain.doFilter(request, response);
58 }
59
60 @Override
61 public void destroy() {
62 System.out.println("过滤器被销毁!");
63 }
64
65 }

到此,准备工作已经完成,下一步进行部署工作。
5.在新建立的两个站点下分别新建ROOT文件夹,并且将MyEclipse项目中Webroot下的所有文件拷贝过去
为什么要新建ROOT文件夹?tomcat服务器默认访问站点下的ROOT文件夹中的内容,使用ROOT文件夹访问的时候就不需要加上项目名称了。
6.分别修改两个站点下的index.jsp页面,目的是在测试的时候方便区分。
比如在bbs站点下的index.jsp页面中的修改内容:
<c:choose>
<c:when test="${not empty sessionScope.user}">
欢迎你,${sessionScope.user.userName}<br/>
这里是论坛界面!
</c:when>
在news站点下的修改内容
<c:choose>
<c:when test="${not empty sessionScope.user}">
欢迎你,${sessionScope.user.userName}<br/>
这里是新闻界面!
</c:when>
7.启动tomcat,进行测试,这里使用火狐浏览器进行测试
首先,访问http://localhost/day68_SSO/,输入英文用户名和密码,两者保证是相同的字符串。以xiaozhang为例:


查看Cookie信息,发现并没有期望中的.kdyzm.com的cookie信息,这是因为我们访问的是localhost:

接着访问www.bbs.kdyzm.com,出现的页面和之前一模一样,这次我们输入bbs为登录名和密码:


查看cookie信息,发现多了两种cookie信息,这时候,.kdyzm.com域中的cookie已经写成功了,而且其生命周期为一个小时、域为.kdyzm.com、名称为userName、内容为bbs这些内容都和程序设计的预期完全相同;同时bbs.kdyzm.com中也有了新的cookie信息,这个信息只是自动分配的JSESSIONID信息:

最后登录www.news.kdyzm.com,发现已经自动登陆了:

查看Cookie信息,发现多了news.kdyzm.com的站点信息的Cookie,但是并不是登陆信息的Cookie,只是JSESSIONID而已,它发送的Cookie信息是从kdyzm.com域名中获取到的。

二、没有相同的一级域名的实现多个站点的单点登录的方法:CAS
1.使用CAS框架实现多个站点如果没有相同的一级域名的单点登录测试
(1)CAS:Central Authentication Service,翻译过来就是中心认证服务,顾名思义,该框架的功能就是“认证”
使用CAS框架实现多个不同站点的单点登录的原理的关键就是使用一个认证服务器集中处理登陆的事宜。
流程图如下图所示:

(2)使用CAS完成不同站点的单点登录的demo下载地址:
https://github.com/kdyzm/day68_SSO_CAS_Demo
2.运行demo测试的步骤
1).首先需要修改hosts配置文件:添加上一下的两行信息:
127.0.0.1 www.bbs.com
127.0.0.1 www.news.com
2).修改hosts文件,添加一下的三行信息
<Host name="www.server.com" appBase="server">
</Host>
<Host name="www.news.com" appBase="news1">
</Host>
<Host name="www.bbs.com" appBase="bbs1">
</Host>
3).将news1文件夹和bbs1文件夹分别拷贝到%Tomcat_Home%文件夹中,分别作为两个独立的站点;将server文件夹拷贝到%Tomcat_Home%文件夹中,作为认证服务器站点。
4).启动tomcat服务器。首先访问www.server.com,如果没有任何问题的话,才能进行下一步。出现的界面如下:
5).随便输入一个用户名,但是必须确保密码和用户名相同,这是服务端默认的一个认证规则。如果成功了,则会显示如下界面:

清空浏览器cookies信息,然后进行下一步。
6).访问www.bbs.com,单击下图中的“to to protected area”超链接,在显示出来的页面中输如bbs作为用户名,使用bbs作为密码登陆


注意上图中的地址栏部分,已经不是www.bbs.com站点了,而是www.server.com。
登陆成功:

7).访问www.news.com,直接单击"go to protected area",发现已经自动登陆了。

3.演示到此结束,进行该测试的时候必须使用MyEclipse启动tomcat服务器;如果只是单独使用tomcat则很有可能会无法访问www.server.com。
4.具体使用方法比较复杂,但是这种技术在真正的开发中可能用不着。暂时存档。
单点登录(两种单点登录类型:SSO/CAS、相同一级域名的SSO)的更多相关文章
- 【Java EE 学习 68】【单点登录】【两种单点登录类型:SSO/CAS、相同一级域名的SSO】
单点登录:SSO(Single Sign On) 什么是单点登录:大白话就是多个网站共享一个用户名和密码的技术,对于普通用户来说,只需要登录其中任意一个网站,登录其他网站的时候就能够自动登陆,不需要再 ...
- 【单点登录】【两种单点登录类型:SSO/CAS、相同一级域名的SSO】
单点登录:SSO(Single Sign On) 什么是单点登录:大白话就是多个网站共享一个用户名和密码的技术,对于普通用户来说,只需要登录其中任意一个网站,登录其他网站的时候就能够自动登陆,不需要再 ...
- Splinter学习--初探3,两种方式登录QQ邮箱
目前,qq邮箱的登录方式有: 1.利用账号.密码登录 2.快捷登录,前提是你本地已有qq账号登录中 和前面一样,还是先到qq邮箱登录首页,审查页面元素,找到我们进行登录操作所相关的链接.按钮或是输入框 ...
- SSH简介及两种远程登录的方法
出处 https://blog.csdn.net/li528405176/article/details/82810342 目录 SSH的安全机制 SSH的安装 启动服务器的SSH服务 SSH两种级别 ...
- 谈谈两种标准库类型---string和vector
两种最重要的标准库---string和vector string和vector是两种最重要的标准库类型,string表示可变长的字符序列,vector存放的是某种给定类型对象的可变长序列. 一.标准库 ...
- MES实施会有哪些情况?为你介绍两种常见的类型
MES项目实施顾问是一份极具挑战的工作,需具备大量的专业知识,以及丰富的实施经验.今天,小编为大家介绍最常见的两种MES实施顾问类型,希望对大家有所启发. 保姆型实施顾问 是指以实施顾问为主导,只要是 ...
- SQL:两种获取时间类型日期部分的方法
参考网址:http://www.w3school.com.cn/sql/sql_dates.asp. ), PassedDate, ), , PassedDate), )
- Spring Security 一键接入验证码登录和小程序登录
最近实现了一个多端登录的Spring Security组件,用起来非常丝滑,开箱即用,可插拔,而且灵活性非常强.我觉得能满足大部分场景的需要.目前完成了手机号验证码和微信小程序两种自定义登录,加上默认 ...
- Android中BroadcastReceiver的两种注册方式(静态和动态)详解
今天我们一起来探讨下安卓中BroadcastReceiver组件以及详细分析下它的两种注册方式. BroadcastReceiver也就是"广播接收者"的意思,顾名思义,它就是用来 ...
随机推荐
- java并发编程(四)----(JUC)Lock锁初探
首先我们来回忆一下上一节讲过的synchronized关键字,该关键字用于给代码段或方法加锁,使得某一时刻它修饰的方法或代码段只能被一个线程访问.那么试想,当我们遇到这样的情况:当synchroniz ...
- 每个程序员都可以「懂」一点 Linux
提到 Linux,作为程序员来说一定都不陌生.但如果说到「懂」Linux,可能就没有那么多人有把握了.到底用 Linux 离懂 Linux 有多远?如果决定学习 Linux,应该怎么开始?要学到什么程 ...
- OSGi Bundle之Hello World
开发一个简单的Hello World的OSGi Bundle(OSGi绑定包) 在OSGi中,软件是以Bundle的形式发布的.一个Bundle由Java类和其它资源构成,它可为其它的Bundle提供 ...
- 洛谷 P4124 [CQOI2016]手机号码
题意简述 求l~r之间不含前导零,至少有三个相邻的相同数字,不同时含有4和8的11位正整数的个数 题解思路 数位DP,注意在l,r位数不够时补至11位 代码 #include <cstdio&g ...
- C++中轻量级多线程openmp
关于其概念及使用方法: https://baike.baidu.com/item/openmp/3735430?fr=aladdin
- java高并发系列 - 第32天:高并发中计数器的实现方式有哪些?
这是java高并发系列第32篇文章. java环境:jdk1.8. 本文主要内容 4种方式实现计数器功能,对比其性能 介绍LongAdder 介绍LongAccumulator 需求:一个jvm中实现 ...
- CodeForces 989D
题意略. 思路: 可以看成是所有的云彩照常运动,而月亮在跑.只要两个云彩相交后,在分离前月亮能赶到,就算是符合题意的. 可以知道,两个相隔越远的相向运动地云彩是越有可能符合题意的,因为它们相遇所用时间 ...
- Python Web Flask源码解读(三)——模板渲染过程
关于我 一个有思想的程序猿,终身学习实践者,目前在一个创业团队任team lead,技术栈涉及Android.Python.Java和Go,这个也是我们团队的主要技术栈. Github:https:/ ...
- 互联网从此没有 BAT
根据 Wind 数据截止2019年8月30日,中国十大互联网上市公司排名中,百度排名第 6 位市值 365 亿美元,阿里巴巴排名第一市值高达 4499 亿美元,腾讯排名第二市值 3951 亿美元. 1 ...
- Java深层复制方式
为什么需要深层复制 Object 的 clone() 方法是浅层复制(但是 native 很高效).另外,Java 提供了数组和集合的复制方法,分别是 Arrays.copy() 和 Collecti ...