.Net 单点登录(SSO)的原理与实现------ASP.Net Form认证

.Net 单点登录(SSO)的原理与实现——ASP.Net Form认证

一、使用Form认证

   说到认证,不得不提一下ASP.Net的Form认证模式,相信大家在开发B/S架构的系统时都有用到过,例如WebForm和MVC框架都可以使用Form认证模式,至于不知道Form认证的童鞋,在这里我们我们先介绍Form的使用,一步步慢慢剖析Form认证的原理,请大家耐心的阅读本博客。同时本博客以剖析原理为主,讲解技术为辅,也是为了方便大家理解和拓展思维。
  以大家常用的ASP.Net MVC架构为例,在VS中新建项目->选择ASP.Net Web 应用程序->选择MVC->确定后命名为SSO.Client1,这个Project假设为系统1,在项目上新建一个AccountController:

    public class AccountController : Controller
    {
        // GET: Account
        public ActionResult Index()
        {
            return View();
        }
    }

VS 默认帮我们建了一个Index方法,在View中我们也能看到一个Index视图,我们修改视图的内容:


@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div> 
        <p>我是系统1的登录界面</p>
        <button type="button">登录</button>
    </div>
</body>
</html>

这些操作的目的是为了新建一个超级简单的登录界面
然后我们打开Web.config,在system.web配置节中加入如下内容:

    <authentication mode="Forms">
      <forms loginUrl="~/Account/Index" timeout="2880" />
    </authentication>

然后我们在HomeController加上 [Authorize]属性,然后我们开始调试,发现系统直接跳转到了我们新建的登录页面上。
这里写图片描述
然后我们把登录的链接地址改为路由Account/Login

<a href="@Url.Action("Login", "Account")"> 登录</a>

然后我们在AccountController中新建Login方法

        public ActionResult Login()
        {
            FormsAuthentication.SetAuthCookie("123", false);
            return RedirectToAction("Index", "Home");
        }

然后我们做一个实验,开始调试,发现系统直接跳转到了路由Account/Login,这时即使我们手动在浏览器上把链接地址的路由改为Home/Index也不行,还是会跳转到路由Account/Login,然后我们点击登录发现系统跳转到了Home/Index,这时我们手动输入路由Home/Index,发现也可以访问!
我们在Home/Index页面中添加一个按钮:

    <div class="col-md-3">
        <button onclick="logout()">登出</button>
    </div>

在按钮事件中指定LogOut方法:

<script>
    function logout() {
        document.location = "@Url.Action("Logout", "Account")" + "?ReturnUrl=" + document.location;
    }
</script>

可以看到LogOut方法转到路由Account/Logout中,在AccountController的Logout方法中实现如下代码:

        /// <summary>
        /// 登出
        /// </summary>
        /// <returns></returns>
        public ActionResult Logout(string returnUrl)
        {
            FormsAuthentication.SignOut();
            HttpContext.Request.Cookies.Clear();
            return Redirect($"{LogOutUrl}?ReturnUrl={ returnUrl}");
        }

我们重复上面的步骤登录,登录完成后进入Home/Index路由,然后我们点击登出,再次访问Home/Index发现已经访问不了了,系统直接跳转到了登录页面!

到这里,我们已经简单的使用了Form认证!接下来我们要思考一下如下问题:

  • 为什么没点击登录的时候访问路由Home/Inde失败,而点击登录后能访问成功?
  • 为什么登录之后点击登出按钮后再次访问Home/Index路由会失败?
  • 这一切现象的原理是什么?(Form认证的原理是什么?)

接下来我为大家一一揭秘!

二、Form认证登录的原理

   我们回忆一下Form认证的使用。
首先,我们在Web.config文件中配置了如下配置节:

    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login" timeout="2880" />
    </authentication>

这个配置节指定了系统的认证方式为Form认证,并指定未认证时(未登录时)将路由跳转到Account/Login
然后,我们在HomeController上加上了Authorize扩展属性,我们F12进去看一下这个扩展属性有哪些方法,
这里写图片描述
能看到这个类里面有(只讲解与登录认证相关的三个方法):

  • OnAuthorization方法,该方法作用于登录认证之前,并触发认证;
  • AuthorizeCore方法,该方法是登录认证的主体,用于判断有没有登录的,返回值为bool,bool为true则表示已经登录;
  • HandleUnauthorizedRequest方法,该方法在认证失败时触发,也就是在AuthorizeCore返回False时被调用,用于捕获认证失败的请求;

那么,为什么加上Authorize扩展属性,访问路由会进入到上面的三个方法呢?
因为Authorize是一个拦截器,它拦截了Http请求,这是AOP的相关知识,在本文不做详解,大家想知道AOP的实现可自行百度


因此,这个扩展属性实现了Form认证逻辑,即判断有没有登录,所有加上Authorize扩展属性的路由都会被这个认证类所控制!因此Form认证通过了这中手段来控制我们想控制的受限内容!具体在代码里如何做的呢?
在我们的登录方法中,也就是我们点击登录后跳转到的路由Account/Login:

        public ActionResult Login()
        {
            FormsAuthentication.SetAuthCookie("123", false);
            return RedirectToAction("Index", "Home");
        }

这里实现登录的关键单在

FormsAuthentication.SetAuthCookie("123", false);

这句话实现了登录认证,将认证信息保存在Cookie中,因此在访问Home/Index路由中时触发登录认证机制,也就是AuthorizeCore,这时的认证模式读取Cookie,发现认证Cookie存在因此通过了认证,路由能正常访问,至于登出,我们在登出方法中使用了:

 FormsAuthentication.SignOut();

这个方法调用登出方法,清除Cookie后,再次访问Home/Index路由,触发AuthorizeCore方法发现Cookie不存在因此认证失败,大家可以手动清除Cookie刷新页面发现也会再次跳转到登录页,这就是Form认证的原理!

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值