近来工作无事,想做个SSO, 之前做过一个项目用到SSO,自己也没有看明白是个什么东西。现在正好有时间,所以想研究下。

先是从网上看到了SSO的思路:

三个站点:SiteA,SiteB,SiteMain

1想到重写个ActionResult,于是就有了CustomRedirectResult(其实这种方式挺不好的, 不过也想试试看)

public class CustomRedirectResult:ActionResult
{
public override void ExecuteResult(ControllerContext context)
{
if (context.HttpContext.Session["Token"] == null)//if siteA doesn't have token,redirect user to siteMain to get token
{
string url = context.HttpContext.Request.Url.AbsoluteUri;
if (context.HttpContext.Request.QueryString["Token"] == null)
{
url= GetTokenURL();
}
context.HttpContext.Response.Redirect(url);
}
else //if siteA has token,direct user to the right requested page
{
context.HttpContext.Response.Redirect(context.HttpContext.Request.Url.AbsoluteUri + "UserInfo/IndexUserInfo");
}
}
}

2 siteMain 里完成用户登录并返回到siteA

public void  ReturnUserInfo()
{
string backurl = Request.Form["backurl"];
string token =GetToken(Request .Form ["Name"],Request.Form ["Password"]);
backurl = Server.UrlDecode(backurl);
backurl = backurl.Replace("$Token$", token);
HttpContext.Response.Redirect(backurl);//backurl="http://localhost:45625/UserInfo/IndexUserInfo",mvc 中要跳转到此路径时 要用方法HttpContext.Response.Redirect(backurl)直接跳转; }

3 siteA通过如下方法来接收返回回来的Token

public ActionResult IndexUserInfo(String token)
{
Session["Token"] = token;
Account.AccountSoapClient account = new AccountSoapClient();//利用webservice来取得用户信息
SiteA.Account .User user = account.GetUserByToken(token) ;
Session["UserName"] = user.Name;
       CustomIdentity identity = new CustomIdentity("Admin");
CustomPrincipal principal = new CustomPrincipal(identity, "admin");
       HttpContext.Current.User = principal;
return View("IndexUserInfo", user);
}

然后我又增加了一个action,想看看是不是登录后,一些需要认证的action 能顺利访问到,如下:

[Authorize]
public ActionResult GoToDesk()
{
string name = HttpContext.User.Identity.Name;
return View("GoToDesk","",name );
}

一运行到GoToDesk就提示我没有权限。原来HttpContext.User在下一次请求已经变成了空,也就是说他只在一次请求的过程中有值。于是想在Global.asax文件的 Application_BeginRequest里再重新给httpcontext.current.user赋值,如下

 protected void Application_BeginRequest(object sender, EventArgs e)
{ CustomIdentity identity = new CustomIdentity("Admin");//Admin is user name
CustomPrincipal principal = new CustomPrincipal(identity, "admin");//admin is role name
HttpContext.Current.User = principal;
//HttpContext.Current.Request.Headers.Add("UserName", "Admin");//该写法在mvc平台下不支持,在webform下支持
}

问题出现了,user name 从什么地方获取呢,现在是写死成Admin了。除了用cookie以后还能有别的方法吗?

 同时让我疑惑的是HttpContext.User只在一次请求下有值,那属性[Authorize]不就把所以之后的请求都给屏蔽在外边了吗?一定是我哪一块弄错了,望高人看到后指点一二。先在此谢过。

在网上搜索mvc sso的过程中看到了dotNetOpenAuth,然后写了一把,最终还是遇到了上述的问题,现在被block住了,希望有人来解救。

最后发现,原来如此:

//建立表单验证票据
FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket(, "testContextUser",
DateTime.Now, DateTime.Now.AddMinutes(), true, "管理员,会员", "/"); //使用webcongfi中定义的方式,加密序列化票据为字符串
string HashTicket = FormsAuthentication.Encrypt(Ticket); //将加密后的票据转化成cookie
HttpCookie UserCookie = new HttpCookie(FormsAuthentication.FormsCookieName, HashTicket);//FormsAuthentication.FormsCookieName的值为“.ASPXAUTH” //添加到客户端cookie
Context.Response.Cookies.Add(UserCookie);

貌似httpcontext.current.user的值来自己于FormsAuthentication.FormsCookieName,这样只放到cookie里,那再次请求页面是httpcontex.current.user就不会为空了。

只是role信息需要在每次请求时重新赋一下值

 protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (HttpContext.Current.User !=null)
{
FormsIdentity _Identity = (FormsIdentity)HttpContext.Current.User.Identity;
string[] Roles = _Identity.Ticket.UserData.Split(','); //将角色字符串,即login.aspx.cs中的“管理员,会员”,变成数组
HttpContext.Current.User = new GenericPrincipal(_Identity, Roles); //将带有角色的信息,重新生成一个GenericPrincipal赋值给User,
}
if (Request.Headers["user"] != null)
{ } }

更多关于formsAuthentication的请看:

http://www.cnblogs.com/wangjq/archive/2011/03/08/1977032.html

MVC实现SSO的更多相关文章

  1. C# 单点登录 MVC

    实现sso系统的主要难点: 1:不能直接访问数据库,有安全隐患,而且还容易乱套. 2:多个系统需要进行单点登录,逻辑需要严谨,能支持N多系统.而不只是少数几个系统. 3:代码不能过于复杂,需要简洁,灵 ...

  2. ASP.NET Core 2.0使用Cookie认证实现SSO单点登录

    之前写了一个使用ASP.NET MVC实现SSO登录的Demo,https://github.com/bidianqing/SSO.Sample,这个Demo是基于.NET Framework,.NE ...

  3. SSO集成方案[随笔]

    看这个方案之前,先说明下为什么要加入SSO,以防对大家产生不好的影响.我们产品使用传统winform+db服务+Db存储方式开发,一群老菜帮子开发,以传统的datatble做数据传递,很多年了未有变化 ...

  4. NET Core 2.0使用Cookie认证实现SSO单点登录

    NET Core 2.0使用Cookie认证实现SSO单点登录 之前写了一个使用ASP.NET MVC实现SSO登录的Demo,https://github.com/bidianqing/SSO.Sa ...

  5. js模版引擎handlebars.js实用教程

    js模版引擎handlebars.js实用教程 阅读本文需要了解基本的Handlebars.js概念,本文并不是Handlebars.js基础教程,而是注重于实际应用,为读者阐述使用过程中可能会遇到的 ...

  6. JEECG 集成KiSSO单点登录实现统一身份认证

    JEECG 集成KiSSO单点登录实现统一身份认证 JEECG 如何为其他第三方系统实现统一身份认证服务,实现单点登录? 第三方系统如何对接呢? 今天为大家揭开这层面纱,让大家了解实质,使用它更快速的 ...

  7. 开源项目之kisso

    kisso开源项目:https://gitee.com/baomidou/kisso 一.简介 kisso  =  cookie sso 基于 Cookie 的 SSO 中间件,它是一把快速开发 ja ...

  8. .Net Core微服务化ABP之六——处理Authentication

    上篇中我们已经可以实现sso,并且为各个服务集成sso认证.本篇处理权限系统的角色问题,权限系统分两层,第一层为整体系统角色权限,区分app用户.后台用户.网站用户的接口权限,第二层为业务系统权限,对 ...

  9. MVC SSO登陆 的麻烦事~

    前段时间用MVC + Redis 做session搞了个简单的单点登录Web站.真是日了狗的问题多. 今天正好睡不着,做个备忘笔记>_< 实现方法很简单,无非就是从重载个Controlle ...

随机推荐

  1. 【原】cookie小结

    前记:前段时间搞一个活动,开发的时间被严重压缩,忙到飞起,以致于都没怎么写文章了,内疚. 2月份参加了一场面试,有一些关于cookie的问题回答的不是很好,所以这篇文章我们来对cooKie做一个探讨和 ...

  2. 队列工厂之(MSMQ)

    最近vs2017神器正式版发布让人很是激动,vs2017支持了很多语言的开发,从前端-后端-底层的支持,堪称是工具中的神器:netcore我喜爱的架构之一也得到了大力的宣传,应群友的邀请将在队列工厂( ...

  3. Hibernate二级缓存原理

    缓存:缓存是什么,解决什么问题? 位于速度相差较大的两种硬件/软件之间的,用于协调两者数据传输速度差异的结构,均可称之为缓存Cache.缓存目的:让数据更接近于应用程序,协调速度不匹配,使访问速度更快 ...

  4. 3407: [Usaco2009 Oct]Bessie's Weight Problem 贝茜的体重问题

    3407: [Usaco2009 Oct]Bessie's Weight Problem 贝茜的体重问题 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit:  ...

  5. .进程&线程(&java.lang.Thread)详解

    一.进程与线程 进程 我们在进行操作电脑的时候,通常会打开浏览器,通讯工具等应用程序,这个时候CPU通过作业调度在内存中就会分配一些空间让它们处于宏观上的运行状态(处于可以被CPU执行的状态),而这部 ...

  6. 在Chrome中安装PostMan用来测试SpringBoot程序

    1. 首先下载一个PostMan的插件,Postman_v4.1.3.crx 下载下来为这种类型的文件. 2. 在Chrome中输入chrome://extensions/ 这个,打开Chrome的扩 ...

  7. BFS-基础简单的算法

    前言 有时候,当你并不了解很多高级算法的时候,搜索不失为一种解决问题的好方法,而且很多高级算法有或多或少的会用到搜索或者搜索的思想.可见,搜索是一个基础并且必须要掌握的算法. 在这篇文章中,会对BFS ...

  8. 原生ajax 和jquery ajax 个人总结

                   AJAX:即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术. 通过在后台 ...

  9. C#实现不影响当前线程情况下间隔一定的时间执行一段代码

    大家知道C#间隔一定时间去执行一段代码,常用的有 1. Thread.Sleep(多少毫秒); 2. 使用Timer控件间隔一定的时间,设置执行一次 以上两种方法,实现起来不难,弊端在于会阻塞当前线程 ...

  10. 新人报道~cnblogs

    我的名字:杨先生 我的英文名:Allen 和你们一样,是一名程序猿,专业技能  C#.前端小块.