`

sso 同域之下简单模拟

    博客分类:
  • SSO
SSO 
阅读更多
最近了解了下SSO,参考http://blog.csdn.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; 
	}
}
分享到:
评论

相关推荐

    .net 简单sso登录

    接下来,我们将讨论如何构建一个简单的SSO系统: 1. **中心认证服务(CAS服务器)**:创建一个.NET Web应用作为CAS服务器,负责处理用户的登录请求,验证用户凭证,并生成票据。这通常涉及到自定义的登录页面和控制...

    SSO的简单实现SSO的简单实现

    以下是对SSO简单实现的详细说明: 在实现SSO时,有多种方法可以选择: 1. **商业软件**:一些大型公司如 Netgrity(Siteminder)、Novell(iChain)、RSA(ClearTrust)等提供专门的SSO解决方案。这些软件通常具备...

    关于SSO单点登录的简单实现

    在本文中,我们将探讨SSO的基本原理、实现方式以及一个简单的SSO系统的设计。 **SSO基本原理** SSO的核心是通过共享一种信任关系来实现跨系统的身份验证。这种信任通常由一个中央认证服务(CAS,Central ...

    SSO之CAS单点登录实例演示

    SSO之CAS单点登录实例演示

    论文研究-基于SSO-CA模型的重庆渝西片区城市用地动态变化模拟 .pdf

    综上所述,本研究的意义在于提出了一种新的模拟城市用地变化的SSO-CA模型,并通过实证分析,验证了该模型在模拟精度和适用性方面相比于传统模型的优势。研究成果可以为城市规划决策提供有力的技术支持和参考依据。这...

    spring+springMvc简单实现SSO单点登录

    利用springMvc 实现的简单的单点登录Demo,内含三个小Mavn项目分别是 1、认证中心SSOServer 2、子系统1SSOClient1 3、子系统2SSOClient2 文章请参考 http://blog.csdn.net/qq_31183297/article/details/79419222

    sso解决方案汇总

    本文将深入探讨SSO的几种常见实现方案,包括虚拟目录的主应用与子应用之间的SSO、不同验证机制下的SSO、同一域名或不同域名下子域名间SSO的实现,以及不同.NET版本和混合身份验证模式下的SSO解决方案。 ### 虚拟...

    spring boot 实现SSO单点登陆

    spring boot整合spring security 实现SSO单点登陆 完整DEMO. ...2、先后启动SsoServer、sso-resource、sso-client1、sso-client2 3、访问http://sso-taobao:8083/client1/ 或 http://sso-tmall:8084/client2/

    Form实现同一服务器下的SSO

    在SSO场景下,我们不再局限于单一应用,而是要在整个服务器或域内共享用户的登录状态。 首先,实现SSO的关键在于共享用户认证信息。在Form SSO的实现中,通常会创建一个中央认证服务(Central Authentication ...

    xxl-sso-1.1.0

    XXL-SSO 1.1.0 是一个专为初学者设计的简单单点登录(Single Sign-On,简称SSO)系统示例。这个项目是基于Maven构建的,适用于那些想要学习如何实现SSO功能的开发者。通过将源代码导入Eclipse等开发工具,用户可以...

    sso 单点登陆 java 动手写sso

    下面我们将深入探讨SSO的基本原理、实现流程以及如何使用Spring Boot来搭建一个简单的SSO系统。 **SSO基本原理** SSO的核心思想是共享认证信息,通过中央认证服务器(CAS)来统一处理用户的登录状态。当用户访问受...

    SSO单点登录

    SSO(Single Sign-On)单点登录是一种网络身份验证机制,允许用户在一次登录后访问多个相互关联的应用系统,而无需再次输入凭证。...随着云计算和多应用环境的发展,SSO已经成为现代企业不可或缺的技术之一。

    C#单点登陆组件源码SSO

    4. **跨域支持**:实现SSO的关键挑战之一是跨域问题。源码可能包含了处理不同域之间的票据传递的技术,例如使用隐藏的IFrame或者设置P3P头来实现跨域Cookie。 5. **会话管理**:在SSO环境中,会话管理需要特别注意...

    SSO之返回多个值

    SSO(Single Sign-On)是单点登录的缩写,是一种网络身份验证机制,允许用户在一次登录后访问多个相互关联的应用系统,而无需再次进行身份验证。在本文中,我们将探讨SSO如何处理返回多个值的情况,以及相关工具和...

    SSO个人实现方式

    SSO(Single Sign-On)是单点登录的缩写,是一种网络身份验证机制,允许用户在一次登录后访问多个相互关联的应用系统,而无需再次进行身份验证。在本文中,我们将探讨SSO的原理,以及如何通过提供的压缩包文件实现...

    SSO_same_domain

    在这个“SSO_same_domain”主题中,我们关注的是同一域名下的SSO实现。这意味着所有相关应用都部署在同一顶级域名或子域名下,从而简化了身份验证流程。 1. **同域概念**:同域是指多个网页或应用共享相同的顶级...

    sso单点登录

    本示例中的"Simple-SSO"是一个简单的SSO实现,包括客户端和服务器两部分,用于演示如何在多应用间实现统一的身份认证。 **SSO基本原理** 1. **票据(Ticket)机制**:SSO的核心是票据,它相当于用户的临时通行证。...

    sso_introduction.pdf

    认证服务器是SSO的核心组件之一,负责管理用户身份验证流程。它需要能够高效地处理大量的认证请求,并且具有足够的安全性来保护用户的敏感信息。 - **安全性**:采取各种措施来保护认证过程的安全,如使用HTTPS协议...

Global site tag (gtag.js) - Google Analytics