单点登录流程图

系统登陆拦截器

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package com.jdcloud.policycloudapi.sso; import com.alibaba.fastjson.JSON;
import com.jdcloud.policycloudapi.domain.response.RetResponse;
import com.jdcloud.policycloudapi.domain.vo.LoginUser;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter; public class SsoClientInterceptor implements HandlerInterceptor {
private Logger log = LoggerFactory.getLogger(this.getClass());
private SsoProperties ssoProperties;
private RemoteService remoteService;
public SsoClientInterceptor(SsoProperties ssoProperties, RemoteService remoteService) {
this.ssoProperties = ssoProperties;
this.remoteService = remoteService;
} public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
String tokenParam = null;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for(int i = 0; i < cookies.length; ++i) {
if (cookies[i].getName().equals("gunsToken")) {
tokenParam = cookies[i].getValue();
break;
}
}
}
if(!StringUtils.isNotBlank(tokenParam)){
tokenParam=request.getParameter("gunsToken");
} if (StringUtils.isNotBlank(tokenParam)) {
//验证tokenParam是否正确
Integer userId = this.remoteService.validateToken(tokenParam, HttpUtil.getRequestContextPath(request));
if (userId != null) {
request.setAttribute("SESSION_LOGIN_FLAG", tokenParam);
// 调用接口获取user,以及user权限列表
LoginUser loginUser=remoteService.getLoginUser(userId,tokenParam);
// log.info("loginUser:"+ JSON.toJSONString(loginUser));
// RestTemplateUtils restTemplateUtils=new RestTemplateUtils();
// LoginUser loginUser = restTemplateUtils.getLoginUser(tokenParam);
request.setAttribute(SsoConstants.LOGIN_USER_SESSION, loginUser);
return true;
} else {
// this.redirectSsoServer(request, response);
return responseFalse(response);
}
} else {
// this.redirectSsoServer(request, response);
return responseFalse(response);
}
// return true;
} private boolean responseFalse(HttpServletResponse response) throws IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = null;
out = response.getWriter();
out.write(JSON.toJSONString(RetResponse.retFail()));
out.flush();
out.close();
return false;
} private void redirectSsoServer(HttpServletRequest request, HttpServletResponse response) {
String redirectUrl = this.ssoProperties.getServerUrl() + "?" + "redirectUrl" + "=" + HttpUtil.encodeUrl(HttpUtil.getRequestFullPathNoParam(request)); try {
response.sendRedirect(redirectUrl);
} catch (IOException var5) {
this.log.error("跳转到服务器出错!", var5);
} } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
} public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}

 

SSO服务器登录验证代码

package com.stylefeng.sso.server.modular.controller;

import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.sso.plugin.constants.SsoConstants;
import com.stylefeng.sso.plugin.service.AuthService;
import com.stylefeng.sso.server.common.Rests;
import com.stylefeng.sso.server.modular.entity.SysUser;
import com.stylefeng.sso.server.modular.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import static com.stylefeng.sso.plugin.constants.SsoConstants.LOGOUT_URL; /**
* 登录验证控制器
*
* @author stylefeng
* @Date 2018/2/3 22:23
*/
@Controller
@Slf4j
public class AuthController extends BaseController { private static final String LOGIN_TIPS = "tips"; @Autowired
AuthService authService; @Autowired
private SysUserService sysUserService; private boolean isMobile(HttpServletRequest request) {
String userAgent = request.getHeader("User-Agent");
userAgent = userAgent.toLowerCase();
if (userAgent.contains("iphone") || userAgent.contains("android")
|| userAgent.contains("ipad") || userAgent.contains("ipod")) {
return true;
}
return false;
} @RequestMapping (value = "/login", method = RequestMethod.GET)
public String toLogin(HttpServletRequest request) {
return isMobile(request)? "/login_m.html" : "/login.html";
} @Value ("${spring.profiles.active}")
private String profile; @RequestMapping (value = "/login", method = RequestMethod.POST)
public String doLogin(HttpServletRequest request, HttpServletResponse response, Model model) { String returnUrl = isMobile(request)? "/login_m.html" : "/login.html"; String tokenParam = null;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equals("gunsToken")) {
tokenParam = cookies[i].getValue();
break;
}
}
} String redirectUrl = request.getParameter(SsoConstants.REDIRECT_PARAM_NAME); // 如果cookie中能取到token,则认为从其他页面登录,不继续登录流程,跳回原地址
// if (StringUtils.isNotBlank(tokenParam) && StringUtils.isNotBlank(redirectUrl)){
// log.info("用户已经处于登录状态,不继续登录流程,跳回原地址: {}", redirectUrl);
// try {
// response.sendRedirect(redirectUrl);
// return null;
// } catch (IOException e) {
// log.warn("已经登录,跳回原地址失败", e);
// model.addAttribute(LOGIN_TIPS, "网络异常!");
// return "/login.html";
// }
// } String userName = request.getParameter("userName");
String password = request.getParameter("password"); // 登录失败是记录redirectUrl
model.addAttribute(SsoConstants.REDIRECT_PARAM_NAME, redirectUrl);
if (ToolUtil.isEmpty(userName) || ToolUtil.isEmpty(password) || ToolUtil.isEmpty(redirectUrl)) {
model.addAttribute(LOGIN_TIPS, "请求信息不完整!");
return returnUrl;
} else { /**
* 判断用户账号密码是否正确
*/
Integer userId = authService.checkUserLogin(userName, password);
if (userId != null) { //如果账号密码正确,跳转回业务系统的url
String token = "";
try {
/*SysUser sysUser = sysUserService.getSysUser(userId);
sysUserService.insertLoginUserIntoRedisDto(sysUser, token);*/
token = authService.createToken(userId);
} catch (Exception e) {
log.warn("createToken失败",e);
model.addAttribute(LOGIN_TIPS, "登录失败,请稍后再试!");
return returnUrl;
} if (profile.equals("dev")) {
Cookie localhost = new Cookie(SsoConstants.TOKEN_PARAM_NAME, token);
localhost.setDomain("jdcloud.com");
localhost.setPath("/");
localhost.setMaxAge(36000);
response.addCookie(localhost);
} else {
Cookie cookie = new Cookie(SsoConstants.TOKEN_PARAM_NAME, token);
cookie.setPath("/");
response.addCookie(cookie);
} try {
// String redirect=redirectUrl+"?"+SsoConstants.TOKEN_PARAM_NAME + "=" + token;
// response.sendRedirect(redirectUrl /*+ "?" + SsoConstants.TOKEN_PARAM_NAME + "=" + token*/);
response.sendRedirect(redirectUrl);
return null;
} catch (IOException e) {
model.addAttribute(LOGIN_TIPS, "网络异常!");
return returnUrl;
}
} else {
//如果账号密码错误
model.addAttribute(LOGIN_TIPS, "账号或密码错误!");
return returnUrl;
}
}
} @ResponseBody
@RequestMapping ("/hello")
public String token() {
return "暂未登录";
} @RequestMapping (LOGOUT_URL)
public String logout(HttpServletRequest request, HttpServletResponse response, Model model) {
String tokenParam = null;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equals("gunsToken")) {
tokenParam = cookies[i].getValue();
break;
}
}
}
String redirectUrl = request.getParameter(SsoConstants.REDIRECT_PARAM_NAME);
if (StringUtils.isNotBlank(tokenParam)){
// 删除redis中保存的token,如果失败,不允许退出登录,跳回源地址
if (!authService.removeCachedToken(tokenParam)) {
try {
redirectUrl = redirectUrl + "?status="+SsoConstants.LOGIN_FAILED_FLAG+"?gunsToken"+tokenParam;
response.sendRedirect(redirectUrl);
return null;
} catch (Exception e) {
log.error("重定向失败", e);
return "/404.html";
}
} } // 删除cookie
// 开发环境为了方便前端本地测试配置域名hosts,cookie选择种到二级域下;线上环境域名一致,cookie种到默认的domain下
if (profile.equals("dev")) {
Cookie localhost = new Cookie(SsoConstants.TOKEN_PARAM_NAME, null);
localhost.setPath("/");
localhost.setMaxAge(0);
response.addCookie(localhost);
} else {
Cookie newCookie = new Cookie(SsoConstants.TOKEN_PARAM_NAME, null); //假如要删除名称为username的Cookie
newCookie.setMaxAge(0); //立即删除型
newCookie.setPath("/"); //项目所有目录均有效,这句很关键,否则不敢保证删除
response.addCookie(newCookie); //重新写入,将覆盖之前的
} //跳转到登录页面
model.addAttribute(SsoConstants.REDIRECT_PARAM_NAME, redirectUrl);
return isMobile(request)? "/login_m.html" : "/login.html";
}
}

  

SSO单点登录实例的更多相关文章

  1. 基于CAS的SSO(单点登录)实例

    第一步 部署CAS-Server(服务端) 1.从CAS官方网站(http://developer.jasig.org/cas/)下载最新版本的CAS-Server(当前最新版本cas-server- ...

  2. CAS SSO单点登录实例

    1.因为是本地模拟sso环境,而sso的环境测试需要域名,所以需要虚拟几个域名出来,步骤如下: 2.进入目录C:\Windows\System32\drivers\etc 3.修改hosts文件 12 ...

  3. php实现SSO单点登录实例

    1.点击登录跳转到SSO登录页面并带上当前应用的callback地址2.登录成功后生成COOKIE并将COOKIE传给callback地址3.callback地址接收SSO的COOKIE并设置在当前域 ...

  4. SSO 基于CAS实现单点登录 实例解析(二)

    本文目录: 概述 演示环境 部署CAS-Server相关的Tomcat 部署CAS-Client相关的Tomcat 测试验证SSO 第一: 本demo在一个机器上实现(三个虚拟主机),来看SSO单点登 ...

  5. SSO单点登录学习总结(3)—— 基于CAS实现单点登录实例

    第一: 本demo在一个机器上实现(三个虚拟主机),来看SSO单点登录实例(我们可以布到多个机器上使用都是同一个道理的),一个服务器主机,和两个客户端虚拟主机 [html] view plaincop ...

  6. SpringCloud系列——SSO 单点登录

    前言 作为分布式项目,单点登录是必不可少的,文本基于之前的的博客(猛戳:SpringCloud系列——Zuul 动态路由,SpringBoot系列——Redis)记录Zuul配合Redis实现一个简单 ...

  7. SSO之CAS单点登录实例演示

    本文目录: 一.概述 二.演示环境 三.JDK安装配置 四.安全证书配置 五.部署CAS-Server相关的Tomcat 六.部署CAS-Client相关的Tomcat 七. 测试验证SSO 一.概述 ...

  8. SSO单点登录、跨域重定向、跨域设置Cookie、京东单点登录实例分析

    最近在研究SSO单点登录技术,其中有一种就是通过js的跨域设置cookie来达到单点登录目的的,下面就已京东商城为例来解释下跨域设置cookie的过程 涉及的关键知识点: 1.jquery ajax跨 ...

  9. [精华][推荐]CAS SSO 实现单点登录实例源码

    1.修改server.xml文件,如下: 注意: 这里使用的是https的认证方式,需要将这个配置放开,并做如下修改: <Connector port="8443" prot ...

随机推荐

  1. interface Part4(接口中的多态)

    使用接口实现多态 需要满足以下两个条件. 定义接口并使用类实现了接口中的成员. 创建接口的实例指向不同的实现类对象. 假设接口名称为 ITest,分别定义两个实现类来实现接口的成员,示例代码如下. i ...

  2. 基于【 责任链模式】二 || 网关zuul过滤器封装

    一.基于责任链模式封装网关拦截 上一篇文章中已经使用建造者模式对网关拦截进行封装,存在一个问题,在连接器build中,每一个拦截都要进行true判断,代码看起来冗余,下面使用责任链模式封装 1.基于责 ...

  3. Java 之 字节输入流 [InputStream]

    一.字节输入流 java.io.InputStream 抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中. 它定义了字节输入流的基本共性功能方法. 共性方法: public void c ...

  4. 读取普通java web项目下的WEB-INF目录下的配置文件(application.xml,xx.properties等配置文件)

    一.在Java web工程WEB-INF下创建weixin.properties属性文件 weixin.properties属性文件里内容如下: 二.创建PropertiesUtils.java测试类 ...

  5. Lwip与底层的接口

    Lwip有三套api,分别是: raw api:使用方法为使用回调函数,即先注册一个函数,当接受到数据之后调用这个函数.缺点是对于数据连续处理不好. Lwip api:把接收与处理放在一个线程里面.因 ...

  6. NTFS文件系统概述

    NTFS简介 NTFS是Windows NT家族1的限制级专用的文件系统2.Win95.Win98识别不了NTFS,只有支持NT内核的OS才能识别NTFS文件系统.当前,NTFS取代了老式的FAT文件 ...

  7. Python_算术运算符

    1.算术运算符 示例: >>> num1=7 >>> num2=3 >>> num1+num2 #+ 10 >>> num1-n ...

  8. Linux常用命令与详解

    在Linux系统中文件删除.创建.更改等操作都是通过一个个不同的命令来完成我们想要的操作,那么什么是命令呢? 凡是在字符操作界面中输入的能够完成特定操作和任务的字符串都可以称为命令.严格来说,命令通常 ...

  9. Nginx.conf配置文件默认配置块略解

    #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #erro ...

  10. C++中priority_queue的用法

    本来想自己写一写的,但看到这个随笔,感觉要写的东西跟这个差不多,就直接附上链接. 需要注意事项: rand()函数需要引入头文件#include<cstdlib>. 自定义类型,重载ope ...