了解或想探索单点登录的朋友应该对单点登录有一个大致的了解,在这里我不在过多的阐述单点登录的概念。

单点登录说的通俗一点,就是一处登录(统一认证中心--Server),处处通行(Client)。

一、第一步我们先来探讨探讨SSO单点登录的过程

   1.当Client第一次登录时,查看自己有没有局部会话,没有的话,则重定向到统一认证中心进行进行登录操作

   2.登录成功后,Server会保存一个全局会话。并会产生一个token返回给Client

   3.这时又回到了Client,Client拿到Server返回的token并不是直接跳转到正确的页面。而是拿着这个token去Server校验这个token是否是Server产生的,校验通过了才进行跳转,同时生成一个局部会话

   4.当第二个Client登录时,同样也会先跳转到Server。然而此时不同的时,这是Server端已经有了一个全局的会话,此时直接重定向到Client,并带着Server端产生的token

二、上面已经阐述了单点登录的过程,接下来我们结合着代码详细的复现这一过程

  1.Client登录时,查看自己有没有局部会话,没有的话,则重定向到统一认证中心进行进行登录操作

     public override  void OnActionExecuting(ActionExecutingContext filterContext)
{
var request = filterContext.HttpContext.Request;
var response = filterContext.HttpContext.Response; string ReturnURL = request.Url.AbsoluteUri; //请求的路径
string Passport = System.Configuration.ConfigurationManager.AppSettings["Server"]; //Server端的路径
object isLogin = filterContext.HttpContext.Session["isLogin"]; //局部会话 if (isLogin != null) //有局部会话的时候直接放行
{
return;
}
else
{
//这一部分是校验Server返回的token,第一次登录的时候没有token,会直接跳过这部分
}

       //执行这步操作
filterContext.Result = new RedirectResult(string.Format("{0}/Login/CheckLogin?redirectUrl={1}", Passport,ReturnURL)); //第一次登录时没有局部会话,要跳到Server端进行认证
return; }

   2.跳转到Server端进行校验

        public ActionResult CheckLogin(string redirectUrl) {
object token = Session["token"];
if (token==null)
{
string url = "http://localhost:52666/Login/Login?redirectUrl="+redirectUrl; //跳转到登录界面,并携着跳转过来的路径,以方便后续操作
return Redirect(url);
}
else
{
return Redirect(redirectUrl+ "?tokenId=" + token.ToString());
}
}
public ActionResult Login(string redirectUrl)
{
ViewBag.Url = redirectUrl;
return View(); //返回登录界面的视图
}

   3.对Server登录界面输入的用户和密码进行校验,登录成功就重定向到Client端

        [HttpPost]
public ActionResult Login(string userName, string password,string RetrunURL) { if (userName=="admin"&&password=="admin") //登录成功
{
Session["token"] = Guid.NewGuid().ToString(); //生成一个全局会话
MockDatabase.T_Token.Add(Session["token"].ToString()); //将产生的token写到数据库
return Redirect(RetrunURL + "?tokenId=" + Session["token"].ToString()); //重定向到Client端并携带着这个token
}
else
{
string url = "http://localhost:52666/Login/Login?redirectUrl=" + RetrunURL; //否则继续返回到登录界面
return Redirect(url);
}
}

   4.这里又跳转到Client的过滤器中,进行对token的校验

  public override  void OnActionExecuting(ActionExecutingContext filterContext)
{
var request = filterContext.HttpContext.Request;
var response = filterContext.HttpContext.Response; string ReturnURL = request.Url.AbsoluteUri; //请求的路径
string Passport = System.Configuration.ConfigurationManager.AppSettings["Server"]; //Server端的路径
object isLogin = filterContext.HttpContext.Session["isLogin"]; //局部会话 if (isLogin != null) //有局部会话的时候直接放行
{
return;
}
else
{
          //执行这步操作
//从Server端跳转到这里,对token进行校验
string token = request["tokenId"];
if (!string.IsNullOrWhiteSpace(token))
{
using (HttpClient http = new HttpClient())
{
HttpContent httpContent = new StringContent(token);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
httpContent.Headers.ContentType.CharSet = "utf-8";
//验证Tokend是否有效
HttpClient httpClient = new HttpClient(); string url = Passport + "Login/Verify?token="+token; //带着token请求到Server端的Verify方法进行校验
HttpResponseMessage res = httpClient.GetAsync(url).Result;
string result = res.Content.ReadAsStringAsync().Result;
if (res.StatusCode.ToString()=="OK")
{
if (result == "True")
{
filterContext.HttpContext.Session["isLogin"] = true;
return; //通过校验就放行
}
}
}
}
} filterContext.Result = new RedirectResult(string.Format("{0}/Login/CheckLogin?redirectUrl={1}", Passport,ReturnURL)); //第一次登录时没有局部会话,要跳到Server端进行认证
return; }

    5.Server端的Verify方法对token进行校验(校验token是否由Server产生的)

      public string Verify(string token) {
return MockDatabase.T_Token.Contains(token).ToString(); //判断数据库中存入的token,有没有包含传递过来的token
}

    6、当第二个Client登录时,Server端已经有了全局会话,则直接跳转回去

       public ActionResult CheckLogin(string redirectUrl) {
object token = Session["token"];
if (token==null)
{
string url = "http://localhost:52666/Login/Login?redirectUrl="+redirectUrl; //跳转到登录界面,并携着跳转过来的路径,以方便后续操作
return Redirect(url);
}
else
{
         //走这段逻辑
return Redirect(redirectUrl+ "?tokenId=" + token.ToString()); //当第二个Client登录时,此时已经有了一个全局会话。会直接跳转过去并带上token
}
}

三、上面一步一步的操作不是那么完整,这里给出Server端和Client端过滤器的完整代码,希望能对研究这块东西的小伙伴有所帮助

   1.Client端过滤器的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web;
using System.Web.Mvc; namespace ClientO.Filter
{
public class AuthAttribute : ActionFilterAttribute
{
public static List<string> Tokens = new List<string>();
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var request = filterContext.HttpContext.Request;
var response = filterContext.HttpContext.Response; string ReturnURL = request.Url.AbsoluteUri; //请求的路径
string Passport = System.Configuration.ConfigurationManager.AppSettings["Server"]; //Server端的路径
object isLogin = filterContext.HttpContext.Session["isLogin"]; //局部会话 if (isLogin != null) //有局部会话的时候直接放行
{
return;
}
else
{
//从Server端跳转到这里,对token进行校验
string token = request["tokenId"];
if (!string.IsNullOrWhiteSpace(token))
{
using (HttpClient http = new HttpClient())
{
HttpContent httpContent = new StringContent(token);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
httpContent.Headers.ContentType.CharSet = "utf-8";
//验证Tokend是否有效
HttpClient httpClient = new HttpClient(); string url = Passport + "Login/Verify?token="+token; //带着token请求到Server端的Verify方法进行校验
HttpResponseMessage res = httpClient.GetAsync(url).Result;
string result = res.Content.ReadAsStringAsync().Result;
if (res.StatusCode.ToString()=="OK")
{
if (result == "True")
{
filterContext.HttpContext.Session["isLogin"] = true;
return; //通过校验就放行
}
}
}
}
} filterContext.Result = new RedirectResult(string.Format("{0}/Login/CheckLogin?redirectUrl={1}", Passport,ReturnURL)); //第一次登录时没有局部会话,要跳到Server端进行认证
return; }
}
}

    2.Server端Control中的代码

using Server.Filter;
using Server.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using System.Web.Security; namespace Server.Controllers
{
public class LoginController : Controller
{
// GET: Login public ActionResult Index()
{
return View();
} public ActionResult CheckLogin(string redirectUrl) {
object token = Session["token"];
if (token==null)
{
string url = "http://localhost:52666/Login/Login?redirectUrl="+redirectUrl; //跳转到登录界面,并携着跳转过来的路径,以方便后续操作
return Redirect(url);
}
else
{
return Redirect(redirectUrl+ "?tokenId=" + token.ToString()); //当第二个Client登录时,此时已经有了一个全局会话。会直接跳转过去并带上token
}
}
public ActionResult Login(string redirectUrl)
{
ViewBag.Url = redirectUrl;
return View(); //返回登录界面的视图
} [HttpPost]
public ActionResult Login(string userName, string password,string RetrunURL) { if (userName=="admin"&&password=="admin") //登录成功
{
Session["token"] = Guid.NewGuid().ToString(); //生成一个全局会话
MockDatabase.T_Token.Add(Session["token"].ToString()); //将产生的token写到数据库
return Redirect(RetrunURL + "?tokenId=" + Session["token"].ToString()); //重定向到Client端并携带着这个token
}
else
{
string url = "http://localhost:52666/Login/Login?redirectUrl=" + RetrunURL; //否则继续返回到登录界面
return Redirect(url);
}
}
     public string Verify(string token) {
return MockDatabase.T_Token.Contains(token).ToString(); //判断数据库中存入的token,有没有包含传递过来的token
} }
}

    

基于C#实现的单点登录的更多相关文章

  1. .NET基于Redis缓存实现单点登录SSO的解决方案[转]

    一.基本概念 最近公司的多个业务系统要统一整合使用同一个登录,这就是我们耳熟能详的单点登录,现在就NET基于Redis缓存实现单点登录做一个简单的分享. 单点登录(Single Sign On),简称 ...

  2. .NET基于Redis缓存实现单点登录SSO的解决方案

    一.基本概念 最近公司的多个业务系统要统一整合使用同一个登录,这就是我们耳熟能详的单点登录,现在就NET基于Redis缓存实现单点登录做一个简单的分享. 单点登录(Single Sign On),简称 ...

  3. 前后端分离基于Oauth2的SSO单点登录怎样做?

    一.说明 单点登录顾名思义就是在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统,免除多次登录的烦恼:本文主要介绍跨域间的 前后端分离 项目怎样实现单点登录,并且与 非前后端分离 的差 ...

  4. 如何基于Security实现OIDC单点登录?

    一.说明 本文主要是给大家介绍 OIDC 的核心概念以及如何通过对 Spring Security 的授权码模式进行扩展来实现 OIDC 的单点登录. OIDC 是 OpenID Connect 的简 ...

  5. SSO 基于Cookie+fliter实现单点登录(SSO):工作原理

    SSO的概念: 单点登录SSO(Single Sign-On)是身份管理中的一部分. SSO的一种较为通俗的定义是:SSO是指訪问同一server不同应用中的受保护资源的同一用户,仅仅须要登录一次,即 ...

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

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

  7. SSO 基于Cookie+fliter实现单点登录 实例解析(一)

    接上文,SSO的理论讲解,接下来实践实践! 1.使用Cookie解决单点登录 技术点: 1.设置Cookie的路径为setPath("/").即Tomcat的目录下都有效 2.设置 ...

  8. Spring Security基于Oauth2的SSO单点登录怎样做?一个注解搞定

    一.说明 单点登录顾名思义就是在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统,免除多次登录的烦恼.本文主要介绍 同域 和 跨域 两种不同场景单点登录的实现原理,并使用 Spring ...

  9. 基于cookie的SSO单点登录系统

    利用COOKIE实现单点登录功能 近期公司要求帮一个项目实现单点登录功能,在综合考量下决定采用cookie实现,大概的流程如下图所:

  10. 基于JWT机制的单点登录

    使用JWT实现单点登录时,需要注意token时效性.token是保存在客户端的令牌数据,如果永久有效,则有被劫持的可能.token在设计的时候,可以考虑一次性有效或一段时间内有效.如果设置有效时长,则 ...

随机推荐

  1. docker gitlab-runner的安装

    参考: Run GitLab Runner in a container 前面介绍了gitlab-ce的安装,下面是gitlab-runner的安装,同样还是安装docker版本. 1.下载 dock ...

  2. NBU磁带库报错代码

    Linux驱动报错"Sense Key"和"ASC and ASCQ"含义 1.Sense Keys Definitions 0x0 No sense 0x1 ...

  3. wpf学习资料链接(做记录)

    1.wpf快速入门系列:https://www.cnblogs.com/zhili/tag/WPF/

  4. @TableName(mybatis-plus中的注解)

    @TableName 描述:表名注解 属性 类型 必须指定 默认值 描述 value String 否 "" 表名 schema String 否 "" sch ...

  5. 洛谷 P1167 刷题

    洛谷 P1167 刷题 洛谷传送门 题目描述 noip临近了,小A却发现他已经不会写题了.好在现在离竞赛还有一段时间,小A决定从现在开始夜以继日地刷题.也就是说小A废寝忘食,一天二十四小时地刷题. 今 ...

  6. apt-get update失败处理:*** Error in `appstreamcli': double free or corruption (fasttop): 0x00000000015c4bf0 ***

    好像只要卸载一个东西就可以了(至少我的是这样): sudo apt-get purge libappstream3 再重新执行update命令, sudo apt-get update 参考链接: 1 ...

  7. 几个golang 静态资源嵌入包

    静态资源嵌入二进制文件中,可以方便我们的软件分发(只需要简单的二进制文件就可以了),目前大部分golang 的 web 应用都是使用类似的方法. 以下是收集到的一些常见方案 github.com/go ...

  8. 图像处理pillow模块

    pillow模块: -->基本的图像处理模块 Pip install pillow from PIL import Image #1.读取图片 im = Image.open('/test.jp ...

  9. java登录图形界面

    编写程序,利用JtextField和JpasswordField分别接收用户输入的用户名和密码,并对用户输入的密码进行检验.对于每个用户名有三次密码输入机会. package beizi; impor ...

  10. JVM系列之一:JVM架构

    1.简介 Java平台可分为两部分,即Java虚拟机(Java virtual machine,JVM)和Java API类库. JVM是Java Virtual Machine(Java虚拟机)的缩 ...