web sso 單點登入簡單例項原始碼
首先,單點登入主要目的為多個系統共用同一個身份驗證系統,即:使用者登入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上。