我有一个角度应用程序使用的dotNetCore webapi项目。
我希望用户通过Twitter连接
然后用户填写其“电子邮件”
然后他将可以访问我的webApi。
对于一个mvc / razor网站,它可以正常工作,也是Asp.Net core 2 / VS2017中的基本模板
但是对于棱角怎么办?
身份库通过内部控制器支持最后阶段 / Identity / Account / ExternalLogin?ReturnUrl =%2F
var key = Encoding.ASCII.GetBytes(Configuration["Secret:JWT"]);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
services.AddAuthentication().AddTwitter(options =>
{
options.ConsumerKey = Configuration["Twitter:ConsumerKey"];
options.ConsumerSecret = Configuration["Twitter:ConsumerSecret"];
});
答案 0 :(得分:0)
我通过咨询AspNetCore存储库代码找到了实现方法: https://github.com/aspnet/AspNetCore/tree/master/src/Identity/samples/IdentitySample.Mvc/Controllers/AccountController.cs
https://github.com/aspnet/AspNetCore/tree/master/src/Mvc/benchmarkapps/BasicApi
我的控制器
[Authorize]
public class ConnectController : ControllerBase
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly SigningCredentials _credentials;
private readonly JwtBearerOptions _options;
private readonly UserManager<IdentityUser> _userManager;
public ConnectController(
UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager,
IOptionsSnapshot<JwtBearerOptions> options,
SigningCredentials credentials)
{
_userManager = userManager;
_signInManager = signInManager;
_options = options.Get(JwtBearerDefaults.AuthenticationScheme);
_credentials = credentials;
}
[HttpPost]
[HttpGet]
[AllowAnonymous]
[Route("connect/{provider}")]
public IActionResult ExternalLogin(string provider)
{
var normalizeProvider = provider.First().ToString().ToUpper() + provider.Substring(1).ToLower();
var properties = _signInManager.ConfigureExternalAuthenticationProperties(normalizeProvider, "");
properties.RedirectUri = Url.Action(nameof(ExternalLoginCallback));
return Challenge(properties, normalizeProvider);
}
[AllowAnonymous]
public async Task<IActionResult> ExternalLoginCallback()
{
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
return Unauthorized();
}
// Sign in the user with this external login provider if the user already has a login.
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
if (result.Succeeded)
{
// Update any authentication tokens if login succeeded
await _signInManager.UpdateExternalAuthenticationTokensAsync(info);
return Content(GetToken(info));
}
if (result.IsLockedOut)
{
return Unauthorized();
}
// If the user does not have an account, then ask the user to create an account.
return Ok(ActionRegisterModel.GetAction(Request.Cookies["identity.External"]));
}
// replay cookie identity.External
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Register([FromBody]RegisterModel registerModel)
{
// Get the information about the user from the external login provider
// how to use header and not cookie identity.External ??
//AuthenticateResult auth = await HttpContext.AuthenticateAsync(IdentityConstants.ExternalScheme);
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
return Unauthorized();
}
var user = new IdentityUser { UserName = registerModel.Email, Email = registerModel.Email };
var result = await _userManager.CreateAsync(user);
if (result.Succeeded)
{
result = await _userManager.AddLoginAsync(user, info);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
// Update any authentication tokens as well
await _signInManager.UpdateExternalAuthenticationTokensAsync(info);
return Content(GetToken(info));
}
}
return Unauthorized();
}
public string GetToken(ExternalLoginInfo info)
{
var identity = (ClaimsIdentity)info.Principal.Identity;
var handler = _options.SecurityTokenValidators.OfType<JwtSecurityTokenHandler>().First();
var securityToken = handler.CreateJwtSecurityToken(
issuer: _options.TokenValidationParameters.ValidIssuer,
audience: _options.TokenValidationParameters.ValidAudience,
signingCredentials: _credentials,
subject: identity);
var token = handler.WriteToken(securityToken);
return token;
}
}
并进入startup.cs
var rsa = new RSACryptoServiceProvider(2048);
var key = new RsaSecurityKey(rsa.ExportParameters(true));
services.AddSingleton(new SigningCredentials(key, SecurityAlgorithms.RsaSha256Signature));
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
//options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.TokenValidationParameters.IssuerSigningKey = key;
options.TokenValidationParameters.ValidAudience = "MyDomain";
options.TokenValidationParameters.ValidIssuer = "MyAPI";
});