C# 从Web Api获取完整的GenericPrincipal MVC
这一次,我正在尝试设置并获取前端用户的全部信息,但我不知道我做错了什么 我有两个独立的项目,第一个是Webapi项目,我用它来输入用户,然后给用户一个令牌C# 从Web Api获取完整的GenericPrincipal MVC,c#,asp.net,asp.net-mvc,asp.net-web-api,asp.net-web-api2,C#,Asp.net,Asp.net Mvc,Asp.net Web Api,Asp.net Web Api2,这一次,我正在尝试设置并获取前端用户的全部信息,但我不知道我做错了什么 我有两个独立的项目,第一个是Webapi项目,我用它来输入用户,然后给用户一个令牌 // GET api/Account/ExternalLogin [OverrideAuthentication] [HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)] [AllowAnonymous] [Route("ExternalL
// 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();
}
//获取api/Account/ExternalLogin
[覆盖认证]
[主机身份验证(DefaultAuthenticationTypes.ExternalCookie)]
[异名]
[路由(“外部登录”,Name=“外部登录”)]
公共异步任务GetExternalLogin(字符串提供程序,字符串错误=null)
{
if(错误!=null)
返回重定向(Url.Content(“~/”+“#error=“+Uri.EscapeDataString(error));
如果(!User.Identity.IsAuthenticated)
返回新的ChallengeResult(提供程序,此);
ExternalLoginData externalLogin=ExternalLoginData.FromIdentity(User.Identity作为索赔实体);
if(externalLogin==null)
返回InternalServerError();
if(externalLogin.LoginProvider!=提供程序)
{
Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
返回新的ChallengeResult(提供程序,此);
}
appjobseker user=await UserManager.FindAsync(新用户登录信息(externalLogin.LoginProvider,externalLogin.ProviderKey));
bool hasRegistered=user!=null;
如果(已注册)
{
Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
ClaimsIdentity oAuthIdentity=await UserManager.CreateIdentityAsync(用户,OAuthDefaults.AuthenticationType);
ClaimSideEntity cookieIdentity=await UserManager.CreateIdentityAsync(用户,CookieAuthenticationDefaults.AuthenticationType);
AuthenticationProperties=ApplicationAuthProvider.CreateProperties(user.UserName,user.Id);
身份验证.签名(属性、oAuthIdentity、cookieIdentity);
}
其他的
{
IEnumerable claims=externalLogin.GetClaims();
ClaimsIdentity identity=newclaimsidentity(声明,OAuthDefaults.AuthenticationType);
身份验证。签名(身份);
}
返回Ok();
}
客户端是一个MVC5项目,其中我有一个方法来postasyn身份验证,还有一个方法来创建AuthTicket,如下所示
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,
});
}
public异步任务AuthenticateAsync(字符串用户名、字符串密码)
{
使用(var client=new HttpClient())
{
var result=wait client.PostAsync(@)http://localhost:8060/Token“”,新格式UrlEncodedContent(新列表
{
新的KeyValuePair(@“授权类型”,“密码”),
新的KeyValuePair(@“userName”,userName),
新的KeyValuePair(@“password”,password)
}));
string json=wait result.Content.ReadAsStringAsync();
if(结果。IsSuccessStatusCode)
返回JsonConvert.DeserializeObject(json);
抛出新的ApiException(result.StatusCode,json);
}
}
私有void CreateTicket(SignInResult结果、SignInModel模型、字符串返回URL)
{
//让我们在MVC webapp中对用户进行身份验证。
//通过使用AccessToken,我们可以在MVC控制器中使用User.Identity.Name来进行API调用。
FormsAuthentication.SetAuthCookie(result.AccessToken、model.RememberMe);
//创建AuthenticationTicket以生成用于根据Web API进行身份验证的cookie。
//但在此之前,我们需要一个可以在Web API中进行身份验证的索赔实体。
索赔[]索赔=
{
新声明(ClaimTypes.Name,result.AccessToken),//Name是默认的名称声明类型,UserName是Web API中已知的名称声明类型。
新声明(ClaimTypes.Email,result.UserName),//如果要在Web API中使用User.Identity.GetUserId,则需要一个NameIdentifier声明。
};
//使用DefaultAuthenticationTypes.ApplicationOkie authenticationType生成新的ClaimsEntity。
//这也与我们在WebAPI中设置的内容相匹配。
AuthenticationTicket authTicket=新的AuthenticationTicket(新的索赔实体(索赔、DefaultAuthenticationTypes.ApplicationOkie)、新的AuthenticationProperties
{
ExpiresUtc=result.Expires,
IsPersistent=model.RememberMe,
IssuedUtc=结果。已发布,
RedirectUri=returnUrl,
});
//HttpContext.Response..User=principal;
//现在是生成cookie数据的时候了,它使用的代码与OWIN中CookieAuthenticationMiddleware类使用的代码相同。
字节[]userData=DataSerializers.Ticket.Serialize(authTicket);
//保护此用户数据并添加额外属性。这些属性必须与Web API中的相同!
字节[]protectedData=MachineKey.Protect(用户数据,新[]{“Microsoft.Owin.Security.Cookies.Cookie AuthenticationMiddleware”,DefaultAuthenticationTypes.ApplicationCookie,“v1”});
//base64对该数据进行编码。
string protectedText=textcodings.Base64Url.Encode(protectedData);
//现在,我们有了饼干。
Response.SetCookie(新的HttpCookie(“JobSeekerAuth”)
{
HttpOnly=true,
Expires=result.Expires.UtcDateTime,
值=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;
}
}
//POST:Account/SignIn
[HttpPost]
公共异步任务登录(SignInModel模型,字符串返回URL)
{
如果(!ModelState.IsValid)
返回视图(模型);
尝试
{
CreateTicket(等待WebApiService.Instance.authenticateSync(model.Email、model.Password)、model、returnUrl);
返回重定向到本地(returnUrl);
//return wait WebApiService.Instance.authenticateSync(model.Email,model.Password)!=null?重定向到本地(returnUrl):Redi
@if (HttpContext.Current.User.Identity.IsAuthenticated)
{
<li>@Html.ActionLink("Sign Out", "SignOut", "Account")</li>
}
else
{...
[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; }