You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用OpenIddict集成Microsoft外部登录时回调报invalid_client错误

问题描述

使用OpenIddict编写认证服务,支持本地账号和Microsoft账号生成令牌。在Azure上授权成功,但重定向到回调时,OpenIddict抛出invalid_client错误。相关配置及代码如下:

Startup.cs 配置

// Register the OpenIddict server components.
.AddServer(options =>
{
    options
        //.AllowClientCredentialsFlow()
        .AllowAuthorizationCodeFlow()
         .RequireProofKeyForCodeExchange()
        .AllowRefreshTokenFlow()//.AllowImplicitFlow()
        .AllowPasswordFlow();

    options
        .SetTokenEndpointUris("/connect/token")
        .SetAuthorizationEndpointUris("/connect/authorize")
        .SetIntrospectionEndpointUris("/connect/introspect");

    options.AddEncryptionCertificate(config["Certificates:EncryptionCertificate"]);

    // Register the signing credentials.
    options.AddSigningCertificate(config["Certificates:SigningCertificate"]);

    // Register scopes (permissions)
    options.RegisterScopes("api");

    options.SetAccessTokenLifetime(TimeSpan.FromMinutes(15));
    options.SetRefreshTokenLifetime(TimeSpan.FromMinutes(60));

    // Register the ASP.NET Core host and configure the ASP.NET Core-specific options.
    options
        .UseAspNetCore()
        .EnableTokenEndpointPassthrough()
        .EnableAuthorizationEndpointPassthrough();
})
.AddClient(options=> 
{
    options.AddDevelopmentEncryptionCertificate();
    options.AddDevelopmentSigningCertificate();
    options.AllowAuthorizationCodeFlow();
    options.UseAspNetCore().EnableRedirectionEndpointPassthrough();
    options.UseWebProviders()
        .AddMicrosoft(options=> {
            options.SetClientId("xxxxx");
            options.SetClientSecret("xxxx");
            options.SetRedirectUri("connect/callback/microsoft");
            
        });
});

AccountController 挑战逻辑

[HttpGet]
[AllowAnonymous]
public IActionResult Login(string returnUrl = null, string provider="")
{
    if (string.Equals(provider,"microsoft", StringComparison.OrdinalIgnoreCase))
    {
        return new ChallengeResult(properties: null, authenticationSchemes: new[] { Providers.Microsoft });
    }
}

AuthorizationController 回调定义

[HttpGet("~/callback/github")]
[HttpPost("~/callback/github")]
[AllowAnonymous]
public async Task<IActionResult> CallBackGitHub(CancellationToken cancellationToken)
{
    // 回调逻辑
}

疑问:在Azure应用注册页面找不到添加client_id的入口,请问如何传递OpenIddict中已配置的client_id?或者是否可以在执行回调函数时跳过client_id检查?


解决方案

1. 修正回调端点不匹配问题

你配置的Microsoft回调URI是connect/callback/microsoft,但实际定义的回调方法是针对GitHub的~/callback/github,这会导致回调请求无法正确匹配处理方法,直接修改回调方法的路由为对应Microsoft的路径:

[HttpGet("~/connect/callback/microsoft")]
[HttpPost("~/connect/callback/microsoft")]
[AllowAnonymous]
public async Task<IActionResult> CallBackMicrosoft(CancellationToken cancellationToken)
{
    // 处理Microsoft回调逻辑
    var result = await HttpContext.AuthenticateAsync(OpenIddictClientAspNetCoreDefaults.AuthenticationScheme);
    // 后续生成令牌等操作
}

2. 正确传递client_id到授权流程

发起Microsoft登录挑战时,需要将OpenIddict的客户端ID等信息通过AuthenticationProperties传递,而不是传入null。修改Login方法:

[HttpGet]
[AllowAnonymous]
public IActionResult Login(string returnUrl = null, string provider = "")
{
    if (string.Equals(provider, "microsoft", StringComparison.OrdinalIgnoreCase))
    {
        var properties = new AuthenticationProperties
        {
            RedirectUri = Url.Action(nameof(CallBackMicrosoft)),
            Items =
            {
                ["OpenIddict.Client:ClientId"] = "xxxxx", // 这里填你在OpenIddict Client中配置的ClientId
                ["OpenIddict.Client:Scope"] = "api",
                ["OpenIddict.Client:ReturnUri"] = returnUrl
            }
        };
        return new ChallengeResult(Providers.Microsoft, properties);
    }
    // 本地账号登录逻辑
}

3. Azure应用注册的ClientId说明

Azure应用注册的应用程序(客户端)ID就是你在OpenIddict中配置的SetClientId("xxxxx")的值,这个ID在Azure应用注册的"概述"页面就能找到,不需要额外添加,只要确保OpenIddict配置的ClientId和Azure上的完全一致即可。

4. 关于跳过client_id检查

不建议跳过client_id检查,这会严重破坏认证流程的安全性,导致恶意客户端可以冒充合法客户端获取令牌。如果确实有特殊需求,需要通过自定义OpenIddict的验证逻辑实现,但强烈不推荐这么做。


内容的提问来源于stack exchange,提问作者Binki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 00:11:29