最近了解了下SSO,参考[url]http://blog.csdn.net/javachannel/article/details/752437[/url]
模拟了同域之下的通过cookie实现单点登录。
大体思路是:
1.当每次访问client端(指普通web应用)时,会进入client端的过滤器,
然后在过滤器中获取名为ticket的cookie,然后通过HttpURLConnection访问server端(SSO服务).
2.server端获取传过来的cookie值,然后进行验证看是否用户已经登录,如果登录则返回用户名,
如果未登录则返回一个"failure"字符串。
3.客户端获取服务器端返回的字符串数据,然后进行判断,如果为"failure"则跳转到登录页面login.jsp,
否则正常显示.
4.当在login.jsp中输入用户名和密码后,会提交给SSO服务器,然后SSO服务器端会验证用户。如果验证通过,
会添加一个path为"/",domain为当前域,名字为"ticket"的cookie,并在内存中添加accounts和SSOIDs的2个Map
(accounts存储用户账户信息 键:username 值:password。SSOIDs存储名为ticket的cookie的value值
和username 之间的对应关系 键:cookie value 值:username)。
具体代码如下
客户端ssoclient:
jsp 页面
index.jsp
result.jsp 页面
客户端过滤器
SSOFilter.java
服务器端ssoserver:
jsp 页面
login.jsp
服务器端接受请求的servlet
SSOAuth.java
模拟了同域之下的通过cookie实现单点登录。
大体思路是:
1.当每次访问client端(指普通web应用)时,会进入client端的过滤器,
然后在过滤器中获取名为ticket的cookie,然后通过HttpURLConnection访问server端(SSO服务).
2.server端获取传过来的cookie值,然后进行验证看是否用户已经登录,如果登录则返回用户名,
如果未登录则返回一个"failure"字符串。
3.客户端获取服务器端返回的字符串数据,然后进行判断,如果为"failure"则跳转到登录页面login.jsp,
否则正常显示.
4.当在login.jsp中输入用户名和密码后,会提交给SSO服务器,然后SSO服务器端会验证用户。如果验证通过,
会添加一个path为"/",domain为当前域,名字为"ticket"的cookie,并在内存中添加accounts和SSOIDs的2个Map
(accounts存储用户账户信息 键:username 值:password。SSOIDs存储名为ticket的cookie的value值
和username 之间的对应关系 键:cookie value 值:username)。
具体代码如下
客户端ssoclient:
jsp 页面
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Insert title here</title>
</head>
<body>
<a href="result.jsp">进入结果页</a>
<a href="result.jsp?action=logout">注销</a>
</body>
</html>
result.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=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
你好:${user}
</body>
</html>
客户端过滤器
SSOFilter.java
package com.filter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SSOFilter implements Filter {
private static String cookieName="ticket";
private static String ssoUrl="http://localhost:8080/ssoserver";
private static String ssoAuthUrl=ssoUrl+"/SSOAuth";
private static String ssoLoginUrl=ssoUrl+"/login.jsp";
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest) req;
HttpServletResponse response=(HttpServletResponse) res;
String result="failure";
String url = request.getRequestURL().toString();
String qstring = request.getQueryString();
if (qstring == null) qstring ="";
//检查http请求的head是否有需要的cookie
String cookieValue ="";
Cookie[] diskCookies = request.getCookies();
if (diskCookies != null) {
for (int i = 0; i < diskCookies.length; i++) {
if(diskCookies[i].getName().equals(cookieName)){
cookieValue = diskCookies[i].getValue();
//如果找到了相应的cookie则效验其有效性
result = SSOService(cookieValue);
}
}
}
if (result.equals("failure")) { //效验失败或没有找到cookie,则需要登录
response.sendRedirect(ssoLoginUrl+"?goto="+url);
} else if (qstring.indexOf("logout") > 1) {//logout服务
response.sendRedirect(ssoAuthUrl+"?goto="+url+"&action=logout&cookiename="+cookieValue);
} else {//效验成功
request.setAttribute("user",result);
chain.doFilter(req, res);
}
}
// 验证cookie
private String SSOService(String cookievalue) throws IOException {
String authAction = "?action=authcookie&cookiename=";
URL url = new URL(ssoAuthUrl+authAction+cookievalue);
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.connect();
InputStream is=conn.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(is));
StringBuffer bodyMessage=new StringBuffer();
String line=null;
while((line=br.readLine())!=null){
bodyMessage.append(line);
}
return bodyMessage.toString();
}
public void destroy() {
}
public void init(FilterConfig arg0) throws ServletException {
}
}
服务器端ssoserver:
jsp 页面
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>登录页面</title>
</head>
<body>
<form action="SSOAuth">
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password" /><br/>
<input type="submit" value="提交"/>
<input type="hidden" value="${param.goto}" name="goto"/>
</form>
</body>
</html>
服务器端接受请求的servlet
SSOAuth.java
package com.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SSOAuth extends HttpServlet {
private static final long serialVersionUID = 2259814016129033740L;
// 存储用户账户信息 键:username 值:password
private static Map<String,String> accounts=new HashMap<String,String>();
// 存储session id和username 之间的对应关系 键:sessionId 值:username
private static Map<String,String> SSOIDs=new HashMap<String,String>();
// 写入浏览器的cookie
private static String cookieName="ticket";
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
String action = request.getParameter("action");
String result="failure";
if (action==null) {
handlerFromLogin(request,response);
} else if (action.equals("authcookie")){
String cookievalue = request.getParameter("cookiename");
if (cookievalue != null) result = authCookie(cookievalue);
out.print(result);
out.close();
} else if (action.equals("authuser")) {
result=authNameAndPasswd(request,response);
out.print(result);
out.close();
} else if (action.equals("logout")) {
String cookievalue=request.getParameter("cookiename");
if (cookievalue != null){
logout(response, cookievalue);
}
String gotoURL = request.getParameter("goto");
response.sendRedirect(gotoURL);
out.close();
}
}
// 处理登录
private void handlerFromLogin(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
boolean result= checkAccount(username, password);
if (result==false)
request.getRequestDispatcher("/login.jsp").forward(request, response);
else {
String gotoURL = request.getParameter("goto");
String newID = createUID();
// 添加账户信息
accounts.put(username, password);
// 添加sessionID 和 账户关联关系
SSOIDs.put(newID, username);
Cookie cookie = new Cookie(cookieName, newID);
cookie.setValue(newID);
cookie.setPath("/");
response.addCookie(cookie);
if (gotoURL == null||gotoURL.length()==0) {
response.sendRedirect("http://localhost:8080/ssoclient/index.jsp");
}else{
response.sendRedirect(gotoURL);
}
}
}
// 创建session id
private String createUID(){
return UUID.randomUUID().toString().replaceAll("-", "");
}
// 验证cookie
private String authCookie(String cookie){
String username=SSOIDs.get(cookie);
if(username==null||username.length()==0){
return "failure";
}
return username;
}
// 验证用户名和密码
private String authNameAndPasswd(HttpServletRequest request, HttpServletResponse response){
String username = request.getParameter("username");
String password = request.getParameter("password");
String pass = accounts.get(username);
if ((pass==null)||(!pass.equals(password))){
return "failure";
}
return username;
}
// 注销用户
private void logout(HttpServletResponse response,String cookievalue){
String username=SSOIDs.get(cookievalue);
if(username==null){
return ;
}
SSOIDs.remove(cookievalue);
if(accounts.get(username)==null){
return ;
}
accounts.remove(username);
Cookie cookie=new Cookie(cookieName, cookievalue);
cookie.setValue("");
cookie.setMaxAge(0);
cookie.setPath("/");
response.addCookie(cookie);
}
// 验证账户
private boolean checkAccount(String username,String password){
Map<String,String> initData=new HashMap<String, String>();
initData.put("admin", "admin");
String pass=initData.get(username);
if(password==null||!password.equals(pass)){
return false;
}
return true;
}
}