欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

.net單點(diǎn)登錄設(shè)計(jì)的示例分析-創(chuàng)新互聯(lián)

這篇文章將為大家詳細(xì)講解有關(guān).net單點(diǎn)登錄設(shè)計(jì)的示例分析,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

我們一直強(qiáng)調(diào)成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作對(duì)于企業(yè)的重要性,如果您也覺得重要,那么就需要我們慎重對(duì)待,選擇一個(gè)安全靠譜的網(wǎng)站建設(shè)公司,企業(yè)網(wǎng)站我們建議是要么不做,要么就做好,讓網(wǎng)站能真正成為企業(yè)發(fā)展過程中的有力推手。專業(yè)的建站公司不一定是大公司,創(chuàng)新互聯(lián)建站作為專業(yè)的網(wǎng)絡(luò)公司選擇我們就是放心。

名稱定義

為了方便說明先說明幾個(gè)文中出現(xiàn)的名詞的含義:

P站:統(tǒng)一登錄授權(quán)驗(yàn)證中心,demo中 域名是www.passport.com:801

A站:處于不同域名下的測試網(wǎng)站,demo中 域名是www.a.com:802

B站:處于不同域名下的測試網(wǎng)站,demo中 域名是www.b.com:803

Token:用戶訪問P站的秘鑰


Ticket:用來保存用戶信息的加密字符串


單點(diǎn)登錄

訪問A站需要登陸的就跳轉(zhuǎn)P站中進(jìn)行登陸,P站登陸之后跳轉(zhuǎn)回至A站,用戶再次訪問B站需要登陸的頁面,用戶不需要進(jìn)行登陸操作就可以正常訪問。

實(shí)現(xiàn)思路

未登錄用戶訪問A站,首先會(huì)重定向跳轉(zhuǎn)至P站授權(quán)中心,P站首先通過檢測Cookie來判斷當(dāng)前不是處于登陸狀態(tài),就跳轉(zhuǎn)至登陸頁面進(jìn)行登陸操作,登陸成功之后把用戶信息加密ticket附在A的請(qǐng)求地址上返回,A站通過解密ticket來獲取用戶信息,解密成功并存進(jìn)Session中(這樣用戶在A中就處于登陸狀態(tài)了),訪問通過;當(dāng)用戶再次訪問B站的時(shí)候,對(duì)于B站來說,用戶是處于未登錄狀態(tài),則同樣會(huì)重定向跳轉(zhuǎn)至P站授權(quán)中心,P站檢測Cookie,判斷當(dāng)前用戶處于登陸狀態(tài),就把當(dāng)前用戶信息加密成ticket附在B的請(qǐng)求地址上返回,后面的操作就和A站處理一樣;這樣都登陸之后再次訪問A或者B,A和B中Session中都存儲(chǔ)了用戶信息,就不會(huì)再次請(qǐng)求P站了。


簡單關(guān)系圖
.net單點(diǎn)登錄設(shè)計(jì)的示例分析


泳道流程圖.net單點(diǎn)登錄設(shè)計(jì)的示例分析


主要邏輯說明

A站主要邏輯


用戶首先訪問A站,A站中會(huì)生成Token,并存入Cache中。Token是A訪問P的鑰匙,P在回調(diào)給A的時(shí)候需要攜帶這個(gè)Token。A請(qǐng)求P,P驗(yàn)證Token,P回調(diào)A,A檢測Token是否是發(fā)送出去的Token,驗(yàn)證之后Token即失效,防止Token被再次使用。


Token的生成是通過取時(shí)間戳的不同字段進(jìn)行MD5加密生成,當(dāng)然這里可以再加個(gè)鹽進(jìn)行防偽。


/// <summary>
    /// 生成秘鑰
    /// </summary>
    /// <param name="timestamp"></param>
    /// <returns></returns>
    public static string CreateToken(DateTime timestamp)
    {
      StringBuilder securityKey = new StringBuilder(MD5Encypt(timestamp.ToString("yyyy")));
      securityKey.Append(MD5Encypt(timestamp.ToString("MM")));
      securityKey.Append(MD5Encypt(timestamp.ToString("dd")));
      securityKey.Append(MD5Encypt(timestamp.ToString("HH")));
      securityKey.Append(MD5Encypt(timestamp.ToString("mm")));
      securityKey.Append(MD5Encypt(timestamp.ToString("ss")));
      return MD5Encypt(securityKey.ToString());
    }

P回調(diào)A的時(shí)候進(jìn)行,A中對(duì)Token進(jìn)行校驗(yàn),校驗(yàn)不成功則請(qǐng)求P站統(tǒng)一授權(quán)驗(yàn)證。


/// <summary>
  /// 授權(quán)枚舉
  /// </summary>
  public enum AuthCodeEnum
  {
    Public = 1,
    Login = 2
  }

  /// <summary>
  /// 授權(quán)過濾器
  /// </summary>
  public class AuthAttribute : ActionFilterAttribute
  {
    /// <summary> 
    /// 權(quán)限代碼 
    /// </summary> 
    public AuthCodeEnum Code { get; set; }

    /// <summary> 
    /// 驗(yàn)證權(quán)限
    /// </summary> 
    /// <param name="filterContext"></param> 
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
      var request = filterContext.HttpContext.Request;
      var session = filterContext.HttpContext.Session;
      //如果存在身份信息 
      if (Common.CurrentUser == null)
      {
        if (Code == AuthCodeEnum.Public)
        {
          return;
        }
        string reqToken = request["Token"];
        string ticket = request["Ticket"];
        Cache cache = HttpContext.Current.Cache;
        //沒有獲取到Token或者Token驗(yàn)證不通過或者沒有取到從P回調(diào)的ticket 都進(jìn)行再次請(qǐng)求P
        TokenModel tokenModel= cache.Get(ConstantHelper.TOKEN_KEY)==null?null:(TokenModel)cache.Get(ConstantHelper.TOKEN_KEY);
        if (string.IsNullOrEmpty(reqToken) || tokenModel == null || tokenModel.Token!= reqToken ||
          string.IsNullOrEmpty(ticket))
        {
          DateTime timestamp = DateTime.Now;
          string returnUrl = request.Url.AbsoluteUri;
          tokenModel = new TokenModel
          {
            TimeStamp = timestamp,
            Token = AuthernUtil.CreateToken(timestamp)
          };
          //Token加入緩存中,設(shè)計(jì)過期時(shí)間為20分鐘
          cache.Add(ConstantHelper.TOKEN_KEY, tokenModel, null, DateTime.Now.AddMinutes(20),Cache.NoSlidingExpiration,CacheItemPriority.Default, null);
          filterContext.Result = new ContentResult
          {
            Content = GetAuthernScript(AuthernUtil.GetAutherUrl(tokenModel.Token, timestamp), returnUrl)
          };
          return;
        }
        LoginService service = new LoginService();
        var userinfo = service.GetUserInfo(ticket);
        session[ConstantHelper.USER_SESSION_KEY] = userinfo;
        //驗(yàn)證通過,cache中去掉Token,保證每個(gè)token只能使用一次
        cache.Remove(ConstantHelper.TOKEN_KEY);
      }
    }

    /// <summary>
    /// 生成跳轉(zhuǎn)腳本
    /// </summary>
    /// <param name="authernUrl">統(tǒng)一授權(quán)地址</param>
    /// <param name="returnUrl">回調(diào)地址</param>
    /// <returns></returns>
    private string GetAuthernScript(string authernUrl, string returnUrl)
    {
      StringBuilder sbScript = new StringBuilder();
      sbScript.Append("<script type='text/javascript'>");
      sbScript.AppendFormat("window.location.href='{0}&returnUrl=' + encodeURIComponent('{1}');", authernUrl, returnUrl);
      sbScript.Append("</script>");
      return sbScript.ToString();
    }
  }

代碼說明:這里為了方便設(shè)置Token的過期時(shí)間,所以使用Cache來存取Token,設(shè)定Token的失效時(shí)間為兩分鐘,當(dāng)驗(yàn)證成功則從cache中移除Token。

調(diào)取過濾器


[Auth(Code = AuthCodeEnum.Login)]
     public ActionResult Index()
     {
       return View();
    }

P站主要邏輯


P站收到授權(quán)請(qǐng)求,P站首先通過Coookie來判斷是否登陸,未登錄則跳轉(zhuǎn)至登陸頁面進(jìn)行登陸操作。


/// <summary>
    /// 授權(quán)登陸驗(yàn)證
    /// </summary>
    /// <returns></returns>
    [HttpPost]
    public ActionResult PassportVertify()
    {
      var cookie=Request.Cookies[ConstantHelper.USER_COOKIE_KEY];
      if (cookie == null ||string.IsNullOrEmpty(cookie.ToString()))
      {
        return RedirectToAction("Login", new { ReturnUrl = Request["ReturnUrl"] ,Token= Request["Token"] });
      }
      string userinfo = cookie.ToString();
      var success= passportservice.AuthernVertify(Request["Token"], Convert.ToDateTime(Request["TimeStamp"]));
      if (!success)
      {
        return RedirectToAction("Login", new { ReturnUrl = Request["ReturnUrl"], Token = Request["Token"] });
      }
      return Redirect(passportservice.GetReturnUrl(userinfo, Request["Token"],Request["ReturnUrl"]));
    }

已登陸則驗(yàn)證Token


/// <summary>
    /// 驗(yàn)證令牌
    /// </summary>
    /// <param name="token">令牌</param>
    /// <param name="timestamp">時(shí)間戳</param>
    /// <returns></returns>
    public bool AuthernVertify(string token,DateTime timestamp)
    {
      return AuthernUtil.CreateToken(timestamp) == token;
    }

測試說明

1、修改host


127.0.0.1 www.passport.com


127.0.0.1 www.a.com


127.0.0.1 www.b.com

2、部署IIS


P www.passport.com:801

A www.a.com:802

B www.b.com:803

3、測試賬號(hào)和webconfig


<add key="PassportCenterUrl" value="http://www.passport.com:801"/>

用戶名:admin  密碼:123

關(guān)于.net單點(diǎn)登錄設(shè)計(jì)的示例分析就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

新聞標(biāo)題:.net單點(diǎn)登錄設(shè)計(jì)的示例分析-創(chuàng)新互聯(lián)
地址分享:http://www.chinadenli.net/article20/iicjo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設(shè)計(jì)公司域名注冊手機(jī)網(wǎng)站建設(shè)用戶體驗(yàn)定制網(wǎng)站網(wǎng)站策劃

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)