2015-05-16 51 views
3

這次我triying設置和獲取有關在前端用戶的全部信息,但我不知道whant我做錯了獲取完整的GenericPrincipal MVC從網絡API

我有兩個分開的項目第一個是Webapi項目,我正在使用它來爲用戶提供一個令牌。

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

問題是,我想使用的GenericPrincipal在Razor視圖二送的用戶id或用戶名來回回登錄的用戶,當我試圖這樣做它給我什麼MO再比這裏令牌

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

所以,我不知道如何讓這個目標 祝商祺!......

回答

0

我的身份驗證方法效果很好,因爲一旦我進入登錄方法這一個給我我的實體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中而不是成功 問候