首先,单点登录主要目的为多个系统共用同一个身份验证系统,即:用户登录A系统,也可以访问共用同一验证系统的B系统。
废话不多说,看实例:
采用三个web项目,实现单点登录。
项目一:SSOAuth
servlet类:AuthServlet
package org.servlet;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns="servlet/AuthServlet",loadOnStartup=1)
public class AuthServlet extends HttpServlet {
private static final long serialVersionUID = -2655740926477469126L;
public AuthServlet() {
super();
}
public void destroy() {
super.destroy();
}
/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("进入servlet了");
DomainName= request.getSession().getServletContext().getInitParameter("DomainName");
CookName = request.getSession().getServletContext().getInitParameter("CookieName");
System.out.println("---------"+DomainName+"----------------跳转了-------------"+CookName+"----------------");
String location =request.getContextPath()+"/login.jsp";
String ccode =(String) request.getSession().getAttribute("ccode");
String checkcode =request.getParameter("checkcode");
if(!checkcode.equals(ccode)){
response.sendRedirect(location);
}else{
String username =request.getParameter("username");
String userpassword =request.getParameter("userpassword");
String key =accounts.get(username);
if(key==null){
response.sendRedirect(location);
}else{
if(key.equals(userpassword)){
String gotoURL = request.getParameter("goto");
String sessionId =request.getSession().getId();
Cookie cookie =new Cookie(CookName,sessionId);
// cookie.setDomain(gotoURL);
cookie.setMaxAge(100);
// cookie.setValue(sessionId);
cookie.setPath("/");
response.addCookie(cookie);
if (gotoURL != null) {
response.sendRedirect(gotoURL);
System.out.println("登录成功!!!!"+cookie+"----------------"+sessionId);
}else{
response.sendRedirect(location);
}
}else{
response.sendRedirect(location);
}
}
}
}
static private ConcurrentMap<String, String> accounts;
// static private ConcurrentMap SSOIDs;
String CookName;
String DomainName;
@Override
public void init(ServletConfig config) throws ServletException {
// SSOIDs = new ConcurrentHashMap<String, String>();
accounts=new ConcurrentHashMap<String, String>();
accounts.put("joylife", "123456");
accounts.put("admin", "123456");
accounts.put("json", "123456");
}
}
一个login.jsp页面:
注:jquery 自己网上下载;
<%@ page language="java" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String url =request.getParameter("goto");
%>
<%
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>系统登录界面</title>
<script type="text/javascript" src="<%=path %>/js/jquery/jquery-1.7.2.min.js"></script>
<style type="text/css">
body {
font: normal 11px auto "Trebuchet MS", Verdana, Arial, Helvetica,sans-serif;
color: #4f6b72;/*background: #E6EAE9;*/
}
table {
margin-top: 10%;
margin-left: 30%;
border: 1px solid #CCCCFF;
}
table td {
border: 0px solid #CCCCFF;
font: bold 12px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
color: #000000;
}
table input {
width: 180px;
}
.leftTd {
text-align: right;
width: 35%;
}
.centerTd {
text-align: center;
font: bold 18px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
color: #000000;
}
.rightTd {
text-align: left;
width: 65%;
}
#btn_ok{
width: 50px;
}
#btn_clear{
width: 50px;
}
a{
margin:30px;
}
</style>
<script type="text/javascript">
$(function(){
$("#btn_reload").bind("click",function(){
btn_reload();
});
$("#btn_clear").bind("click",function(){
btn_clear();
});
$("#btn_ok").bind("click",function(){
btn_ok();
});
});
function btn_ok(){
var result =validateform();
if(!result){
return ;
}
$("#form").attr("action","servlet/AuthServlet");
$("#form").submit();
}
function btn_reload(){
$("#image").removeAttr("src");
$("#image").attr("src", "<%=path%>/image.jsp?random()*1000");
}
function btn_clear(){
$(":input").not("input[type=button]").each(function(){
$(this).val("");
});
}
function validateform(){
var result =true;
$(":input").not("input[type=button]").each(function(){
if($(this).val() ==""){
result=false;
}
});
return result ;
}
</script>
</head>
<body>
<form id="form" action="login.jsp" method="post">
<table>
<tbody>
<tr>
<td colspan="99" class="centerTd">用户信息登录 </td>
</tr>
<tr>
<td class="leftTd"><label>用户名</label></td>
<td class="rightTd"><input type="text" name="username" /></td>
</tr>
<tr>
<td class="leftTd"><label>密码</label></td>
<td class="rightTd"><input type="password" name="userpassword" /></td>
</tr>
<tr>
<td class="leftTd"><label>验证码</label></td>
<td class="rightTd"><input type="text" name="checkcode" />
<img src="<%=path%>/image.jsp"id="image" />
</td>
</tr>
<tr >
<td class="leftTd"><input type="button" id="btn_ok" value="登录" /></td>
<td class="rightTd"><input type="button" id="btn_clear" value="重置" />
<a href ="javascript:void(0);" id="btn_reload">看不清,换一张</a>
</td>
</tr>
</tbody>
</table>
<input name="goto" type="hidden" value=<%=url%>/>
</form>
</body>
</html>
一个image.jsp页面:
<%@ page pageEncoding = "gb2312" contentType="image/jpeg" import = "javax.imageio.*,java.util.*,java.awt.image.*,java.awt.*" %>
<%!
//在此处 获取并生成随机颜色
Color getRandColor(Random random, int ff, int cc) {
if (ff > 255)
ff = 255;
if (cc > 255)
cc = 255;
int r = ff + random.nextInt(cc - ff);
int g = ff + random.nextInt(cc - ff);
int b = ff + random.nextInt(cc - ff);
return new Color(r, g, b);
} %>
<%
//在此处 设置JSP页面无缓存
response.setHeader( "Pragma" , "No-cache" );
response.setHeader( "Cache-Control" , "no-cache" );
response.setDateHeader( "Expires" , 0);
// 设置图片的长宽
int width = 130;
int height = 30;
//设定被随机选取的中文字,此处中文字内容过多,不一一列出,只是举例说明下。
String base = "\u9752\u534a\u706b\u6cd5\u9898\u5efa\u8d76\u4f4d\u5531\u6d77\u4e03\u5973\u4efb\u4ef6\u611f\u51c6\u97f3\u7b54\u54e5\u9645\u65e7\u795e\u5ea7\u7ae0\u538b\u6162\u53d4\u80cc\u7ec6...省略文字。。。" ;
//设置 备选随机汉字的个数
int length = base.length();
// 创建缓存图像
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 获取图像
Graphics g = image.getGraphics();
// 创建随机函数的实例
Random random = new Random();
//此处 设定图像背景色
g.setColor(getRandColor(random, 188, 235));
g.fillRect(0, 0, width, height);
//设置随机 备选的字体类型
String[] fontTypes = { "\u5b8b\u4f53" , "\u65b0\u5b8b\u4f53" ,
"\u9ed1\u4f53" , "\u6977\u4f53" , "\u96b6\u4e66" };
int fontTypesLength = fontTypes.length;
// 在图片背景上增加噪点,增加图片分析难度
g.setColor(getRandColor(random, 180, 199));
g.setFont( new Font( "Times New Roman" , Font.PLAIN, 14));
for ( int i = 0; i < 4; i++) {
g.drawString( "@*@*@*@*@*@*@*" ,
0, 5 * (i + 2));
}
// 取随机产生的验证码 (4 个汉字 )
// 保存生成的汉字字符串
String sRand = "" ;
for ( int i = 0; i < 4; i++) {
int start = random.nextInt(length);
String rand = base.substring(start, start + 1);
sRand += rand;
// 设置图片上字体的颜色
g.setColor(getRandColor(random, 10, 150));
// 设置字体格式
g.setFont( new Font(fontTypes[random.nextInt(fontTypesLength)],
Font.BOLD, 18 + random.nextInt(6)));
// 将此汉字画到验证图片上面
g.drawString(rand, 24 * i + 10 + random.nextInt(8), 24);
}
// 将验证码存入S ession中
session.setAttribute( "rand" , sRand);
g.dispose();
//将 图象输出到JSP页面中
ImageIO.write(image, "JPEG" , response.getOutputStream());
//关闭流
out.clear();
out=pageContext.pushBody();
%>
最后web.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>AuthServlet</servlet-name>
<servlet-class>org.servlet.AuthServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AuthServlet</servlet-name>
<url-pattern>/servlet/AuthServlet</url-pattern>
</servlet-mapping>
<context-param>
<param-name>DomainName</param-name>
<param-value>localhost</param-value>
</context-param>
<context-param>
<param-name>CookieName</param-name>
<param-value>XiaoHaibingDesktopSSOID</param-value>
</context-param>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
web项目二:SSOWebDemo1
一个index.jsp页面:
<%@ page language="java" pageEncoding="UTF-8"%>
<%
String SSOLoginPage =request.getSession().getServletContext().getInitParameter("SSOLoginPage");
String CookieName =request.getSession().getServletContext().getInitParameter("CookieName");
CookieName =CookieName.toLowerCase().trim();
Cookie[] cookies= request.getCookies();
Cookie loginCookie =null;
String cookname ="";
if(cookies!=null){
for(Cookie cookie:cookies){
cookname =cookie.getName().trim().toLowerCase();
if(CookieName.equals(cookname)){
loginCookie =cookie;
break;
}
}
}
if(loginCookie==null){
String url =request.getRequestURL().toString();
response.sendRedirect(SSOLoginPage+"?goto="+url);
}
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ssowebdemo1</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<h1 align="center">WELCOME SsoWebDemo1 !</h1>
</body>
</html>
web.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>CookieName</param-name>
<param-value>
XiaohaibingDesktopSSOID
</param-value>
</context-param>
<context-param>
<param-name>SSOLoginPage</param-name>
<param-value>
http://localhost:8080/SSOAuth/login.jsp
</param-value>
</context-param>
</web-app>
web项目二:SSOWebDemo2
一个index.jsp页面:
<%@ page language="java" pageEncoding="UTF-8"%>
<%
String SSOLoginPage =request.getSession().getServletContext().getInitParameter("SSOLoginPage");
String CookieName =request.getSession().getServletContext().getInitParameter("CookieName");
CookieName =CookieName.toLowerCase().trim();
Cookie[] cookies= request.getCookies();
Cookie loginCookie =null;
String cookname ="";
if(cookies!=null){
for(Cookie cookie:cookies){
cookname =cookie.getName().trim().toLowerCase();
if(CookieName.equals(cookname)){
loginCookie =cookie;
break;
}
}
}
if(loginCookie==null){
String url =request.getRequestURL().toString();
response.sendRedirect(SSOLoginPage+"?goto="+url);
}
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ssowebdemo1</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<h1 align="center">WELCOME SsoWebDemo2 !</h1><br>
</body>
</html>
web.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>CookieName</param-name>
<param-value>
XiaohaibingDesktopSSOID
</param-value>
</context-param>
<context-param>
<param-name>SSOLoginPage</param-name>
<param-value>
http://localhost:8080/SSOAuth/login.jsp
</param-value>
</context-param>
</web-app>
如此:简单的单点登录便可实现。本人是将三个项目都是部署到本机上的,但是分别在2个tomcat上,
SSOAuth作为身份验证系统单独部署在了一个tomcat上,SSOWebDemo1和SSOWebDemo2是部署在同一个tomcat上。