2017-08-02 37 views
0

**編輯:如果任何人有任何線索我怎麼能更好地問或告知你們這個問題,請讓我知道。用戶聲稱似乎被取代沿管道

所以我正在創建自定義聲明並嘗試將它們添加到我的用戶。我在User.Identity中看到了這些聲明,之後我將它們添加到流水線中,但到達我的Global.asax時,User.Identity已經失去了我的所有聲明。我也認爲用戶在同一時間內從claimPrinciapl改爲GenericPrincipal。我不知道我是否理解這一點或解釋得很好。甚至不知道所有的代碼發佈,但我會發布一些下面。

這是我的用戶進行身份驗證,並創建cookie和聲明。注意:我一直在嘗試了很多東西所以這可能有一些奇怪的代碼:

private AuthenticationResponse AuthenticateUserByService(string userName, string password, bool rememberMe) 
    { 
     Authenticator auth = new Authenticator(AppInfo.AuthServiceAddress, AppInfo.ClientId, AppInfo.Secret); 
     AppInfo.rememberMe = rememberMe; 
     AuthenticationResponse response = auth.Authenticate(userName, password); 
     if (response.IsError) 
     { 
      // MessageBox.Show(response.ErrorDescription); 
      return null; 
     } 

     if (response.AppUser == null) 
     { 
      //MessageBox.Show("No error or user! Unknown reason."); 
      return null; 
     } 
     var cookieHelper = new Helpers.CookieHelper(); 
     //FormsAuthenticationTicket authtick = new FormsAuthenticationTicket(1, response.AppUser.Username, DateTime.Now, DateTime.Now.AddSeconds(response.AppUser.ExpiresIn *2), true, response.AppUser.RefreshToken); 
     var authtick = cookieHelper.CreateAuthTicket(response.AppUser, true); 

     var authCookie = cookieHelper.CreateAuthCookie(authtick); 
     Response.Cookies.Add(authCookie); 

     var tokenCookie = cookieHelper.CreateTokenCookie(response.AppUser, true); 
     Response.Cookies.Add(tokenCookie); 

     // If caching roles in userData field then extract 
     string[] roles = response.AppUser.Permissions.Select(x => x.PermissionName).ToArray(); // = authTicket.UserData.Split(new char[] { '|' }); 

     // Create the IIdentity instance 
     IIdentity id = new FormsIdentity(authtick); 

     var newIdent = new ClaimsIdentity(id); 

     foreach (var item in roles) 
     { 
      newIdent.AddClaim(new Claim(ClaimTypes.Role, item)); 
     } 
     ClaimsPrincipal cp = new ClaimsPrincipal(newIdent);   


     // Create the IPrinciple instance 
     IPrincipal principal = cp; //new GenericPrincipal(id, roles); 
     Thread.CurrentPrincipal = cp; 
     AppDomain.CurrentDomain.SetThreadPrincipal(cp); 
     // Set the context user 
     HttpContext.User = principal; 
     //IOwinContext context = Request.GetOwinContext(); 
     //var authManager = context.Authentication; 
     //authManager.SignIn(newIdent); 

     this.AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = true }, newIdent); 


     return response; 

在上面的代碼中,我可以看到我的用戶和他的要求之後我定的HttpContext.User中。

以下僅僅是我檢查出來的用戶,以確保它是成功的:

private AppUser AuthenticateUser(string userName, string password, bool rememberMe) 
    { 
     //bool userAuthenticated = false; 
     AuthenticationResponse userAuthenticated = null; 
     bool success = false; 
     try 
     { 
      userAuthenticated = AuthenticateUserByService(userName, password, rememberMe); 
      var c = User.Identity; 
      success = !userAuthenticated.IsError; 
     } 
     catch { } 
    } 

在一個點上由我設定C到用戶的時間消失的說法。

和我猜想這可能是下面這樣重要的是我創造我的餅乾及門票:

internal class CookieHelper 
{ 
    internal FormsAuthenticationTicket CreateAuthTicket(AppUser appUser, bool isPersistent) 
    { 
     return new FormsAuthenticationTicket(
      1, 
      appUser.Username, 
      DateTime.Now, 
      DateTime.Now.AddSeconds((appUser.ExpiresIn * 2)), 
      isPersistent, 
      appUser.RefreshToken == null ? "" : appUser.RefreshToken, 
      FormsAuthentication.FormsCookiePath); 
    } 

    internal HttpCookie CreateAuthCookie(FormsAuthenticationTicket authTicket) 
    { 
     // Encrypt the ticket. 
     string encAuthTicket = FormsAuthentication.Encrypt(authTicket); 

     // Create the cookie. 
     HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encAuthTicket); 
     authCookie.Expires = authTicket.Expiration; 

     return authCookie; 
    } 

    internal HttpCookie CreateTokenCookie(AppUser appUser, bool isPersistent) 
    { 

     // Create token ticket 
     FormsAuthenticationTicket tokenTicket = new FormsAuthenticationTicket(
      1, 
      appUser.Username, 
      DateTime.Now,     
      DateTime.Now.AddSeconds(appUser.ExpiresIn), 
      isPersistent, 
      appUser.AccessToken); 

     // Encrypt the ticket. 
     string encTokenTicket = FormsAuthentication.Encrypt(tokenTicket); 

     // Create the cookie. 
     HttpCookie tokenCookie = new HttpCookie("Mellon", encTokenTicket); 
     tokenCookie.Secure = false; 
     tokenCookie.Name = "Mellon"; 
     //tokenCookie.Path = Request.ApplicationPath; 
     tokenCookie.Expires = tokenTicket.Expiration; 

     return tokenCookie; 
    } 
} 

我覺得這樣的問題將需要問我得到的幫助正確的信息。我只是迷失了,在這一點上我的隧道視野正在殺死我。任何見解或暗示或在這一點上都會有所幫助。提前致謝。

更新

這是我檢查,如果cookie是仍然有效,並履行其是否仍然有效的刷新。

protected void Application_AuthenticateRequest(object sender, EventArgs e) 
    { 
     HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName]; 
     HttpCookie tokenCookie = Request.Cookies["Mellon"]; 

     if (authCookie == null) 
     { 
      FormsAuthentication.SignOut(); 
      HttpContext.Current.User = new GenericPrincipal(new GenericIdentity(string.Empty), null); 
      return; 
     } 

     // Extract the forms authentication cookie 
     FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value); 

     if (authTicket == null || authTicket.Expired) 
     { 
      FormsAuthentication.SignOut(); 
      HttpContext.Current.User = new GenericPrincipal(new GenericIdentity(string.Empty), null); 
      return; 
     } 

     // Extract the forms authentication cookie 
     //FormsAuthenticationTicket newAuthTicket; 

     if (tokenCookie == null) 
     { 
      RefreshCookies(authTicket); 
      return; 
     } 
     else 
     { 
      FormsAuthenticationTicket tokenTicket = FormsAuthentication.Decrypt(tokenCookie.Value); 

      // If the access token is stil good, then continue on. 
      if (tokenTicket.Expired) 
      { 
       RefreshCookies(authTicket); 
       return; 
      } 
     } 
     var tick = (FormsIdentity)HttpContext.Current.User.Identity; 
     if (tick == null) 
     { 
      FormsAuthentication.SignOut(); 
      HttpContext.Current.User = new GenericPrincipal(new GenericIdentity(string.Empty), null); 
      return; 
     } 

     if (authTicket.UserData != tick.Ticket.UserData) // .Ticket.UserData) 
     { 
      RefreshCookies(authTicket); 
     } 

    } 

基本上我的是我的AuthToken持有我刷新令牌和第二個cookie,持有我AccessToken。這些是在AuthenticateUserByService方法中創建的,該方法從我們的webapi獲取所有信息,並在response.AppUser中返回。所以我不能使用forms.setauthcookie,因爲它會覆蓋那裏已經存在的內容。

的怎麼回事圖片證明: Now you see them

Now you dont

+1

將用戶詳細信息添加到索賠的邏輯是哪裏? –

+0

我很抱歉,但是您的意思是? – Darkwingduck

+1

不用擔心,我會盡快發佈答案,但我會將其分解成更小的部分,並且將成爲可行的解決方案。消化所發佈的片段相當困難。 –

回答

1

正如我在我的評論說,這是相當艱難的消化已張貼的片斷,所以我會分解成較小的邏輯塊。

驗證服務調用client repository,並返回一個User

public class AuthenticationService 
{ 
    IUserRepository _userRepo; 

    public AuthenticationService() 
    { 
     _userRepo = new UserRepository(); 
    } 

    public User GetUser(string username, string password) 
    { 
     return _userRepo.FindByCredentials(username, password); 
    } 

    public User GetUserByUserName(string username) 
    { 
     return _userRepo.FindByUserName(username); 
    } 
} 

在我們需要與飛行前的請求驗證Global.asax

讓我們用一個Authentication Service Class開始。

 protected void Application_AuthenticateRequest(object sender, EventArgs e) 
     { 
      //Check the request for a cookie 
      var authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]; 

      if (authCookie != null) 
      { 
       //Decrypt the Auth Cookie vale 
       var ticket = FormsAuthentication.Decrypt(authCookie.Value); 

       //Instantiate Auth Service 
       var _authService = new AuthenticationService(); 

       //Get user by encrypted name stored in ticket 
       var user = _authService.GetUserByUserName(ticket.Name); 
       if (user != null) 
       { 
        // Create a ClaimsIdentity with all the claims for this user. 

        Claim emailClaim = new Claim("Email", (!string.IsNullOrWhiteSpace(user.Email)) ? user.Email: ""); 
        Claim AddressClaim = new Claim("Address", (!string.IsNullOrWhiteSpace(user.Address)) ? user.Address: ""); 
        Claim userNameClaim = new Claim(ClaimTypes.Name, (!string.IsNullOrWhiteSpace(user.Username)) ? user.Username : ""); 

        //Add claims to a collection of claims 
        List<Claim> claims = new List<Claim> 
        { 
         emailClaim , 
         AddressClaim , 
         userNameClaim 
        }; 

        //Create forms Identity 
        FormsIdentity formsIdentity = new FormsIdentity(ticket); 

        //Create Claims Identity 
        ClaimsIdentity claimsIdentity = new ClaimsIdentity(formsIdentity); 

        //Add Claims 
        claimsIdentity.AddClaims(claims); 

        //Create Claims Principal 
        ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(claimsIdentity); 

        //Assign principal to current user 
        HttpContext.Current.User = claimsPrincipal; 
       } 
      } 
     } 

登錄控制器:

 [HttpPost] 
     [AllowAnonymous] 
     public ActionResult Login(LoginModel model) 
     { 
      if (ModelState.IsValid) 
      { 
        var user = _authService.GetUser(model.UserName, model.password); 
        if (user != null) 
        { 
         FormsAuthentication.SetAuthCookie(model.UserName,model.RememberMe); 
         return Redirect(model.ReturnUrl);     } 
        } 
      } 

      ModelState.AddModelError("", "The user name or password provided is incorrect."); 
      return View(model); 

正如我已經說過,這是一個天真的嘗試,請考慮多一點保障,但是這是工作SLN我趕緊把和我一起可以訪問索賠。

看着你的代碼,感覺你只是缺少添加用戶的聲明。

+0

我打算將我的Application_AuthenticateRequest方法添加到原始文章中。你在這裏有什麼不會爲我正在努力完成的工作。我會看看是否可以更多地更新上面的原因。 – Darkwingduck

+1

請放心,也可以幫助從別人得到答案。 –

+0

是的,越多人問的越好,我就能解釋到底是什麼。我對這個問題的掌握不是很好,我的能力也很強。 – Darkwingduck

0

基本上發生了什麼是聲明被覆蓋在我的global.asax中。到目前爲止,我的修復一直是在我的global.asax中重建我的聲明。