SSO单点登录实例
单点登录流程图

系统登陆拦截器
//
// 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单点登录实例的更多相关文章
- 基于CAS的SSO(单点登录)实例
第一步 部署CAS-Server(服务端) 1.从CAS官方网站(http://developer.jasig.org/cas/)下载最新版本的CAS-Server(当前最新版本cas-server- ...
- CAS SSO单点登录实例
1.因为是本地模拟sso环境,而sso的环境测试需要域名,所以需要虚拟几个域名出来,步骤如下: 2.进入目录C:\Windows\System32\drivers\etc 3.修改hosts文件 12 ...
- php实现SSO单点登录实例
1.点击登录跳转到SSO登录页面并带上当前应用的callback地址2.登录成功后生成COOKIE并将COOKIE传给callback地址3.callback地址接收SSO的COOKIE并设置在当前域 ...
- SSO 基于CAS实现单点登录 实例解析(二)
本文目录: 概述 演示环境 部署CAS-Server相关的Tomcat 部署CAS-Client相关的Tomcat 测试验证SSO 第一: 本demo在一个机器上实现(三个虚拟主机),来看SSO单点登 ...
- SSO单点登录学习总结(3)—— 基于CAS实现单点登录实例
第一: 本demo在一个机器上实现(三个虚拟主机),来看SSO单点登录实例(我们可以布到多个机器上使用都是同一个道理的),一个服务器主机,和两个客户端虚拟主机 [html] view plaincop ...
- SpringCloud系列——SSO 单点登录
前言 作为分布式项目,单点登录是必不可少的,文本基于之前的的博客(猛戳:SpringCloud系列——Zuul 动态路由,SpringBoot系列——Redis)记录Zuul配合Redis实现一个简单 ...
- SSO之CAS单点登录实例演示
本文目录: 一.概述 二.演示环境 三.JDK安装配置 四.安全证书配置 五.部署CAS-Server相关的Tomcat 六.部署CAS-Client相关的Tomcat 七. 测试验证SSO 一.概述 ...
- SSO单点登录、跨域重定向、跨域设置Cookie、京东单点登录实例分析
最近在研究SSO单点登录技术,其中有一种就是通过js的跨域设置cookie来达到单点登录目的的,下面就已京东商城为例来解释下跨域设置cookie的过程 涉及的关键知识点: 1.jquery ajax跨 ...
- [精华][推荐]CAS SSO 实现单点登录实例源码
1.修改server.xml文件,如下: 注意: 这里使用的是https的认证方式,需要将这个配置放开,并做如下修改: <Connector port="8443" prot ...
随机推荐
- 基于【 bug解决】一 || mysql的ONLY_FULL_GROUP_BY导致的sql语句错误
一.Mysql错误: In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated ...
- K2 BPM_规范内部供应链流程,提高企业整体绩效_工作流流程管理
方案背景 随着企业竞争的加剧.顾客需求的多样化以及市场变化的不确定因素增多,企业与企业间的竞争已经逐步转变为供应链与供应链间的竞争.企业只有在内部各业务流程有机统一的状态下,再与外部企业进行融合与协作 ...
- win10 下的YOLO v3 的编译与使用
部署环境:win10 +CUDA 10.0 + vs2017 + opencv 3.4.0 代码版本是 https://github.com/AlexeyAB/darknet 1.初始准备 (1)下 ...
- Linux中关于dns配置的小记
一. 如上图 我当时的网卡配置文件里是静态模式,然后DNS1=114.114.114.114. 就是纳闷,这是为什么 随后,我又是将网卡配置文件,修改为DNS1=114.114.114.113. 重启 ...
- 笔记一下debian8升级到debian9遇到的几个坑
由于debian8不再维护了,出于安全需要,参照官方的方法,在线升级到debian9,结果遇到了好多坑,虽然没死人,但也够惨了 坑1.升级后,多占了很多空间,莫明奇妙的把 / 分区占的满满的,由于之前 ...
- Bootstrap学习地址
第一步:https://www.runoob.com/bootstrap/bootstrap-tutorial.html //菜鸟教程 第二步:https://v3.bootcss.com/gett ...
- 运输层6——TCP可靠传输的实现
目录 1. 以字节为单位的滑动窗口 2. 超时重传时间的选择 写在前面:本文章是针对<计算机网络第七版>的学习笔记 运输层1--运输层协议概述 运输层2--用户数据报协议UDP 运输层3- ...
- java 从上至下打印二叉树
从上往下打印二叉树题目描述: 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 输入: 输入可能包含多个测试样例. 对于每个测试案例,输入的第一行一个整数n(1<=n<=1000, ...
- master-worker常驻型程序代码修改哪些需要重启master或者worker
之前在yii的项目里用redis作为消息队列,现在很多任务需要延迟需求,于是把之前redis的消息队列替换成了rabbitmq 于是使用yii的yii2-queue这个组件 但是由于提供的yii qu ...
- Linq 中 Join 的用法
Linq中连接主要有组连接.内连接.左外连接.交叉连接四种.各个用法如下. 注:本文内容主要来自<Linq实战>,本例中用到的对象请见文章底部. 1. 组连接 组连接是与分组查询是一样的. ...