存储 OAuth 配置文件信息
我发现 Web API 模板已损坏 - 默认实现依赖于最后一步中的 cookie,你可能不希望在 Rest API 中使用它。如果没有 cookie,RegisterExternal 中的 GetExternalLoginInfoAsync 将始终返回 null。我完全删除了 RegisterExternal,而是在 GetExternalLogin 中创建最终用户帐户 - 从 OAuth 提供程序返回时调用(在本例中为 Google):
[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);
}
ApplicationUser user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider,
externalLogin.ProviderKey));
bool hasRegistered = user != null;
if (hasRegistered)
{
Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,
OAuthDefaults.AuthenticationType);
ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager,
CookieAuthenticationDefaults.AuthenticationType);
AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);
}
else
{
var accessToken = Authentication.User.Claims.Where(c => c.Type.Equals("urn:google:accesstoken")).Select(c => c.Value).FirstOrDefault();
Uri apiRequestUri = new Uri("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + accessToken);
RegisterExternalBindingModel model = new RegisterExternalBindingModel();
using (var webClient = new System.Net.WebClient())
{
var json = webClient.DownloadString(apiRequestUri);
dynamic jsonResult = JsonConvert.DeserializeObject(json);
model.Email = jsonResult.email;
model.Picture = jsonResult.picture;
model.Family_name = jsonResult.family_name;
model.Given_name = jsonResult.given_name;
}
var appUser = new ApplicationUser
{
UserName = model.Email,
Email = model.Email,
ImageUrl = model.Picture,
FirstName = model.Given_name,
Surname = model.Family_name,
DateCreated = DateTime.Now
};
var loginInfo = await Authentication.GetExternalLoginInfoAsync();
IdentityResult result = await UserManager.CreateAsync(appUser);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
result = await UserManager.AddLoginAsync(appUser.Id, loginInfo.Login);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
ClaimsIdentity oAuthIdentity = await appUser.GenerateUserIdentityAsync(UserManager,
OAuthDefaults.AuthenticationType);
ClaimsIdentity cookieIdentity = await appUser.GenerateUserIdentityAsync(UserManager,
CookieAuthenticationDefaults.AuthenticationType);
AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(appUser.UserName);
Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);
}
return Ok();
}
这消除了客户端应用程序在收到外部访问令牌后执行不必要的 POST 请求的需要。