【Java EE 学习 68】【单点登录】【两种单点登录类型: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内容如下:
<body>
<c:choose>
<c:when test="${not empty sessionScope.user}">
欢迎你,${sessionScope.user.userName}
</c:when>
<c:otherwise>
<form method="post"
action="${pageContext.servletContext.contextPath}/loginServlet">
<table>
<tr>
<td>用户名</td>
<td><input type="text" name="userName"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="text" name="password"></td>
</tr>
<tr>
<td><input type="submit" value="登陆"></td>
<td><input type="reset" value="重置"></td>
</tr>
</table>
</form>
</c:otherwise>
</c:choose>
</body>
3.书写Servlet类
/loginServlet 中的内容如下
package com.kdyzm.servlet; import java.io.IOException; import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.kdyzm.domain.User; public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = -7472135565931819576L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8"); String userName=request.getParameter("userName");
String password=request.getParameter("password");
if(userName.equals(password)){
User user=new User();
user.setUserName(userName);
user.setPassword(password);
//保存到Session
request.getSession().setAttribute("user", user);
//保存到Cookie
Cookie cookie=new Cookie("userName",user.getUserName());
cookie.setMaxAge(3600); //设置生命周期为一个小时
cookie.setDomain(".kdyzm.com"); //设置域名
cookie.setPath("/"); //设置路径为根路径
response.addCookie(cookie);
}
response.sendRedirect(request.getContextPath()+"/index.jsp");
}
}
到此为止已经实现了登陆的功能,并且将内容写入到了Cookie和Session中。
下一步实现自动登录功能,这时候就需要一个过滤器进行判断请求的信息中是否带有登录信息。
4.AutoLoginFilter过滤器的书写如下:
package com.kdyzm.filter; import java.io.IOException; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import com.kdyzm.domain.User; /**
* 不做登录验证,只做自动登录
* @author kdyzm
*
*/
public class AutoLoginFilter implements Filter{ @Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("过滤器初始化!");
} @Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest) req;
HttpServletResponse response=(HttpServletResponse) resp;
HttpSession session=request.getSession();
System.out.println("被拦截器过滤!");
//先判断是否已经登陆再做其他的判断比较高效
if(session.getAttribute("user")==null){
System.out.println("还没有登陆!");
Cookie [] cookies=request.getCookies();
if(cookies!=null){
for(Cookie cookie:cookies){
String name=cookie.getName();
if(name.equals("userName")){
System.out.println("还没有登录,但是存在登录信息!");
User user=new User();
String userName=cookie.getValue();
String password=userName;
user.setUserName(userName);
user.setPassword(password);
session.setAttribute("user", user);
}
System.out.println(cookie.getName()+":"+cookie.getValue());
}
}
}
chain.doFilter(request, response);
} @Override
public void destroy() {
System.out.println("过滤器被销毁!");
} }
到此,准备工作已经完成,下一步进行部署工作。
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.具体使用方法比较复杂,但是这种技术在真正的开发中可能用不着。暂时存档。
【Java EE 学习 68】【单点登录】【两种单点登录类型:SSO/CAS、相同一级域名的SSO】的更多相关文章
- 【Java EE 学习 35 上】【strus2】【类型转换器】【struts2和Servlet API解耦】【国际化问题】【资源文件乱码问题已经解决】
一.类型转换器 1.在动作类action中,声明和表单中name属性的值同名的属性,提供get和set方法,struts2就可以通过反射机制,从页面中获取对应的内容 package com.kdyzm ...
- Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库
参考: https://my.oschina.net/gaussik/blog/513444 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 ...
- 【Java EE 学习 80 上】【WebService】
一.WebService概述 什么是WebService,顾名思义,就是基于Web的服务,它使用Http方式接收和响应外部系统的某种请求,从而实现远程调用.WebService实际上就是依据某些标准, ...
- Java EE 学习(8):IDEA + maven + spring 搭建 web(4)- 用户管理
转载:Gaussic(一个致力于AI研究却不得不兼顾项目的研究生) 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 web(1) ava E ...
- Java EE 学习(5):IDEA + maven + spring 搭建 web(1)
参考:http://www.cnblogs.com/lonelyxmas/p/5397422.html http://www.ctolib.com/docs-IntelliJ-IDEA-c--1590 ...
- Java EE学习——Quartz的Cron表达式
经历过低谷后,还是要好好学习,越失落会越来越落后. 今天写一下Cron表达式的用法,虽然是之前自己写的,也过了挺长一段时间,这次就拿出来作为回顾吧. Cron表达式是Quartz的精髓(个人觉得),比 ...
- Java EE 学习(6):IDEA + maven + spring 搭建 web(2)- 配置 Spring
参考:https://my.oschina.net/gaussik/blog/513353 注:此文承接上一文:Java EE 学习(5):IDEA + maven + spring 搭建 web(1 ...
- 【Java EE 学习 30】【闪回】【导入导出】【管理用户安全】【分布式数据库】【数据字典】【方案】
一.闪回 1.可能的误操作 (1)错误的删除了记录 (2)错误的删除了表 (3)查询历史记录 (4)撤销已经提交了的事务. 2.对应着以上四种类型的误操作,有四种闪回类型 (1)闪回表:将表回退到过去 ...
- Java中的ReentrantLock和synchronized两种锁定机制的对比
问题:多个访问线程将需要写入到文件中的数据先保存到一个队列里面,然后由专门的 写出线程负责从队列中取出数据并写入到文件中. http://blog.csdn.net/top_code/article/ ...
随机推荐
- thinkphp访问不存在的模块或者方法跳转到404页面
使用的thinkphp 版本是3.2.0, 在config.php中配置 404地址,即可: 'TMPL_EXCEPTION_FILE' => './Application/Home/View/ ...
- JestClient
JestService.java [html] view plain copy 在CODE上查看代码片派生到我的代码片 public class JestService { /** * 获取JestC ...
- github拉取和推送
登入github 创建一个开源项目 然后打开安装好的git 首先进入一个指定的文件夹 例如: 1)E:\>cd miaov/testGit 回车 进入E盘的testGit文件夹 2)E:\mia ...
- 练习用基础SQL语句
http://www.cnblogs.com/zxlovenet/p/3728842.html 本文语句大部分SQL语句来自<数据库系统概论>(第四版)王珊&萨师煊 ,是我们上课用 ...
- Ajax方式上传文件
用到两个对象 第一个对象:FormData 第二个对象:XMLHttpRequest 目前新版的Firefox 与 Chrome 等支持HTML5的浏览器完美的支持这两个对象,但IE9尚未支持 For ...
- css驼峰写法
当style样式与 animate() 方法一起使用时,该属性名称必须是驼峰写法: 您必须使用 paddingLeft 代替 padding-left,marginRight 代替 margin-ri ...
- php打印中文乱码
php文档的文本格式都设置成 utf-8 格式 在代码中添加 header("content-type:text/html; charset=utf-8");
- java关键包简易说明
java.lang 语言核心类,系统自动导入. java.util java工具类.集合框架.时间,日历等. java.net 网络编程接口和类. java.io 流的接口和类 java.te ...
- js replaceAll
js 全部替换: /** * 替换(所有) * @param str 要处理的字符串 * @param beRepStr 被替换的字符串 * @param toRepStr 最终生成的字符串 * @r ...
- Java transient 关键字
1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问. 2)transient关键字只能修饰变量,而不能修饰方法和类.注意,本地变量是不能被trans ...