sso 同域之上简单模拟
sso 同域之下简单模拟
最近了解了下SSO,参考http://blog.****.net/javachannel/article/details/752437
模拟了同域之下的通过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
最近了解了下SSO,参考http://blog.****.net/javachannel/article/details/752437
模拟了同域之下的通过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; } }