单点登陆(Single Sign On),简称为SSO,SSO不只在企业级开发很经常使用,在互联网中更是大行其道。随便举几个例子,好比咱们登陆新浪微博后,再访问新浪首页后,咱们发现, 已经自动登陆了;再好比咱们登陆CSDN后,能够写博客、逛论坛、下载资源等等。前者是彻底跨域的单点登陆,下文会讲,后者是共同父域下 (www.csdn.NET、blog.csdn.net、bbs.csdn.Net、passport.csdn.net)的单点登陆,也就是本文的主要内容。html
-------------------------1.同域名下的应用的单点登陆-----------------------------------java
思路:统一登陆接口要根据其访问的地址设置登录成功后跳转的页面。好比你在动物园在景点1被拦截了要求你买票你确定是买一张通票而后继续访问景点1。具体的作法就是在登陆表单中隐藏一个跳转的页面,而后在登陆校验成功以后跳转到隐藏表单提交上来的跳转页面。web
1.准备环境apache
将动态项目映射的项目名字去掉跨域
在tomcat的conf文件夹下的server.xml配置:tomcat
<Context docBase="E:\tomcat\apache-tomcat-7.0.72\wtpwebapps\SSO_SameDomain" path="" reloadable="true" source="org.eclipse.jst.jee.server:SSO_SameDomain"/>
或者在eclipse中配置:服务器
倒入struts2的jar包,配置web.xml中struts的过滤器。cookie
2.统一登录接口网络
登录页面:(login.jsp)app
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content="qlq"> <meta name="Keywords" content=""> <meta name="Description" content="单点登陆的界面"> <title>登陆界面</title> </head> <body> <center> <h3>请登陆</h3> <form action="" method="post"> 用户名:<input type="text" name="username"/> 密码:<input type="password" name="password"/> <input type="hidden" name="gotoUrl" value="${goroUrl}"/> <input type="submit" value="登陆"/> </form> </center> </body> </html>
处理登录的Action
访问主页的时候设置一个goroUrl,用于标记成功以后要重定向的页面(是demo1的主页仍是demo2的主页)。登录的时候带着gotoUrl访问登录Action,成功以后跳转到goroUrl对应的页面
package SSOAction; import java.awt.image.VolatileImage; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ; public class LoginAction extends ActionSupport { private String username; private String password; private String gotoUrl; public String getGotoUrl() { return gotoUrl; } public void setGotoUrl(String gotoUrl) { this.gotoUrl = gotoUrl; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String execute() throws Exception { boolean OK = this.check(); if (OK) { Cookie cookie = new Cookie("sscookie", "sso"); // 设置cookie的做用范围是顶层(localhost),在localhost域下的应用可见 cookie.setPath("/"); HttpServletResponse response = ServletActionContext.getResponse(); // 增长cookie,未设置生命周期默认为一次会话 response.addCookie(cookie); return SUCCESS; } return null; } public boolean check() { if ("user".equals(username) && "123".equals(password)) return true; return false; } }
struts.xml配置登录的Action
<package name="sso" namespace="/sso" extends="struts-default"> <action name="login" class="SSOAction.LoginAction"> <result name="success" type="redirect">${goroUrl}</result> </action> </package>
2.登录校验接口
检查cookie中是否携带登录信息
package utils; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CheckCookie { public static boolean checkCookie(HttpServletRequest request) { Cookie cookies[] = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { // 验证是否存在cookie if ("ssocookie".equals(cookie.getName()) && "sso".equals(cookie.getValue())) return true; } } return false; } }
3. 编写demo1主页和demo2主页(struts2中Action的属性名字有get,Set方法属性会被放到值栈中)
demo1的主页:
Demo1Index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="/struts-tags" prefix="s" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>欢迎访问Demo1的主页</title> </head> <body>欢迎访问Demo1的主页,这是Demo1的主页。~~~~~~~~~~~~~~~~~~ <s:debug></s:debug> </body> </html>
处理登录的Axtion,登录以前先验证cookie,成功跳到demo1主页,失败将主页写到gotoUrl
package Demo1; import javax.print.attribute.standard.RequestingUserName; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; import utils.CheckCookie; /** * Demo1主页,访问主页要先验证cookie * * @author: qlq * @date : 2017年8月29日下午12:02:31 */ public class Demo1Action extends ActionSupport { private String gotoUrl; public String getGotoUrl() { return gotoUrl; } public void setGotoUrl(String gotoUrl) { this.gotoUrl = gotoUrl; } @Override public String execute() throws Exception { HttpServletRequest request = ServletActionContext.getRequest(); if (CheckCookie.checkCookie(request)) return SUCCESS; // 登录失败后将gotoUrl写到JSP页面 gotoUrl = "/demo1/main.action"; return LOGIN; } }
demo2的主页:
Demo2Index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>欢迎访问Demo2的主页</title> </head> <body>欢迎访问Demo2的主页,这是Demo2的主页。 </body> </html>
处理登录的Axtion,登录以前先验证cookie,成功跳到demo2主页,失败将主页写到gotoUrl
package Demo2; import javax.print.attribute.standard.RequestingUserName; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; import utils.CheckCookie; /** * Demo2主页,访问主页要先验证cookie * * @author: qlq * @date : 2017年8月29日下午12:02:31 */ public class Demo2Action extends ActionSupport { private String gotoUrl; public String getGotoUrl() { return gotoUrl; } public void setGotoUrl(String gotoUrl) { this.gotoUrl = gotoUrl; } @Override public String execute() throws Exception { HttpServletRequest request = ServletActionContext.getRequest(); if (CheckCookie.checkCookie(request)) return SUCCESS; // 登录失败后将gotoUrl写到JSP页面 gotoUrl = "/demo2/main.action"; return LOGIN; } }
struts.xml中配置主页
<package name="demo1" namespace="/demo1" extends="struts-default"> <action name="main" class="Demo1.Demo1Action"> <result name="success">/Demo1Index.jsp</result> <result name="login">/login.jsp</result> </action> </package> <package name="demo2" namespace="/demo2" extends="struts-default"> <action name="main" class="Demo2.Demo2Action"> <result name="success">/Demo2Index.jsp</result> <result name="login">/login.jsp</result> </action> </package>
4.启动tomcat测试
1. 访问: http://localhost:8080/demo1/main.action
查看项目源码:
2. 访问: http://localhost:8080/demo2/main.action
查看页面源码:
3.在demo2中登录
4.刷新demo1.action(已经登录成功)
5.查看cookie
6.调整3与4d顺序,先登陆1,再刷新2,结果同样
0. 首先了解下域名的概念与结构:
域名就是对应于IP地址的用于在互联网上标识机器的有意义的字符串。
联网上的域名就至关于咱们现实生活中的门牌号码同样,能够在纷繁芜杂的网络世界 里准确无误地把咱们指引到咱们要访问的站点。在互联网发展之初并无域名,有的只是IP地址。IP地址就是一组相似这样的数字, 如:162.105.203.245。因为当时互联网主要应用在科研领域,使用者很是少,因此记忆这样的数字并非很是困难。可是随着时间的推移,连入互 联网的电脑愈来愈多,须要记忆的IP地址也愈来愈多,记忆这些数字串变得愈来愈困难,因而域名应运而生。域名就是对应于IP地址的用于在互联网上标识机器 的有意义的字符串。例如CNNIC的域名WWW.CNNIC.NET.CN,比起IP地址而言就更形象也更容易记忆。
为了便于你们进一步了解域名的实质,有必要在这里谈谈域名的体系结构。从WWW.CNNIC.NET.CN 这个域名来看,它是由几个不一样的部分组成的,这几个部分彼此之间具备层次关系。其中最后的.CN是域名的第一层,.NET是第二层,.CNNIC是真正的 域名,处在第三层,固然还能够有第四层,如:INNER.CNNIC.NET.CN,至此咱们能够看出域名从后到前的层次结构相似于一个倒立的树型结构。 其中第一层的.CN叫作地理顶级域名。
目前互联网上的域名体系中共有三类顶级域名:一是地理顶级域名,共有243个国家和地区的代码。例如.CN 表明中国,.JP表明日本,.UK表明英国等等,另外一类是类别顶级域名,共有7个:.COM(公司),.NET(网络机构),.ORG(组织机 构),.EDU(美国教育),.GOV(美国政府部门),.ARPA(美国军方),.INT(国际组织)。因为互联网最初是在美国发展起来的,因此最初的 域名体系也主要供美国使用,因此.GOV,.EDU,.ARPA虽然都是顶级域名,但倒是美国使用的。只有.COM,.NET,.ORG成了供全球使用的 顶级域名。相对于地理顶级域名来讲,这些顶级域名都是根据不一样的类别来区分的,因此称之为类别顶级域名。随着互联网的不断发展,新的顶级域名也根据实际需 要不断被扩充到现有的域名体系中来。新增长的顶级域名是.BIZ(商业),.COOP(合做公司),.INFO(信息行业),.AERO(航空 业),.PRO(专业人士),.MUSEUM(博物馆行业),.NAME(我的)。
在这些顶级域名下,还能够再根据须要定义次一级的域名,如在我国的顶级域名.CN下又设立了.COM,.NET,.ORG,.GOV,.EDU以及我国各个行政区划的字母表明如.BJ表明北京,.SH表明上海等等。
1.准备工做:
修改C:\Windows\System32\drivers\etc\hosts文件,增长域名的映射
2.准备统一登陆接口
login.JSP
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content="qlq"> <meta name="Keywords" content=""> <meta name="Description" content="单点登陆的界面"> <title>登陆界面</title> </head> <body> <center> <h3>请登陆</h3> <form action="http://check.x.com:8080/sso/login.action" method="post"> 用户名:<input type="text" name="username" value="user"/> 密码:<input type="password" name="password" value="123"/> <input type="hidden" name="gotoUrl" value="${gotoUrl}"/> <input type="submit" value="登陆"/> </form> </center> </body> </html>
处理登陆的Action(设置cookie为父域下的全部应用可见)
package check.x.com; import java.awt.image.VolatileImage; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ; public class LoginAction extends ActionSupport { private String username; private String password; private String gotoUrl; public String getGotoUrl() { return gotoUrl; } public void setGotoUrl(String gotoUrl) { this.gotoUrl = gotoUrl; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String execute() throws Exception { boolean OK = this.check(); if (OK) { Cookie cookie = new Cookie("ssocookie", "sso"); // 设置cookie的做用范围是父域(.x.com) cookie.setDomain(".x.com"); // 斜杠表明设置到父域的顶层,也就是父域下的全部应用均可访问 cookie.setPath("/"); HttpServletResponse response = ServletActionContext.getResponse(); // 增长cookie,未设置生命周期默认为一次会话 response.addCookie(cookie); return SUCCESS; } return null; } public boolean check() { if ("user".equals(username) && "123".equals(password)) return true; return false; } }
struts.xml配置Action
<package name="sso" namespace="/sso" extends="struts-default"> <action name="login" class="check.x.com.LoginAction"> <result name="success" type="redirect">${gotoUrl}</result> </action> </package>
3.准备统一登陆校验接口
在check.x.com中校验,首先根据demo1.x.com传来的cookieName和cookieValue进行校验,若是校验经过,经过response返回1,不经过返回0。
校验工具类
package check.x.com.utils; public class CheckCookie { public static boolean checkCookie(String cookieName, String cookieValue) { // 验证是否存在cookie if ("ssocookie".equals(cookieName) && "sso".equals(cookieValue)) return true; return false; } }
校验类:checkCookie()方法
package check.x.com; import java.awt.image.VolatileImage; import java.io.IOException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ; import check.x.com.utils.CheckCookie; public class LoginAction extends ActionSupport { private String username; private String password; private String gotoUrl; private String cookieName; private String cookieValue; public String getCookieName() { return cookieName; } public void setCookieName(String cookieName) { this.cookieName = cookieName; } public String getCookieValue() { return cookieValue; } public void setCookieValue(String cookieValue) { this.cookieValue = cookieValue; } public String getGotoUrl() { return gotoUrl; } public void setGotoUrl(String gotoUrl) { this.gotoUrl = gotoUrl; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String execute() throws Exception { boolean OK = this.check(); if (OK) { Cookie cookie = new Cookie("ssocookie", "sso"); // 设置cookie的做用范围是父域(.x.com) cookie.setDomain(".x.com"); // 斜杠表明设置到父域的顶层,也就是父域下的全部应用均可访问 cookie.setPath("/"); HttpServletResponse response = ServletActionContext.getResponse(); // 增长cookie,未设置生命周期默认为一次会话 response.addCookie(cookie); return SUCCESS; } return null; } public void checkCookie() throws IOException{ String result="0"; if(CheckCookie.checkCookie(cookieName, cookieValue)){ result="1"; } HttpServletResponse response = ServletActionContext.getResponse(); response.getWriter().print(result); response.getWriter().close(); } public boolean check() { if ("user".equals(username) && "123".equals(password)) return true; return false; } }
struts.xml中配置验证cookie的action(没有跳转页面,只是返回数据)
4.编写demo1的主页及处理的Action
Demo1Index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>欢迎访问Demo1的主页</title>
</head>
<body>欢迎访问Demo1的主页,这是Demo1的主页。~~~~~~~~~~~~~~~~~~
</body>
</html>
Demo1Action.java
package demo1.x.com; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import javax.print.attribute.standard.RequestingUserName; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; /** * Demo1主页,访问主页要先验证cookie * * @author: qlq * @date : 2017年8月29日下午12:02:31 */ public class Demo1Action extends ActionSupport { private String gotoUrl; public String getGotoUrl() { return gotoUrl; } public void setGotoUrl(String gotoUrl) { this.gotoUrl = gotoUrl; } @Override public String execute() throws Exception { HttpServletRequest request = ServletActionContext.getRequest(); Cookie cookies[] = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { if ("ssocookie".equals(cookie.getName())) { String result = this.doGet("http://check.x.com:8080/sso/checkCookie.action", cookie.getName(), cookie.getValue()); if ("1".equals(result)) { return SUCCESS; } } } } // 登录失败后将gotoUrl写到JSP页面 gotoUrl = "http://demo1.x.com:8080/demo1/main.action"; return LOGIN; } public String doGet(String url, String cookieName, String cookieValue) { // 用于接收返回的数据 StringBuffer sb = new StringBuffer(); // 建立一个链接的请求 HttpURLConnection httpURLConnection = null; try { // 包装请求的地址 URL urls = new URL(url + "?cookieName=" + cookieName + "&cookieValue=" + cookieValue); // 打开链接 httpURLConnection = (HttpURLConnection) urls.openConnection(); httpURLConnection.setRequestMethod("GET"); // 经过BufferReader读取数据 InputStream iStream = httpURLConnection.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(iStream); BufferedReader bReader = new BufferedReader(inputStreamReader); String temp = null; while ((temp = bReader.readLine()) != null) { sb.append(temp); } // 关闭流(先开后关,后开先关) bReader.close(); inputStreamReader.close(); iStream.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (httpURLConnection != null) { // 关闭链接 httpURLConnection.disconnect(); } } return sb.toString(); } }
Demo2Index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>欢迎访问Demo2的主页</title> </head> <body>欢迎访问Demo2的主页,这是Demo2的主页。 </body> </html>
Demo2Action.java
package demo2.x.com; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import javax.print.attribute.standard.RequestingUserName; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; /** * Demo2主页,访问主页要先验证cookie * * @author: qlq * @date : 2017年8月29日下午12:02:31 */ public class Demo2Action extends ActionSupport { private String gotoUrl; public String getGotoUrl() { return gotoUrl; } public void setGotoUrl(String gotoUrl) { this.gotoUrl = gotoUrl; } @Override public String execute() throws Exception { HttpServletRequest request = ServletActionContext.getRequest(); Cookie cookies[] = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { if ("ssocookie".equals(cookie.getName())) { String result = this.doGet("http://check.x.com:8080/sso/checkCookie.action", cookie.getName(), cookie.getValue()); if ("1".equals(result)) { return SUCCESS; } } } } // 登录失败后将gotoUrl写到JSP页面 gotoUrl = "http://demo2.x.com:8080/demo2/main.action"; return LOGIN; } public String doGet(String url, String cookieName, String cookieValue) { // 用于接收返回的数据 StringBuffer sb = new StringBuffer(); // 建立一个链接的请求 HttpURLConnection httpURLConnection = null; try { // 包装请求的地址 URL urls = new URL(url + "?cookieName=" + cookieName + "&cookieValue=" + cookieValue); // 打开链接 httpURLConnection = (HttpURLConnection) urls.openConnection(); httpURLConnection.setRequestMethod("GET"); // 经过BufferReader读取数据 InputStream iStream = httpURLConnection.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(iStream); BufferedReader bReader = new BufferedReader(inputStreamReader); String temp = null; while ((temp = bReader.readLine()) != null) { sb.append(temp); } // 关闭流(先开后关,后开先关) bReader.close(); inputStreamReader.close(); iStream.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (httpURLConnection != null) { // 关闭链接 httpURLConnection.disconnect(); } } return sb.toString(); } }
struts.xml中配置
<package name="demo1" namespace="/demo1" extends="struts-default"> <action name="main" class="demo1.x.com.Demo1Action"> <result name="success">/Demo1Index.jsp</result> <result name="login">/login.jsp</result> </action> </package> <package name="demo2" namespace="/demo2" extends="struts-default"> <action name="main" class="demo2.x.com.Demo2Action"> <result name="success">/Demo2Index.jsp</result> <result name="login">/login.jsp</result> </action> </package>
5.启动tomcat进行测试:
1.访问:http://demo1.x.com:8080/demo1/main.action
查看页面源码
2.访问:http://demo2.x.com:8080/demo2/main.action
查看页面源码:
3.在demo1中登陆:
查看网络
4.刷新demo2
0.思路:
表单提交的时候 提交到本域,本域带着用户名与密码去验证服务器进行验证,验证经过的时候增长cookie,增长cookie的时候在页面中经过隐藏iframe经过增长cookie到本域与另外一个域;验证cookie的时候也是本域带着cookie名字与值去验证服务器进行验证,验证服务器返回验证结果。
1.准备环境
修改C:\Windows\System32\drivers\etc\hosts文件,增长域名的映射
修改tomcat\conf\server.xml
2.编写同一登陆接口
login.jsp(处理登陆提交地址是在本域。而后本域带着用户名和密码向验证服务器提交请求)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content="qlq"> <meta name="Keywords" content=""> <meta name="Description" content="单点登陆的界面"> <title>登陆界面</title> </head> <body> <center> <h3>请登陆</h3> <!-- 向当前本域提交登陆申请,处理登陆与cookie验证在其它域处理 --> <form action="/${path }/sso/login.action" method="post"> 用户名:<input type="text" name="username" value="user" /> 密码:<input type="password" name="password" value="123" /> <input type="hidden" name="gotoUrl" value="${gotoUrl}" /> <input type="submit" value="登陆" /> </form> </center> </body> </html>
Demo1.action中处理登陆请求:doLogin()方法----带着用户名与密码向验证服务器提交请求
package www.a.com; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.Map; import javax.print.attribute.standard.RequestingUserName; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; /** * Demo1主页,访问主页要先验证cookie * * @author: qlq * @date : 2017年8月29日下午12:02:31 */ public class Demo1Action extends ActionSupport { private String gotoUrl; private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getGotoUrl() { return gotoUrl; } public void setGotoUrl(String gotoUrl) { this.gotoUrl = gotoUrl; } @Override public String execute() throws Exception { /* * HttpServletRequest request = ServletActionContext.getRequest(); * Cookie cookies[] = request.getCookies(); if (cookies != null) { for * (Cookie cookie : cookies) { if ("ssocookie".equals(cookie.getName())) * { String result = * this.doGet("http://check.x.com:8080/sso/checkCookie.action", * cookie.getName(), cookie.getValue()); if ("1".equals(result)) { * return SUCCESS; } } } } */ // 登录失败后将gotoUrl写到JSP页面 gotoUrl = "http://demo1.x.com:8080/demo1/main.action"; return LOGIN; } /** * 登陆方法 * * @return */ public String doLogin() { Map<String, Object> map = new HashMap<>(); map.put("username", username); map.put("password", password); String result = this.doGet("http://www.x.com/sso/doLogin.action", map); if ("1".equals(result)) { return SUCCESS; } return LOGIN; } /* * 验证方法 */ public String doGet(String url, Map<String, Object> map) { // 用于接收返回的数据 StringBuffer sb = new StringBuffer(); // 建立一个链接的请求 HttpURLConnection httpURLConnection = null; try { StringBuffer t_s = new StringBuffer(url).append("?"); for (Map.Entry<String, Object> entry : map.entrySet()) { t_s.append(entry.getKey() + "=" + entry.getValue() + "&"); } url = t_s.substring(0, t_s.length() - 1); // 包装请求的地址 URL urls = new URL(url); // 打开链接 httpURLConnection = (HttpURLConnection) urls.openConnection(); httpURLConnection.setRequestMethod("GET"); // 经过BufferReader读取数据 InputStream iStream = httpURLConnection.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(iStream); BufferedReader bReader = new BufferedReader(inputStreamReader); String temp = null; while ((temp = bReader.readLine()) != null) { sb.append(temp); } // 关闭流(先开后关,后开先关) bReader.close(); inputStreamReader.close(); iStream.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (httpURLConnection != null) { // 关闭链接 httpURLConnection.disconnect(); } } return sb.toString(); } }
Demo2.action中处理登陆请求:doLogin()方法----带着用户名与密码向验证服务器提交请求
package www.b.com; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.Map; import javax.print.attribute.standard.RequestingUserName; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; /** * Demo1主页,访问主页要先验证cookie * * @author: qlq * @date : 2017年8月29日下午12:02:31 */ public class Demo2Action extends ActionSupport { private String gotoUrl; private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getGotoUrl() { return gotoUrl; } public void setGotoUrl(String gotoUrl) { this.gotoUrl = gotoUrl; } @Override public String execute() throws Exception { /* * HttpServletRequest request = ServletActionContext.getRequest(); * Cookie cookies[] = request.getCookies(); if (cookies != null) { for * (Cookie cookie : cookies) { if ("ssocookie".equals(cookie.getName())) * { String result = * this.doGet("http://check.x.com:8080/sso/checkCookie.action", * cookie.getName(), cookie.getValue()); if ("1".equals(result)) { * return SUCCESS; } } } } */ // 登录失败后将gotoUrl写到JSP页面 gotoUrl = "http://demo1.x.com:8080/demo1/main.action"; return LOGIN; } /** * 登陆方法 * * @return */ public String doLogin() { Map<String, Object> map = new HashMap<>(); map.put("username", username); map.put("password", password); String result = this.doGet("http://www.x.com/sso/doLogin.action", map); if ("1".equals(result)) { return SUCCESS; } return LOGIN; } /* * 验证方法 */ public String doGet(String url, Map<String, Object> map) { // 用于接收返回的数据 StringBuffer sb = new StringBuffer(); // 建立一个链接的请求 HttpURLConnection httpURLConnection = null; try { StringBuffer t_s = new StringBuffer(url).append("?"); for (Map.Entry<String, Object> entry : map.entrySet()) { t_s.append(entry.getKey() + "=" + entry.getValue() + "&"); } url = t_s.substring(0, t_s.length() - 1); // 包装请求的地址 URL urls = new URL(url); // 打开链接 httpURLConnection = (HttpURLConnection) urls.openConnection(); httpURLConnection.setRequestMethod("GET"); // 经过BufferReader读取数据 InputStream iStream = httpURLConnection.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(iStream); BufferedReader bReader = new BufferedReader(inputStreamReader); String temp = null; while ((temp = bReader.readLine()) != null) { sb.append(temp); } // 关闭流(先开后关,后开先关) bReader.close(); inputStreamReader.close(); iStream.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (httpURLConnection != null) { // 关闭链接 httpURLConnection.disconnect(); } } return sb.toString(); } }
LoginAction.java 验证服务器处理登陆请求(接收上面带来的用户名与密码进行验证,不用设置cookie,只用设置返回验证结果)
package www.x.com; import java.awt.image.VolatileImage; import java.io.IOException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ; import www.x.com.utils.CheckCookie; public class LoginAction extends ActionSupport { private String username; private String password; private String gotoUrl; private String cookieName; private String cookieValue; public String getCookieName() { return cookieName; } public void setCookieName(String cookieName) { this.cookieName = cookieName; } public String getCookieValue() { return cookieValue; } public void setCookieValue(String cookieValue) { this.cookieValue = cookieValue; } public String getGotoUrl() { return gotoUrl; } public void setGotoUrl(String gotoUrl) { this.gotoUrl = gotoUrl; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } /** * 验证登陆信息 * * @throws IOException */ public void doLogin() throws IOException { boolean OK = this.check(); String result = "0"; if (OK) { result = "1"; } HttpServletResponse response = ServletActionContext.getResponse(); response.getWriter().print(result); response.getWriter().close(); } public void checkCookie() throws IOException { String result = "0"; if (CheckCookie.checkCookie(cookieName, cookieValue)) { result = "1"; } HttpServletResponse response = ServletActionContext.getResponse(); response.getWriter().print(result); response.getWriter().close(); } public boolean check() { if ("user".equals(username) && "123".equals(password)) return true; return false; } }
struts.xml进行配置
<package name="sso" namespace="/sso" extends="struts-default"> <!-- 只是验证,没有返回值 --> <action name="doLogin" class="www.x.com.LoginAction" method="doLogin"> </action> </package> <package name="demo1" namespace="/demo1" extends="struts-default"> <action name="main" class="www.a.com.Demo1Action" method="doLogin"> <result name="success">/Demo1Index.jsp</result> <result name="login">/login.jsp</result> </action> </package> <package name="demo2" namespace="/demo2" extends="struts-default"> <action name="main" class="www.b.com.Demo2Action" method="doLogin"> <result name="success">/Demo2Index.jsp</result> <result name="login">/login.jsp</result> </action> </package>
3.登陆校验接口----------------LoginAction.java检验cookie是否有效
public void checkCookie() throws IOException { String result = "0"; if ("ssocookie".equals(cookieName) && "sso".equals(cookieValue)) { result = "1"; } HttpServletResponse response = ServletActionContext.getResponse(); response.getWriter().print(result); response.getWriter().close(); }
struts.xml进行配置
4.编写Demo1和Demo2主页
两个成功页面都是成功后加载主页时访问域名a与域名b下的添加cookie的方法(经过隐藏的iframe能够实现),cookie添加在本域下面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>欢迎访问Demo2的主页</title> </head> <body> 欢迎访问Demo2的主页,这是Demo2的主页。 <!--成功以后隐藏一个设置cookie的链接 --> <c:forEach var="url" items="${hiddenurls }"> <iframe src="${url }" width="0px" height="0px" style="display: none"></iframe> </c:forEach> </body> </html>
主页处理增长cookie
package www.a.com; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.print.attribute.standard.RequestingUserName; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; /** * Demo1主页,访问主页要先验证cookie * * @author: qlq * @date : 2017年8月29日下午12:02:31 */ public class Demo1Action extends ActionSupport { private String gotoUrl; private String username; private String password; private String path; private List<String> hiddenurls; public String getPath() { return path; } public void setPath(String path) { this.path = path; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getGotoUrl() { return gotoUrl; } public void setGotoUrl(String gotoUrl) { this.gotoUrl = gotoUrl; } public List<String> getHiddenurls() { return hiddenurls; } public void setHiddenurls(List<String> hiddenurls) { this.hiddenurls = hiddenurls; } @Override public String execute() throws Exception { HttpServletRequest request = ServletActionContext.getRequest(); Cookie cookies[] = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { if ("ssocookie".equals(cookie.getName())) { HashMap<String, Object> map = new HashMap<>(); map.put("cookieName", cookie.getName()); map.put("cookieValue", cookie.getValue()); String result = this.doGet("http://www.x.com/sso/checkCookie.action", map); if ("1".equals(result)) { return SUCCESS; } } } } // 登录失败后将gotoUrl写到JSP页面 path = "demo1"; gotoUrl = "http://www.a.com/demo1/main.action"; return LOGIN; } public void addCookie() { Cookie cookie = new Cookie("ssocookie", "sso"); cookie.setPath("/"); HttpServletResponse response = ServletActionContext.getResponse(); response.addCookie(cookie); } /** * 登陆方法 * * @return */ public String doLogin() { Map<String, Object> map = new HashMap<>(); map.put("username", username); map.put("password", password); String result = this.doGet("http://www.x.com/sso/doLogin.action", map); if ("1".equals(result)) { hiddenurls = new ArrayList<>(); hiddenurls.add("http://www.a.com/demo1/addCookie.action"); hiddenurls.add("http://www.b.com/demo2/addCookie.action"); return SUCCESS; } return LOGIN; } /* * 验证方法 */ public String doGet(String url, Map<String, Object> map) { // 用于接收返回的数据 StringBuffer sb = new StringBuffer(); // 建立一个链接的请求 HttpURLConnection httpURLConnection = null; try { StringBuffer t_s = new StringBuffer(url).append("?"); for (Map.Entry<String, Object> entry : map.entrySet()) { t_s.append(entry.getKey() + "=" + entry.getValue() + "&"); } url = t_s.substring(0, t_s.length() - 1); // 包装请求的地址 URL urls = new URL(url); // 打开链接 httpURLConnection = (HttpURLConnection) urls.openConnection(); httpURLConnection.setRequestMethod("GET"); // 经过BufferReader读取数据 InputStream iStream = httpURLConnection.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(iStream); BufferedReader bReader = new BufferedReader(inputStreamReader); String temp = null; while ((temp = bReader.readLine()) != null) { sb.append(temp); } // 关闭流(先开后关,后开先关) bReader.close(); inputStreamReader.close(); iStream.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (httpURLConnection != null) { // 关闭链接 httpURLConnection.disconnect(); } } return sb.toString(); } }
struts.xml配置
5.测试:
1.访问:http://www.b.com/demo2/main.action
查看源码:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content="qlq"> <meta name="Keywords" content=""> <meta name="Description" content="单点登陆的界面"> <title>登陆界面</title> </head> <body> <center> <h3>请登陆</h3> <!-- 向当前本域提交登陆申请,处理登陆与cookie验证在其它域处理 --> demo2 <form action="/demo2/doLogin.action" method="post"> 用户名:<input type="text" name="username" value="user" /> 密码:<input type="password" name="password" value="123" /> <input type="hidden" name="gotoUrl" value="http://www.b.com/demo2/main.action" /> <input type="submit" value="登陆" /> </form> </center> </body> </html>
2.访问: http://www.a.com/demo1/main.action
查看源码:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content="qlq"> <meta name="Keywords" content=""> <meta name="Description" content="单点登陆的界面"> <title>登陆界面</title> </head> <body> <center> <h3>请登陆</h3> <!-- 向当前本域提交登陆申请,处理登陆与cookie验证在其它域处理 --> demo1 <form action="/demo1/doLogin.action" method="post"> 用户名:<input type="text" name="username" value="user" /> 密码:<input type="password" name="password" value="123" /> <input type="hidden" name="gotoUrl" value="http://www.a.com/demo1/main.action" /> <input type="submit" value="登陆" /> </form> </center> </body> </html>
3.登陆demo1
4.刷新demo2