• MVC实现SSO


    近来工作无事,想做个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(1, "testContextUser", 
    DateTime.Now, DateTime.Now.AddMinutes(30), 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

  • 相关阅读:
    oc结构
    iOS分类
    iOS协议
    缓存无底洞现象
    数据库备份,恢复
    PHP邮件发送库:Swiftmailer
    PHP分页组件:Paginator
    PHP验证码类
    PHP日期和时间处理组件-Carbon
    composer的一些操作
  • 原文地址:https://www.cnblogs.com/Gift/p/3595706.html
Copyright © 2020-2023  润新知