【问题标题】:Get Full GenericPrincipal MVC From Web Api从 Web Api 获取完整的 GenericPrincipal MVC
【发布时间】:2015-07-28 11:59:54
【问题描述】:

这次我试图在 FrontSide 设置并获取有关用户的全部信息,但我不知道我做错了什么

我有两个独立的项目,第一个是 Webapi 项目,我用它来 SingIn,然后用户给出一个令牌。

// GET api/Account/ExternalLogin
    [OverrideAuthentication]
    [HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)]
    [AllowAnonymous]
    [Route("ExternalLogin", Name = "ExternalLogin")]
    public async Task<IHttpActionResult> GetExternalLogin(string provider, string error = null)
    {
        if (error != null)
            return Redirect(Url.Content("~/") + "#error=" + Uri.EscapeDataString(error));
        if (!User.Identity.IsAuthenticated)
            return new ChallengeResult(provider, this);

        ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);
        if (externalLogin == null)
            return InternalServerError();
        if (externalLogin.LoginProvider != provider)
        {
            Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
            return new ChallengeResult(provider, this);
        }
        AppJobSeeker user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider, externalLogin.ProviderKey));
        bool hasRegistered = user != null;
        if (hasRegistered)
        {
            Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
            ClaimsIdentity oAuthIdentity = await UserManager.CreateIdentityAsync(user, OAuthDefaults.AuthenticationType);
            ClaimsIdentity cookieIdentity = await UserManager.CreateIdentityAsync(user, CookieAuthenticationDefaults.AuthenticationType);
            AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName, user.Id);
            Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);
        }
        else
        {
            IEnumerable<Claim> claims = externalLogin.GetClaims();
            ClaimsIdentity identity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType);
            Authentication.SignIn(identity);
        }
        return Ok();
    }

客户端是一个 MVC 5 项目,我有一种方法来 postasyn 身份验证,另一种方法可以像这样创建 AuthTickect...

public async Task<T> AuthenticateAsync<T>(string userName, string password)
    {
        using (var client = new HttpClient())
        {
            var result = await client.PostAsync((@"http://localhost:8060/Token"), new FormUrlEncodedContent(new List<KeyValuePair<string, string>>
            {
                new KeyValuePair<string, string>(@"grant_type", @"password"),
                new KeyValuePair<string, string>(@"userName", userName), 
                new KeyValuePair<string, string>(@"password", password)
            }));
            string json = await result.Content.ReadAsStringAsync();
            if (result.IsSuccessStatusCode)
                return JsonConvert.DeserializeObject<T>(json);
            throw new ApiException(result.StatusCode, json);
        }
    }


private void CreateTicket(SignInResult result, SignInModel model, string returnUrl)
    {
        //Let's keep the user authenticated in the MVC webapp.
        //By using the AccessToken, we can use User.Identity.Name in the MVC controllers to make API calls.
        FormsAuthentication.SetAuthCookie(result.AccessToken, model.RememberMe);

        //Create an AuthenticationTicket to generate a cookie used to authenticate against Web API.
        //But before we can do that, we need a ClaimsIdentity that can be authenticated in Web API.
        Claim[] claims =
        {
            new Claim(ClaimTypes.Name, result.AccessToken), //Name is the default name claim type, and UserName is the one known also in Web API.
            new Claim(ClaimTypes.Email, result.UserName), //If you want to use User.Identity.GetUserId in Web API, you need a NameIdentifier claim.
        };
        //Generate a new ClaimsIdentity, using the DefaultAuthenticationTypes.ApplicationCookie authenticationType.
        //This also matches what we've set up in Web API.
        AuthenticationTicket authTicket = new AuthenticationTicket(new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie), new AuthenticationProperties
        {
            ExpiresUtc = result.Expires,
            IsPersistent = model.RememberMe,
            IssuedUtc = result.Issued,
            RedirectUri = returnUrl,
        });
        //HttpContext.Response..User = principal;

        //And now it's time to generate the cookie data. This is using the same code that is being used by the CookieAuthenticationMiddleware class in OWIN.
        byte[] userData = DataSerializers.Ticket.Serialize(authTicket);

        //Protect this user data and add the extra properties. These need to be the same as in Web API!
        byte[] protectedData = MachineKey.Protect(userData, new[] { "Microsoft.Owin.Security.Cookies.CookieAuthenticationMiddleware", DefaultAuthenticationTypes.ApplicationCookie, "v1" });

        //base64-encode this data.
        string protectedText = TextEncodings.Base64Url.Encode(protectedData);

        //And now, we have the cookie.
        Response.SetCookie(new HttpCookie("JobSeekerAuth")
        {
            HttpOnly = true,
            Expires = result.Expires.UtcDateTime,
            Value = protectedText,
        });
    }

我的登录方法看起来像

// POST: Account/SignIn
    [HttpPost]
    public async Task<ActionResult> Login(SignInModel model, string returnUrl)
    {
        if (!ModelState.IsValid)
            return View(model);
        try
        {
            CreateTicket(await WebApiService.Instance.AuthenticateAsync<SignInResult>(model.Email, model.Password), model, returnUrl);
            return RedirectToLocal(returnUrl);
            //return await WebApiService.Instance.AuthenticateAsync<SignInResult>(model.Email, model.Password) != null ? RedirectToLocal(returnUrl) : RedirectToLocal(returnUrl);
        }
        catch (ApiException ex)
        {
            //No 200 OK result, what went wrong?
            HandleBadRequest(ex);
            if (!ModelState.IsValid)
                return View(model);
            throw;
        }
    }

问题是我想在 Razor 视图中使用 GenericPrincipal 两个获取登录用户的 userId 或用户名,当我尝试这样做时,它给我的只是这里的令牌

    @if (HttpContext.Current.User.Identity.IsAuthenticated)
{
    <li>@Html.ActionLink("Sign Out", "SignOut", "Account")</li>
}
else
{...

所以,我不知道如何实现这个目标 最好的问候!...

【问题讨论】:

    标签: c# asp.net asp.net-mvc asp.net-web-api asp.net-web-api2


    【解决方案1】:

    我的身份验证方法运行良好,因为一旦我进入登录方法,这个方法就会给我我的实体 SignInResult,看起来就像设置了所有值

            [JsonProperty("access_token")]
        public string AccessToken { get; set; }
    
        //Included to show all the available properties, but unused in this sample
        [JsonProperty("token_type")]
        public string TokenType { get; set; }
    
        [JsonProperty("expires_in")]
        public uint ExpiresIn { get; set; }
    
        [JsonProperty("userName")]
        public string UserName { get; set; }
    
        [JsonProperty(".issued")]
        public DateTimeOffset Issued { get; set; }
    
        [JsonProperty(".expires")]
        public DateTimeOffset Expires { get; set; }
    
        [JsonProperty("userId")]
        public string UserId { get; set; }
    

    我也尝试设置为 Thread.CurrentPrincipal 但没有成功 最好的问候

    【讨论】:

      猜你喜欢
      • 2018-11-03
      • 2021-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-24
      • 1970-01-01
      • 2017-07-09
      • 1970-01-01
      相关资源
      最近更新 更多