Java--实现单点登录
1 什么是单点登陆

- 用户每天平均 16 分钟花在身份验证任务上 - 资料来源: IDS
- 频繁的 IT 用户平均有 21 个密码 - 资料来源: NTA Monitor Password Survey
- 49% 的人写下了其密码,而 67% 的人很少改变它们
- 每 79 秒出现一起身份被窃事件 - 资料来源:National Small Business Travel Assoc
- 全球欺骗损失每年约 12B - 资料来源:Comm Fraud Control Assoc
- 到 2007 年,身份管理市场将成倍增长至 $4.5B - 资料来源:IDS
- 提高 IT 效率:对于每 1000 个受管用户,每用户可节省$70K
- 帮助台呼叫减少至少1/3,对于 10K 员工的公司,每年可以节省每用户 $75,或者合计 $648K
- 生产力提高:每个新员工可节省 $1K,每个老员工可节省 $350 �资料来源:Giga
- ROI 回报:7.5 到 13 个月 �资料来源:Gartner

- 所有应用系统共享一个身份认证系统。
统一的认证系统是SSO的前提之一。认证系统的主要功能是将用户的登录信息和用户信息库相比较,对用户进行登录认证;认证成功后,认证系统应该生成统一的认证标志(ticket),返还给用户。另外,认证系统还应该对ticket进行效验,判断其有效性。 - 所有应用系统能够识别和提取ticket信息
要实现SSO的功能,让用户只登录一次,就必须让应用系统能够识别已经登录过的用户。应用系统应该能对ticket进行识别和提取,通过与认证系统的通讯,能自动判断当前用户是否登录过,从而完成单点登录的功能。
- 单一的用户信息数据库并不是必须的,有许多系统不能将所有的用户信息都集中存储,应该允许用户信息放置在不同的存储中,如下图所示。事实上,只要统一认证系统,统一ticket的产生和效验,无论用户信息存储在什么地方,都能实现单点登录。

- 统一的认证系统并不是说只有单个的认证服务器,如下图所示,整个系统可以存在两个以上的认证服务器,这些服务器甚至可以是不同的产品。认证服务器之间要通过标准的通讯协议,互相交换认证信息,就能完成更高级别的单点登录。如下图,当用户在访问应用系统1时,由第一个认证服务器进行认证后,得到由此服务器产生的ticket。当他访问应用系统4的时候,认证服务器2能够识别此ticket是由第一个服务器产生的,通过认证服务器之间标准的通讯协议(例如SAML)来交换认证信息,仍然能够完成SSO的功能。



- 统一的身份认证服务。
- 修改Web应用,使得每个应用都通过这个统一的认证服务来进行身份效验。

package com.ll.singlelogin; import javax.servlet.http.*;
import java.util.*; public class SingleLogin implements HttpSessionListener { // 保存sessionID和username的映射
private static HashMap hUserName = new HashMap(); /** 以下是实现HttpSessionListener中的方法* */
public void sessionCreated(HttpSessionEvent se) {
} public void sessionDestroyed(HttpSessionEvent se) {
hUserName.remove(se.getSession().getId());
} /**
* isAlreadyEnter-用于判断用户是否已经登录以及相应的处理方法
*
* @param sUserName
* String-登录的用户名称
* @return boolean-该用户是否已经登录过的标志
*/
public static boolean isAlreadyEnter(HttpSession session, String sUserName) {
boolean flag = false;
// 如果该用户已经登录过,则使上次登录的用户掉线(依据使用户名是否在hUserName中)
if (hUserName.containsValue(sUserName)) {
flag = true;
// 遍历原来的hUserName,删除原用户名对应的sessionID(即删除原来的sessionID和username)
Iterator iter = hUserName.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Object key = entry.getKey();
Object val = entry.getValue();
if (((String) val).equals(sUserName)) {
hUserName.remove(key);
}
}
// 添加现在的sessionID和username
hUserName.put(session.getId(), sUserName);
System.out.println("hUserName = " + hUserName);
} else {// 如果该用户没登录过,直接添加现在的sessionID和username
flag = false;
hUserName.put(session.getId(), sUserName);
System.out.println("hUserName = " + hUserName);
}
return flag;
} /**
* isOnline-用于判断用户是否在线
*
* @param session
* HttpSession-登录的用户名称
* @return boolean-该用户是否在线的标志
*/
public static boolean isOnline(HttpSession session) {
boolean flag = true;
if (hUserName.containsKey(session.getId())) {
flag = true;
} else {
flag = false;
}
return flag;
}
}

web.xml部署于/App/WEB-INF下

<?xml version= "1.0 " encoding= "ISO-8859-1 "?> <!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN "
"http://java.sun.com/j2ee/dtds/web-app_2.3.dtd "> <web-app> <listener>
<listener-class>
com.inspirer.dbmp.SessionListener
</listener-class>
</listener> </web-app>

应用部分
1.在你的登录验证时,调用SessionListener.isAlreadyEnter(session, "admin ")
既可以判断该用户名的用户是否登录过,又可以使上次登录的用户掉线
2.其他页面调用SessionListener.isOnline(session),可以判断该用户是否在线.
转自:http://blog.csdn.net/java_freshman01/article/details/7202776
采用SSH架构加以说明:
1. 建立一个登录管理类LoginManager
2. 在LoginManager中定义一个集合,管理登录的用户。
3. 在Spring中将LoginManager配置成单例
4. 如果使用自定义的用户管理类,则为了说明方便,将此类命名为UserContext(表示用户授权的上下文)
5. 如果未使用自定义的用户管理类,则直接使用Session。
6. 在登录授权对象中,检查用户是否是合法用户,如果是合法用户,则在LoginManager的集合中查找用户是否已经在线,如果不在线,则将用户加入集合。
7. 处理策略一:如果用户已经在线,则取新登录用户的Session,将它失效,则能阻止新登录用户登录。
8. 处理策略二:如果用户已经在线,则取出在线用户的Session,将它失效,再把新登录用户加入LoginManager的集合。则先登录用户不能执行有权限的操作,只能重新登录。
1. applicationContext.xml
<bean id="loginManager" class="LoginManager" scope="singleton" />
<bean id="action" class="LoginAction" scopt="prototype" >
<property name="laginManager" ref="loginManager" />
</bean>
2. LoginManager.java

Collection<Session> sessions;
public Session login(Session session) {
for (Session s : sessions) {
if (s 与 session 是同一用户)
策略一: return session
策略二:{
sessions.add(session); // 这两行在循环中操作集合类会抛出异常
sessions.remove(s); // 此处仅为简单示范代码,实际代码中应该在循环外处理
return s;
}
}
sessions.add(session);
return null;
}

3. LoginAction.java

LoginManager loginManager;
public String execute() throws Exception {
取session
检查用户名,密码
if (是合法用户) {
session = loginManager.login(session);
if (null!=session) session.invalidate();
}
}

4. 如果自定义了UserContext,则可将集合改成Collection<UserContext> users;
5. UserContext.java

Session session;
Session getSession() {
return this.session;
} boolean login(String userName, String password) {
访问数据库,检查用户名密码
return 是否合法;
} boolean sameUser(UserContext uc) {
return uc.userName.equals(this.userName);
}

6. 修改LoginManager.java

Collection<UserContext> users;
public UserContext login(UserContext user) {
for (UserContext uc : users) {
if (uc.sameUser(user))
策略一: return user
策略二:{
users.add(user); // 这两行在循环中操作集合类会抛出异常
users.remove(uc); // 此处仅为简单示范代码,实际代码中应该在循环外处理
return uc;
}
}
users.add(user);
return null;
}

7. 修改LoginAction.java

public String execute() throws Exception {
取session // 也可以在UserContext内部取session。
UserContext user = new UserContext();
user.setSession(session);
if (user.login(userName, password)) {
UserContext uc = loginManager.login(user);
if (null!=uc) uc.getSession().invalidate();
}
}

HalfWater的博客
Java--实现单点登录的更多相关文章
- JAVA CAS单点登录(SSO) 教程
一.教程前言 教程目的:从头到尾细细道来单点登录服务器及客户端应用的每个步骤 单点登录(SSO):请看百科解释猛击这里打开 本教程使用的SSO服务器是Yelu大学研发的CAS(Central Auth ...
- JAVA CAS单点登录(SSO)
一.教程前言 教程目的:从头到尾细细道来单点登录服务器及客户端应用的每个步骤 单点登录(SSO):请看百科解释猛击这里打开 本教程使用的SSO服务器是Yelu大学研发的CAS(Central Auth ...
- 【Java】单点登录(SSO)
单点登录介绍 SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.它包括可以将这次主要的登录映射到其他应用中用于同一 ...
- java之单点登录(SSO)
单点登录(SSO):SSO是指在多个应用系统中个,用户只需要登陆一次就可以访问所有相互信任的应用系统.它包括可以将这次主要的登录映射到其他应用中用于同一用户的登陆的机制. SSO的实现过程: 通过上述 ...
- java UCnter 单点登录 对接。
前提 PHP项目要部署成功.论坛能正常访问. 先配置 应用 1.是论坛应用 4.是java服务器,也就是你java登录的项目. 必须通信成功. .主应用IP就是你java项目的入口. 例如:http: ...
- 【Java EE 学习 68】【单点登录】【两种单点登录类型:SSO/CAS、相同一级域名的SSO】
单点登录:SSO(Single Sign On) 什么是单点登录:大白话就是多个网站共享一个用户名和密码的技术,对于普通用户来说,只需要登录其中任意一个网站,登录其他网站的时候就能够自动登陆,不需要再 ...
- jasig CAS 实现单点登录 - java、php客户端登录实现
jasig CAS项目本身就是一个完整的CAS单点登录服务 1.服务端需要把 认证处理类.用户属性返回值处理类 调整成我们自己处理类即可实现单点登录 2.java客户端需要引入cas-client- ...
- 点单登录原理和java实现简单的单点登录
引用自:http://blog.csdn.net/zuoluoboy/article/details/12851725 摘要: 单点登录(SSO)的技术被越来越广泛地应用到各个领域的软件系统当中.本文 ...
- java和Discuz论坛实现单点登录,通过Ucenter(用户管理中心)
标题有点问题,没有进行修改. 一 Discuz论坛搭建步骤 1:服务器环境配置 服务器要支持php语言+支持mysql 5.0以上的数据库 + Apache服务器(支持网站的一个服务器,通过域名的能访 ...
- java单点登录系统CAS的简单使用
转:http://blog.csdn.net/yunye114105/article/details/7997041 背景 有几个相对独立的java的web应用系统, 各自有自己的登陆验证功能,用户在 ...
随机推荐
- PostgreSQL和MySQL
PostgreSQL分布式
- liunx 安装jdk
1 下载jdk http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 2 切换root ...
- .NET Core微服务之路:基于gRPC服务发现与服务治理的方案
重温最少化集群搭建,我相信很多朋友都已经搭建出来,基于Watch机制也实现了出来,相信也有很多朋友有了自己的实现思路,但是,很多朋友有个疑问,我API和服务分离好了,怎么通过服务中心进行发现呢,这个过 ...
- [算法专题] 二分搜索&排序数组
基础知识 二分非递归写法: int binary_search(const int a[], const int size, const int val) { int lower = 0; int u ...
- SQL Server表分区(水平分区及垂直分区)
什么是表分区? 表分区分为水平表分区和垂直表分区,水平表分区就是将一个具有大量数据的表,进行拆分为具有相同表结构的若干个表:而垂直表分区就是把一个拥有多个字段的表,根据需要进行拆分列,然后根据某一个字 ...
- Android开发 - 掌握ConstraintLayout(二)介绍
介绍 发布时间 ConstraintLayout是在2016的Google I/O大会上发布的,经过这么长时间的更新,现在已经非常稳定. 支持Android 2.3(API 9)+ 目前的Androi ...
- 设置select,option文本居中
设置select,option文本居中 可以通过 padding 属性设置内边距,使它看上去居中: select{ # 从左到右依次表示上内边距,右内边距,下内边距,左内边距: padding :0 ...
- webpack打包工具
目的:平时小项目中例如一些网站需要进行打包压缩,用这个工具可以进行打包压缩,就可以上传到服务器. 使用方法: 1,引进需要打包的项目,把入口html替换掉项目中的index.html,把引进的js,c ...
- [Node.js与数据库]node-mysql 模块介绍
[Node.js与数据库]node-mysql 模块介绍 转载至:https://itbilu.com/nodejs/npm/NyPG8LhlW.html#multiple-statement-q ...
- 课程四(Convolutional Neural Networks),第三 周(Object detection) —— 1.Practice questions:Detection algorithms
[解释] tree的两个bounding boxes 都要保留,因为交并比小于0.5:car 0.73保留:pedestrain 0.98保留:motorcycle 0.58保留.一共5个. [解释] ...