单点登录(两种单点登录类型: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.具体使用方法比较复杂,但是这种技术在真正的开发中可能用不着。暂时存档。

时间: 2024-10-14 16:12:50

单点登录(两种单点登录类型:SSO/CAS、相同一级域名的SSO)的相关文章

两种单点登陆设计

单点登陆设计SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制.它是目前比较流行的企业业务整合的解决方案之一      现在很多企业级应用都基本会去实现单点登陆功能,这样对于用户体验上会有不错的加强.不需要重复登陆多次.好了废话少说,我今天主要介绍两种单点登陆设计. 第一种:最简单的单点登陆设计,如下图: 如图所示:当直接访问各类业务系统时,在页面

placeholder和json两种实现登录隐藏的方法

<head> <title> placeholder和json两种实现登录隐藏的方法 </title> <script type="text/javascript"> //判断浏览器是否支持 placeholder属性 function isPlaceholder() { var input = document.createElement('input'); return 'placeholder' in input; } if (!i

【Java EE 学习第68天】【单点登录】【两种单点登录类型:SSO/CAS、相同一级域名的SSO】

什么是单点登录:大白话就是多个网站共享一个用户名和密码的技术,对于普通用户来说,只需要登录其中任意一个网站,登录其他网站的时候就能够自动登陆,不需要再输入用户名和密码了. 单点登录类型: 1.具有相同一级域名的多个网站,以新浪为例,新浪首页实际上是一个导航页面,它提供了很多很多的旗下网站地址,比如 (1)新浪新闻: http://news.sina.com.cn/ (2)新浪科技:http://tech.sina.com.cn/ (3)新浪博客:http://blog.sina.com.cn/

Splinter学习--初探3,两种方式登录QQ邮箱

目前,qq邮箱的登录方式有: 1.利用账号.密码登录 2.快捷登录,前提是你本地已有qq账号登录中 和前面一样,还是先到qq邮箱登录首页,审查页面元素,找到我们进行登录操作所相关的链接.按钮或是输入框. QQ邮箱登录首页:https://mail.qq.com/ 打开登录页,可以看到两种登录方式选择,如下图:     审查页面元素,发现快速登录方式,对应ID为“qlogin_list“的一个div,而账号.密码登录方式对应ID为“web_login”的一个div,且这两个div元素都位于ID为“

谈谈两种标准库类型---string和vector

两种最重要的标准库---string和vector string和vector是两种最重要的标准库类型,string表示可变长的字符序列,vector存放的是某种给定类型对象的可变长序列. 一.标准库类型string   1.定义和初始化string对象:初始化string对象的方式有 string s1   默认初始化,s1是一个空串   string s2(s1)   s2是s1的副本 string s2=s1   等价于s2(s1),s2是s1的副本 string s3("value&qu

ssh密钥登录(两种方法)

方法一: 使用下例中ssky-keygen和ssh-copy-id,仅需通过3个步骤的简单设置而无需输入密码就能登录远程Linux主机. ssh-keygen 创建公钥和密钥. ssh-copy-id 把本地主机的公钥复制到远程主机的authorized_keys文件上.ssh-copy-id 也会给远程主机的用户主目录(home)和~/.ssh, 和~/.ssh/authorized_keys设置合适的权限 . 步骤1: 用 ssh-key-gen 在本地主机上创建公钥和密钥[email pr

Android中BroadcastReceiver的两种注册方式(静态和动态)详解

今天我们一起来探讨下安卓中BroadcastReceiver组件以及详细分析下它的两种注册方式. BroadcastReceiver也就是"广播接收者"的意思,顾名思义,它就是用来接收来自系统和应用中的广播.在Android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能:当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作:当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户

SSO单点登录三种情况的实现方式详解

单点登录(SSO——Single Sign On)对于我们来说已经不陌生了.对于大型系统来说使用单点登录可以减少用户很多的麻烦.就拿百度来说吧,百度下面有很多的子系统——百度经验.百度知道.百度文库等等,如果我们使用这些系统的时候,每一个系统都需要我们输入用户名和密码登录一次的话,我相信用户体验肯定会直线下降.当然,对于个人博客这类系统来说根本就用不上单点登录了. 假如,我们的系统很庞大,但是就是这一个系统,并没有什么子系统.这时我们也不需要单点登录.我们需要的是搭建集群环境,这里虽说只有一个系

CAS FOR WINDOW ACTIVE DIRECTORY SSO单点登录

一.CAS是什么? CAS(Central Authentication Service)是 Yale 大学发起的一个企业级的.开源的项目,旨在为 Web 应用系统提供一种可靠的单点登录解决方法(支持WEB及客户端). CAS 开始于 2001 年, 并在 2004 年 12 月正式成为 JA-SIG 的一个项目. 二.主要特性  1.开源的.多协议的 SSO 解决方案: Protocols : Custom Protocol . CAS . OAuth . OpenID . RESTful A