1

我正在创建 Web 应用程序,包括 API 和 OAuth 授权代码流用户授权。所以我有AccountController

[HttpGet("/connect/auth")]
public IActionResult Authorize(CancellationToken cancellationToken)
{
    var request = HttpContext.GetOpenIdConnectRequest();

    var application = _applicationRepository.Table
            .FirstOrDefault(x => x.ClientId == request.ClientId);

    if (application == null)
    {
        ModelState.AddModelError(string.Empty, "Application not recognized");
        return BadRequest(ModelState);
    }

    var parameters = request.GetParameters()
            .ToDictionary(parameter => parameter.Key, parameter => parameter.Value.ToString());

    return View(new AuthorizeModel
    {
        ApplicationName = application.DisplayName,
        Parameters = parameters,
        Scope = request.Scope
    });
}

[HttpPost("/connect/auth/accept")]
[ValidateAntiForgeryToken]
public IActionResult AuthorizeAccept(CancellationToken cancellationToken)
{
    var request = HttpContext.GetOpenIdConnectRequest();

    var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme);
        identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, User.FindFirstValue(ClaimTypes.NameIdentifier)));

    var application = _applicationRepository.Table
        .FirstOrDefault(x => x.ClientId == request.ClientId);

    if (application == null)
    {
        ModelState.AddModelError(string.Empty, "Application not recognized");
        return BadRequest(ModelState);
    }

    var ticket = new AuthenticationTicket(
            new ClaimsPrincipal(identity),
            new AuthenticationProperties(),
            OpenIdConnectServerDefaults.AuthenticationScheme);

    ticket.SetScopes(
        /* openid: */ OpenIdConnectConstants.Scopes.OpenId,
        /* email: */ OpenIdConnectConstants.Scopes.Email,
        /* profile: */ OpenIdConnectConstants.Scopes.Profile);
    ticket.SetResources("resource_server");

    return SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme);
}

还有我的Startup班级配置

// services
services.AddIdentity<ApplicationUser, IdentityRole>(setup =>
    {
        setup.Password.RequireDigit = false;
        setup.Password.RequireLowercase = false;
        setup.Password.RequireNonAlphanumeric = false;
        setup.Password.RequireUppercase = false;
        setup.Password.RequiredLength = 6;
    })
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

services.AddOpenIddict<ApplicationDbContext>()
    .AddMvcBinders()
    .EnableAuthorizationEndpoint("/connect/auth")
    .EnableTokenEndpoint("/connect/token")
    .AllowAuthorizationCodeFlow()
    .DisableHttpsRequirement()
    .UseJsonWebTokens()
    .AddEphemeralSigningKey();

services.AddMvc();

// app configuration
app.UseIdentity();

app.UseOAuthValidation();

app.ApplicationServices.GetRequiredService<IOptions<OpenIddictOptions>>().Value.Provider = new AuthorizationProvider();
app.UseOpenIddict();

// Used to make OpenId connect request available for auth accept route
public class AuthorizationProvider : OpenIddictProvider<OpenIddictApplication, OpenIddictAuthorization, OpenIddictScope, OpenIddictToken>
{
    public override Task MatchEndpoint(MatchEndpointContext context)
    {
        if (context.Options.AuthorizationEndpointPath.HasValue && context.Request.Path.StartsWithSegments(context.Options.AuthorizationEndpointPath))
            context.MatchAuthorizationEndpoint();

        return Task.FromResult(0);
    }
}

所以我可以登录并获取访问令牌,但是当我使用令牌对具有[Authorize]属性的控制器进行 API 调用时,它不会将我识别为授权用户。我还注意到表中记录的ApplicationId值为空。怎么了?AuthorizationIdOpenIddictTokens

4

1 回答 1

1

您不能将 JWT 访问令牌与验证中间件一起使用(app.UseOAuthValidation())因为它仅适用于默认格式。

删除.UseJsonWebTokens()以使用默认访问令牌格式或使用 JWT 不记名中间件 ( app.UseJwtBearerAuthentication(...)),它应该可以工作。

于 2016-12-08T11:43:46.213 回答