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 ...
随机推荐
- Java8新特性 - 方法引用与构造器引用
方法引用 若Lambda体中的内容有方法已经实现了,我们可以使用"方法应用",可以理解为方法引用是Lambda表达式的另外一种表现形式. 使用操作符"::"将方 ...
- Python-demo(抖音)
# -*- coding:utf-8 -*- from mitmproxy import ctx import json import requests import time import os p ...
- 转载:centos安装gitlab详解
原文地址:http://blog.csdn.net/jiangtao_st/article/details/73612298 一, 服务器快速搭建gitlab方法 可以参考gitlab中文社区 的教程 ...
- 浅谈javascript中变量作用域和内存(1)
先理解两个概念:基本类型和引用类型的值 1.基本类型和引用类型的值 (1)定义: 基本类型:指简单的数据段,比如按值访问的js五种基本数据类型undefined.null.boolean.number ...
- synchronize与lock
1. synchronize的作用 synchronize是java最原始的同步关键字,通过对方法或者代码块进行加锁实现对临界区域的保护.线程每次进去同步方法或者代码块都需要申请锁,如果锁被占用则会等 ...
- 网络调试助手的使用 调试TCP,UDP
网络调试助手是集TCP/UDP服务端客户端一体的网络调试工具,可以帮助网络应用设计.开发.测试人员检查所开发的网络应用软硬件的数据收发状况,提高开发的速度,是TCP/UDP应用开发助手. 集成TCP/ ...
- javascript_07-break 和 continue
break 和 continue break 立刻退出循环 continue 立即退出当前循环,但退出循环后会从循环的顶部继续执行 //求 200-300 之间的所有的偶数的和,用 continue ...
- 【问题】root账号的UID和GID永远是0吗?
参考:Does the root account always have UID/GID 0? 这实际上是2个问题 Does the superuser account always have uid ...
- C++——overloading
参考 C++——overloading principle analysis operator overloading C语言中,对一个东西进行操作一定要涉及到一个函数,对于自定义类型,为了实现其四则 ...
- 【OF框架】使用IDbContextTransaction在框架中对多个实体进行事务操作
准备 引用框架,按照规范建立数据库表及对应实体. 一.事务操作 关键代码 示例代码如下: //插入数据,使用数据库事务,不支持多连接. var dbContext = IoCHelper.Resolv ...