C# 用户声明似乎在管道的某个地方被取代

C# 用户声明似乎在管道的某个地方被取代,c#,asp.net-mvc,cookies,claims-based-identity,C#,Asp.net Mvc,Cookies,Claims Based Identity,**编辑:如果任何人有任何线索,我可以更好地询问或通知你们关于这个问题,请让我知道 因此,我正在创建自定义声明并尝试将它们添加到我的用户中。我在添加后立即在User.Identity中看到声明,并在管道中稍微向下移动,但当它到达my Global.asax时,User.Identity已丢失除一项声明之外的所有声明。我还认为,在同一时间内,用户正在从ClaimsPrincipal变为GenericPrincipal。我不知道我是否理解或解释得很好。甚至不知道所有的代码发布,但我会在下面发布一些

**编辑:如果任何人有任何线索,我可以更好地询问或通知你们关于这个问题,请让我知道

因此,我正在创建自定义声明并尝试将它们添加到我的用户中。我在添加后立即在User.Identity中看到声明,并在管道中稍微向下移动,但当它到达my Global.asax时,User.Identity已丢失除一项声明之外的所有声明。我还认为,在同一时间内,用户正在从ClaimsPrincipal变为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设置为用户时,声明一度消失了

我想这可能很重要,所以下面是我创建cookie和票据的地方:

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,因为这将覆盖其中已有的内容

正在发生的事情的图像证明:


正如我在评论中所说,要消化您发布的代码片段相当困难,因此我将分解为更小的逻辑块

让我们从一个
身份验证服务类开始:

身份验证服务调用
客户端存储库
,并返回
用户

 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
中,我们需要通过飞行前请求进行身份验证

      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;
                }
            }
        }

正如我所说的,这是一个天真的尝试,请考虑多一点安全性,但这是工作SLN,我很快就放在一起,我可以访问索赔。


查看您的代码后,感觉您只是缺少添加用户声明。

基本上发生的是,声明在my global.asax中被覆盖。到目前为止,我的解决方案是在我的global.asax中重建我的索赔

向声明中添加用户详细信息的逻辑在哪里?很抱歉,但你的意思是什么?不用担心,我会很快发布答案,但我会将其分解为更小的部分,这将是一个有效的解决方案。很难理解所贴的片段。现在我明白你的意思了,因为某种原因,它没有第一次点击。让我试试,我很快会给你回复。你在哪里能解决这个问题?我将把我的应用程序\u AuthenticateRequest方法添加到我的原始帖子中。你在这里所拥有的对我正在努力实现的目标不太管用。我会看看我是否能在上面更新更多关于原因的信息。请放心,这也可能有助于从其他人那里得到答案。是的,问的人越多,我就能更好地解释发生了什么。我对这个问题的理解不是很好,而且我的解释能力也很差。
        [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);