SSO单点登录,简单模拟

SSO单点登录(以下全是个人理解,如果有误,共同批评进步)

1.什么是单点登录:

在不同的应用中,受保护的同一用户,登录一次就可以访问相关的其他系统应用。比如搜狐登录后,可以直接访问博客、邮箱等等,而不用再重新登录博客系统、邮箱系统等等。方便了用户的操作。

2.同域下单点登录实现:

单点登录流程和大概思路如下:

SSO单点登录,简单模拟_第1张图片

  我们用具体代码来实现以下操作:

我们有四个项目,app1、app2、ssofilter、ssoserver分别是web系统1、web系统2、拦截请求系统、sso认证中心。

app1系统结构如下:

SSO单点登录,简单模拟_第2张图片

就一个jsp文件,用来获取用户信息。app2系统的页面也一样。

我们先写sso认证中心的代码,这里只写主要的代码:

登录的代码,登录成功后写入cookie,将令牌和用户信息存入全局信息中

	/**
	 * get请求,表示没有登录直接访问。获取路径,返回登录页面
	 */
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//获取请求路径
		String backurl=request.getParameter("backurl");
		request.setAttribute("backurl", backurl);
		request.getRequestDispatcher("index.jsp").forward(request, response);
	}
	
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//解决中文乱码
		request.setCharacterEncoding("utf-8");
		String username=request.getParameter("username");
		String password=request.getParameter("password");
		String backurl=request.getParameter("backurl");
		try {
			User user=new User();
			//根据用户名名称查询用户
			user = UserUtil.getUserByname(username);
			if(null!=user&& password.equals(user.getPassword())){
				System.out.println("登录成功!");
				/*String[] uuid=UUID.randomUUID().toString().split("-");
				StringBuffer token=new StringBuffer();
				for (String string : uuid) {
					token.append(string);
				}*/
				//生成令牌,根据java生成uuid,将其中的-符号替换为空字符串,然后转成小写字母
				String token=UUID.randomUUID().toString().replace("-", "").toLowerCase();
				//根据自定义的全局工具类,将令牌作为key,将用户信息作为value存入Map中
				MapUtil.addToken(token, user);
				//创建一个cookie
				Cookie cookie=new Cookie("token", token);
				cookie.setHttpOnly(true);
				cookie.setPath("/");
				//将cookie添入响应中,返回客户端
				response.addCookie(cookie);
				if(StringUtils.isNullOrEmpty(backurl)){
					//如果没有获取到请求路径,表示用户直接访问login登录页面,这里可以将值设置为登录成功后的主页
					backurl="success";
				}else{
					//将路径解码
					backurl=URLDecoder.decode(backurl,"utf-8");
				}
				//重新定向到返回路径
				//response.sendRedirect(backurl);
				response.getWriter().println(backurl);
			}else{
				response.setContentType("text/html;utf-8");
				response.setCharacterEncoding("utf-8");
				System.out.println("用户名或密码不对!");
				response.getWriter().println("用户名或密码不对");
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
SSO认证中心,验证代码:
		//获取请求令牌
		String token=request.getParameter("token");
		//根据令牌去请求对应的用户信息
		User user=MapUtil.getUserByToken(token);
		//判断令牌是否有效
		if(null!=user){
			//有效,返回用户信息
			response.getWriter().println("username="+URLEncoder.encode(user.getUsername(),"utf-8")+";password="+user.getPassword());
		}else{
			//无效,返回空字符串
			response.getWriter().println("");
		}
拦截请求系统代码:
		//将ServletRequest和ServletResponse转为Http请求的
		HttpServletRequest httprequest=(HttpServletRequest)request;
		HttpServletResponse httpresponse=(HttpServletResponse)response;
		//获取cookie数组
		Cookie[] cookies=httprequest.getCookies();
		String token=null;
		if(null!=cookies && 00){
				String[] userdata=stringbuffer.split(";");
				User user=new User();
				for (String string : userdata) {
					String[] string2=string.split("=");
						switch (string2[0]){
						case "username":
							user.setUsername(URLDecoder.decode(string2[1],"utf-8"));
							break;
						case "password":
							user.setPassword(string2[1]);
							break;
						}
					}
					request.setAttribute("user", user);
					filter.doFilter(httprequest, httpresponse);
				}else{
					//标示token无效,将请求定向到登录地址
					httpresponse.sendRedirect(SSOLOGINURL+"?backurl="+URLEncoder.encode(url,"utf-8"));
				}
			}
拦截请求系统打成jar包,加入web1和web2中使用,在web1和web2中配置拦截器
  
  	loginfilter
  	com.client.ssoFilter
  
  
  	loginfilter
  	*.jsp
  

还有SSO认证中心的登录页面:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>   




登录








你可能感兴趣的:(JAVA,SSO单点登录,简单模拟)