自定义单点登录(2)

惯例:

我是温浩然:

单点登录,分为客户端和服务器端,客户端,主要与用户的浏览器进行交互,操作浏览器,比如,cookie,session等。

服务器端,主要是储存用户的信息,和后台数据库进行交互,获取当前登录的用户信息,对用户的登录进行验证。

关于单点登录,我感觉,验证方式有很多种,

我这里,是对cookie进行操作,当用户登录成功后,会在浏览器新建cookie,储存一定信息,当用户访问受保护的请求时,获取cookie并进行验证,如果验证通过,则该用户已经登录,可以访问受保护的信息。

下面贴在Filter中,进行验证的代码。

1、服务器中,对用户进行验证的代码。

package com.tujia.core.security;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.util.WebUtils;

import com.tujia.common.exception.UnAuthedException;
import com.tujia.tuuser.dao.UserDao;
import com.tujia.tuuser.entity.User;
import com.tujia.tuuser.service.UserService;

@Component
public class SecurityUtil {

	@Resource
    private UserDao userDao;

	private String TOURL = "TOURL";

	private static ThreadLocal<User> threadTuser = new ThreadLocal<User>();

	private Map<String,AuthTuUser> map = new HashMap<String,AuthTuUser>();

	private Map<String,User> mapUser = new HashMap<String,User>();

        //下面这个是对数据进行操作,与数据库进行交互的Java类
	@Autowired
	private UserService userService;

        /*@Autowired
	TokenAuthentication tokenAuthentication;*/
	//tujia.requrl  下面这些都是配置文件
	@Value("${tujia.requrl}")
	private String requrl;
	@Value("${tujia.token}")
	private String tokenKey;
	@Value("${loginURL:\"\"}")
	private String loginURL;

	private int MS_IN_A_DAY = 24 * 3600 * 1000;
	private int SECS_IN_A_MONTH = 24 * 3600 * 30;

	/**
	 * 得到当前登录的用户,用户再业务逻辑的地方
	 *
	 * @return
	 */
	public static User getCurrentTuser() {
		return threadTuser.get();
	}

	/**
	 * 用在filter的地方,
	 *
	 * @param request
	 * @throws UnAuthedException
	 * @return:true:已经登录了。false:没有登录
	 */
	public boolean authenticate(HttpServletRequest request,
			HttpServletResponse response) throws UnAuthedException {
		boolean result;
		// 处理cookie情况
		Cookie cookie = WebUtils.getCookie(request, tokenKey);
		String url = request.getRequestURI();

		//if登录cookie is null ,则添加cookie url.
		if (cookie == null){
			//这是被拦截后添加的cookie
			Cookie cookieurl = new Cookie(requrl, url);
			cookieurl.setPath("/");
			cookieurl.setMaxAge(-1);
			response.addCookie(cookieurl);
			return false;
			}

		String value = cookie.getValue();
		AuthTuUser au = (AuthTuUser) map.get(value);
		if (au == null ){
			Cookie cookieurl = new Cookie(requrl, url);
			cookieurl.setPath("/");
			cookieurl.setMaxAge(-1);
			response.addCookie(cookieurl);
			return false;
			}
		request.getSession().setAttribute("userLogin", mapUser.get(value));
		result = verifyTuserId(au.getId());
		if (!result) {
			logout(request, response);
		}

		return result;
	}

	public User getLoinTuser(HttpServletRequest request) throws UnAuthedException {
		// 处理cookie情况
		Cookie cookie = WebUtils.getCookie(request, tokenKey);
		if (cookie == null)
			return null;
		String value = cookie.getValue();
		AuthTuUser au = (AuthTuUser) map.get(value);
		if (au == null)// || au.isExpire()
			return null;

		 User user = userService.get(au.getId());
		return user;
	}

	private String generateValue() {
		return UUID.randomUUID().toString();
	}

	public void inputSuccess(HttpServletRequest request,HttpServletResponse response, long userId,
			boolean saved) throws UnAuthedException {
		if (verifyTuserId(userId)) {
			addCookieAndCache(request,response, userId, saved);
		}else{
			throw new UnAuthedException("该用户不存在,请重新输入!");
		}
	}

	private void addCookieAndCache(HttpServletRequest request,HttpServletResponse response, long userId,
			boolean saved) {

		AuthTuUser au = new AuthTuUser(userId);

		User user = userDao.get(userId);

		String tokenValue = generateValue();
		Cookie cookie = new Cookie(tokenKey, tokenValue);
		cookie.setPath("/");
		if (saved) {
			cookie.setMaxAge(SECS_IN_A_MONTH);
			au.setSaved(true);
		} else {
			cookie.setMaxAge(-1);
			au.setExpireDate(new Date(System.currentTimeMillis() + MS_IN_A_DAY));
		}
		request.setAttribute("token", tokenValue);
		response.addCookie(cookie);

		map.put(tokenValue, au);
		mapUser.put(tokenValue, user);
		request.getSession().setAttribute("userLogin", user);
	}

	public boolean verifyTuserId(long userId) throws UnAuthedException {
		boolean result;
		 User user = userService.get(userId);
		if (user.isDeleted()) {// 员工被停用了
			result = false;
		} else {
			threadTuser.set(user);
			result = true;
		}
		return result;
	}

	/**
	 *
	 * @param req
	 * @return
	 */
	public void logout(HttpServletRequest request, HttpServletResponse response) {

		Cookie cookie = WebUtils.getCookie(request, tokenKey);
		if (cookie == null)
			return;

		String value = cookie.getValue();
		AuthTuUser au = (AuthTuUser) map.get(value);
		if (au == null) {
			delteCookie(response, tokenKey);
			delteCookie(response, requrl);
			return;
		}

		delteCookie(response, tokenKey);
		map.remove(value);
		return;

	}

	private void delteCookie(HttpServletResponse response, String cookieName) {
		Cookie cookie = new Cookie(cookieName, "");
		cookie.setPath("/");
		cookie.setMaxAge(0);
		response.addCookie(cookie);
	}

	// 线程结束的时候调用。
	public static void clearOnThreadOver() {
		threadTuser.remove();
	}

	public void setTOURL(HttpServletResponse response,
			HttpServletRequest request) {
		StringBuffer u = request.getRequestURL();
		if (request.getQueryString() != null) {
			u.append('?');
			u.append(request.getQueryString());
		}
		Cookie cookie = new Cookie(TOURL, u.toString());
		cookie.setPath("/");
		cookie.setMaxAge(-1);
		response.addCookie(cookie);
	}

	public String getTOURL(HttpServletRequest request,
			HttpServletResponse response) {
		Cookie cookie = WebUtils.getCookie(request, TOURL);
		if (cookie == null)
			return "";
		delteCookie(response, TOURL);
		return cookie.getValue();
	}

	public String getLoginURL() {
		return loginURL;
	}

	public String getReqURL(HttpServletRequest request,HttpServletResponse response){

		Cookie cookie = WebUtils.getCookie(request, requrl);

		String value = cookie.getValue();
		return value;
	}

	public void setLoginURL(String loginURL) {
		this.loginURL = loginURL;
	}

	public void requrl(HttpServletRequest request,HttpServletResponse response) {
		Cookie cookie = WebUtils.getCookie(request, requrl);
		if(cookie == null){
			Cookie cookieurl = new Cookie(requrl, "/tu-login/user/index");
			cookieurl.setPath("/");
			cookieurl.setMaxAge(-1);
			response.addCookie(cookieurl);
		}
	}

	public boolean getAuthTuUser(String token){

		AuthTuUser au = (AuthTuUser) map.get(token);

		if (au == null ){
			return false;
		}else{
			User user = mapUser.get(token);

			return true;
		}

	}
}

贴的很多,但是如果看得仔细,会发现其中我增加了两个cookie,一个是token,就是保存在浏览器中的登录信息。

另一个cookie是requrl,这个是,当用户访问受保护的请求,然后登录后,能自动调整显示的页面。

AuthTuUser这个是储存用户登录信息的javaBean,当用户判断是否登录时,就用map来判断。
时间: 2024-09-10 15:06:07

自定义单点登录(2)的相关文章

自定义单点登录项目 (1)

这是(1),打算写一个系列 惯例, 我是温浩然: 上一个月,研究了两个周的CAS单点登录.因为是发布到阿里云服务器上,项目中的证书文件,与阿里云服务器冲突,所以,就自己写了一套单点登录页面. 先说一下需求. 1.用户在访问系统时,需要进行验证,该资源是否是受保护的资源,如果不是,可以继续访问,(比如开放的接口,登录页面,退出页面,都不是受保护的.) 2.如果访问的请求是受保护的,再进行验证,当前用户是否已经登录,如果没有登录,进行拦截,跳转登录页面,如果已经登录,进行权限验证,如果有权限访问当前

CAS解决单点登录SSO

关于CAS很多的原理和基础的配置启动,网上是很多的,我更多是结合我的实践和心得.需要了解CAS的原理,认证协议,认证流程,可以参考以下文章. 让CAS支持客户端自定义登陆页面--客户端篇 CAS原理与配置-基于CAS的单点登陆的研究(上) 服务端配置 CAS单点登陆部署 CAS配置手册 CAS单点登录配置 背景 单点登录(SSO)是企业开发的重要问题,在我的毕设项目中,由于要和系统其他开发模块共用用户认证模块,方便共享用户资源,所以需要一个好的SSO解决方案. 一般SSO的实现机制有两种:基于s

SpringSecurity+JPA+CAS单点登录

问题描述 SpringSecurity+JPA+CAS单点登录错误信息如下:ERRORContextLoader:220-Contextinitializationfailedorg.springframework.beans.factory.BeanDefinitionStoreException:UnexpectedexceptionparsingXMLdocumentfromServletContextresource[/WEB-INF/classes/applicationContext

单点登录之CAS SSO从入门到精通(第二天)

啊......沙滩,阳光,笔记本往膝上一搁,开始写博客.第一次没在国内过年,避开了吃吃吃,感觉真好,人也觉得轻松多了. 上次说到了CAS SSO最基本的使用方法,并且我们结合了一个数据库表来实现了我们自定义用户名和密码的单点登录功能.今天我们将要开始把我们的CAS SSO一步步往更深更专业的层次推进下去,我们先来看一下CAS SSO在结合WINDOWS AD域(此处我们使用open-ldap)来实现这个WINDOWS AD域的单点登录.即如何把我们的单点登录和巳有域帐号进行一下结合. 安装ope

SSO单点登录系列2:cas客户端和cas服务端交互原理动画图解,cas协议终极分析

这次的收获是把PPT也深入研究了一番... 上图:一会上原理分析:(本篇不涵盖cas代理认证模式,代理目前还没用到.) 文中所有资料下载地址:在文章中最下方. 1)PPT流程图: 一.用户第一次访问web1应用. ps:上图少画了一条线,那一条线,应该再返回来一条,然后再到server端,画少了一步...谢谢提醒.而且,重定向肯定是从浏览器过去的.我写的不严谨,画的比较通俗了...因该像下面这张图一样就ok了!!PPT自己下载下来修改吧,我就不改了. 二.用户第一次访问web2应用. 困扰了好久

单点登录之CAS SSO从入门到精通(第三天)

开场白 各位新年好,上海的新年好冷,冷到我手发抖. 做好准备全身心投入到新的学习和工作中去了吗?因为今天开始的教程很"变态"啊,我们要完成下面几件事: 自定义CAS SSO登录界面 在CAS SSO登录界面增加我们自定义的登录用元素 使用LDAP带出登录用户在LDAP内存储的更多的信息 实现CAS SSO支持多租户登录的功能 好,开始正文! 正文 上次我们说到了CAS SSO的一些基本用法如:连数据库怎么用,连LDAP怎么用,这次我们要来讲一个网上几乎没有人去过多涉及到的一个问题即:在

Android端实现单点登录的方法详解_Android

前言 单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任.单点登录在大型网站里使用得非常频繁,例如像阿里巴巴这样的网站,在网站的背后是成百上千的子系统,用户一次操作或交易可能涉及到几十个子系统的协作,如果每个子系统都需要用户认证,不仅用户会疯掉,各子系统也会为这种重复认证授权的逻辑搞疯掉.实现单点登录说到底就是要解决如何产生和存储那个信任,再就是其他系统如何验证这个信任的有效

UCenter单点登录/同步登录/同步登出实例

UCenter同步流程: 前提是需要在Ucenter上面添加好需要同步登录的应用(至少2个才能看到效果),并且显示:通信成功 假如我添加了A,B两个应用网站 1.首先当A站登录时,登录成功后,处理实质是调用uc_client提供的方法向UCenter获取2个脚本代码(A.B站),这两个脚本代码就是访问A.B两个站的api/uc.php中的登录方法,可以在方法中做登录所需session和cookie操作. 2.当登出时,操作和登录是一样的,都需要向UCenter获取2个脚本代码,目的是用来触发A.

Asp.net mvc 权限过滤和单点登录(禁止重复登录)_实用技巧

1.权限控制使用controller和 action来实现,权限方式有很多种,最近开发项目使用控制控制器方式实现代码如下 /// <summary> /// 用户权限控制 /// </summary> public class UserAuthorize : AuthorizeAttribute { /// <summary> /// 授权失败时呈现的视图 /// </summary> public string AuthorizationFailView