AspNetCore WebApi / Angular соединяется с Twitter, затем создает токен JWT - PullRequest
0 голосов
/ 24 февраля 2019

У меня есть проект dotNetCore webapi, используемый угловым приложением.

Я хочу, чтобы пользователь подключился через Twitter

Затем пользователь завершает свою «электронную почту»

Затему него будет доступ к моему webApi.

Для сайта mvc / razor это работает без проблем, это также основной шаблон в Asp.Net core 2 / VS2017

Но для угловых какделать?

Последний этап поддерживается библиотекой Identity с внутренним контроллером / Identity / Account / ExternalLogin? ReturnUrl =% 2F

Into Startup.cs?

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"];
});

1 Ответ

0 голосов
/ 24 февраля 2019

Я нашел, как это сделать, сверившись с кодом репозитория 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";
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...