登录后身份验证服务器出现404错误(停留在signin-oidc页面)

24
我按照Identity Server 4文档在本地机器上设置了一个示例服务器。我的问题是,在登录后,应用程序停留在“signin-oidc”页面,日志显示404错误。我完全按照说明进行操作,甚至删除了所有内容并重新开始。因此,当前的设置是一个基本的IdSvr4项目(is4inmem)和一个新的ASPNetCore MVC应用程序,根据文档进行设置。
我唯一做的更改是将所有URL更改为HTTPS并使用appsettings.json文件而不是Config类。由于我没有做任何实质性的更改,我已经无计可施了。
我的MVC日志如下:
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/2 GET https://localhost:44377/Home/Claims
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      Authorization failed.
info: Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler[12]
      AuthenticationScheme: oidc was challenged.
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 559.8895ms 200 text/html;charset=UTF-8
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/2 POST https://localhost:44377/signin-oidc application/x-www-form-urlencoded 547
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 3.2205ms 404

主IdSvr4项目的日志看起来像这样

[00:26:01 Debug] IdentityServer4.Validation.AuthorizeRequestValidator
Start authorize request protocol validation

[00:26:01 Debug] IdentityServer4.Stores.ValidatingClientStore
client configuration validation for client mvc succeeded.

[00:26:01 Debug] IdentityServer4.Validation.AuthorizeRequestValidator
Checking for PKCE parameters

[00:26:01 Debug] IdentityServer4.Validation.AuthorizeRequestValidator
Calling into custom validator: IdentityServer4.Validation.DefaultCustomAuthorizeRequestValidator

[00:26:01 Debug] IdentityServer4.Endpoints.AuthorizeCallbackEndpoint
ValidatedAuthorizeRequest
{"ClientId": "mvc", "ClientName": "MVC Client", "RedirectUri": "https://localhost:44377/signin-oidc", "AllowedRedirectUris": ["https://localhost:44377/signin-oidc"], "SubjectId": "88421113", "ResponseType": "code", "ResponseMode": "form_post", "GrantType": "authorization_code", "RequestedScopes": "openid profile", "State": "CfDJ8Pdtr1YS18ZOp7dIVYqa05dMp_XQH4T-n8WcLhu5aBGOHMMP_JTWt2I4pM0JjtxMBddtz5WSWy-rkrZTqXLwr-BllETJJds86UiTcvUvxfQ7cCvVoM5I-gofWE-LrKJlrdDnhC4ofF4MGMfNAdYvVmT7J9fCEWJzuAspiyK8KBXGWiCZhw77isVR1q3hu7s3cKCvcuNKMi2jww_tjdOi8IYdZ8vTTlmA6tL8NpWDZaY1J6mj1WUzess9FQ2Bc2maeSYy4NBKCfPIITLq4aiHmCVb97itGJsIbImHQm2cTo43B_m7rYIPq-RHtGAgXU6l81mIMwmxjhJhsfhH28KExQitCgPNewh9ltpLgumr4Zm49TuUMubYy6L6sYM7jzeekA", "UiLocales": null, "Nonce": "637086795594073564.YWI5YWMzMTgtZjU0Ni00YjI5LTg1ZTMtOGViN2JjYjgwY2YxYzAxZTY2YzQtMjg2Yy00YjkyLWE0ZGYtODYzNDA1NWIwYWY5", "AuthenticationContextReferenceClasses": null, "DisplayMode": null, "PromptMode": null, "MaxAge": null, "LoginHint": null, "SessionId": "k6AJ_-EdagzerxIIl6oQmA", "Raw": {"client_id": "mvc", "redirect_uri": "https://localhost:44377/signin-oidc", "response_type": "code", "scope": "openid profile", "code_challenge": "sHPH6r59Ij8Iap6esr_3opZrue72ZdOVxBg-20IQMs4", "code_challenge_method": "S256", "response_mode": "form_post", "nonce": "637086795594073564.YWI5YWMzMTgtZjU0Ni00YjI5LTg1ZTMtOGViN2JjYjgwY2YxYzAxZTY2YzQtMjg2Yy00YjkyLWE0ZGYtODYzNDA1NWIwYWY5", "state": "CfDJ8Pdtr1YS18ZOp7dIVYqa05dMp_XQH4T-n8WcLhu5aBGOHMMP_JTWt2I4pM0JjtxMBddtz5WSWy-rkrZTqXLwr-BllETJJds86UiTcvUvxfQ7cCvVoM5I-gofWE-LrKJlrdDnhC4ofF4MGMfNAdYvVmT7J9fCEWJzuAspiyK8KBXGWiCZhw77isVR1q3hu7s3cKCvcuNKMi2jww_tjdOi8IYdZ8vTTlmA6tL8NpWDZaY1J6mj1WUzess9FQ2Bc2maeSYy4NBKCfPIITLq4aiHmCVb97itGJsIbImHQm2cTo43B_m7rYIPq-RHtGAgXU6l81mIMwmxjhJhsfhH28KExQitCgPNewh9ltpLgumr4Zm49TuUMubYy6L6sYM7jzeekA"}, "$type": "AuthorizeRequestValidationLog"}

[00:26:01 Debug] IdentityServer4.Test.TestUserProfileService
IsActive called from: AuthorizeEndpoint

[00:26:01 Debug] IdentityServer4.Stores.DefaultUserConsentStore
user_consent grant with value: mvc|88421113 not found in store.

[00:26:01 Debug] IdentityServer4.Services.DefaultConsentService
Found no prior consent from consent store, consent is required

[00:26:01 Information] IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator
User consented to scopes: ["openid", "profile"]

[00:26:01 Debug] IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator
User indicated to remember consent for scopes: ["openid", "profile"]

[00:26:01 Debug] IdentityServer4.Services.DefaultConsentService
Client allows remembering consent, and consent given. Updating consent store for subject: 88421113

[00:26:01 Debug] IdentityServer4.ResponseHandling.AuthorizeResponseGenerator
Creating Authorization Code Flow response.

[00:26:01 Information] IdentityServer4.Events.DefaultEventService
{"ClientId": "mvc", "ClientName": "MVC Client", "RedirectUri": "https://localhost:44377/signin-oidc", "Endpoint": "Authorize", "SubjectId": "88421113", "Scopes": "openid profile", "GrantType": "authorization_code", "Tokens": [{"TokenType": "code", "TokenValue": "****MUrA", "$type": "Token"}], "Category": "Token", "Name": "Token Issued Success", "EventType": "Success", "Id": 2000, "Message": null, "ActivityId": "0HLR322N3G5DT:00000017", "TimeStamp": "2019-11-06T23:26:01.0000000Z", "ProcessId": 3312, "LocalIpAddress": "::1:44374", "RemoteIpAddress": "::1", "$type": "TokenIssuedSuccessEvent"}

[00:26:01 Debug] IdentityServer4.Endpoints.AuthorizeCallbackEndpoint
Authorize endpoint response
{"SubjectId": "88421113", "ClientId": "mvc", "RedirectUri": "https://localhost:44377/signin-oidc", "State": "CfDJ8Pdtr1YS18ZOp7dIVYqa05dMp_XQH4T-n8WcLhu5aBGOHMMP_JTWt2I4pM0JjtxMBddtz5WSWy-rkrZTqXLwr-BllETJJds86UiTcvUvxfQ7cCvVoM5I-gofWE-LrKJlrdDnhC4ofF4MGMfNAdYvVmT7J9fCEWJzuAspiyK8KBXGWiCZhw77isVR1q3hu7s3cKCvcuNKMi2jww_tjdOi8IYdZ8vTTlmA6tL8NpWDZaY1J6mj1WUzess9FQ2Bc2maeSYy4NBKCfPIITLq4aiHmCVb97itGJsIbImHQm2cTo43B_m7rYIPq-RHtGAgXU6l81mIMwmxjhJhsfhH28KExQitCgPNewh9ltpLgumr4Zm49TuUMubYy6L6sYM7jzeekA", "Scope": "openid profile", "Error": null, "ErrorDescription": null, "$type": "AuthorizeResponseLog"}

客户端的配置是这样的

{
      "ClientId": "mvc",
      "ClientName": "MVC Client",

      // 49C1A7E1-0C79-4A89-A3D6-A37998FB86B0
      "ClientSecrets": [ { "Value": "o90IbCACXKUkunXoa18cODcLKnQTbjOo5ihEw9j58+8=" } ],
      "AllowedGrantTypes": [ "client_credentials", "authorization_code" ],
      "RequirePkce": true,
      "AllowedScopes": [ "openid", "profile", "api1" ],
      "AllowOfflineAccess": true,


      "RedirectUris": [ "https://localhost:44377/signin-oidc" ],
      "FrontChannelLogoutUris": [ "https://localhost:44377/signout-oidc" ],
      "PostLogoutRedirectUris": [ "https://localhost:44377/signout-callback-oidc" ]
},

并且客户端启动时看起来像这样

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();

    JwtSecurityTokenHandler.DefaultMapInboundClaims = false;

    services.AddAuthentication(opt =>
        {
            opt.DefaultScheme = "Cookies";
            opt.DefaultChallengeScheme = "oidc";
        })
        .AddCookie("Cookies")
        .AddOpenIdConnect("oidc", opt =>
        {
            opt.Authority = "https://localhost:44374";
            opt.RequireHttpsMetadata = true;

            opt.ClientId = Configuration["OIDC:ClientId"];
            opt.ClientSecret = Configuration["OIDC:Secret"];
            opt.ResponseType = "code";

            opt.SaveTokens = true;
            opt.AuthenticationMethod = OpenIdConnectRedirectBehavior.FormPost;
        });
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
        endpoints
            .MapDefaultControllerRoute()
            .RequireAuthorization();
    });
}

opt.SaveTokens = true; 是必须的吗? - Enrico
1个回答

81

看起来您忘记在Startup.Configure方法中添加对UseAuthentication()的调用了。这个中间件是使回调比如说/signin-oidc能够被您的客户端应用程序处理的关键:

app.UseRouting();
app.UseAuthentication(); // <-- Add it here.
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
    endpoints
        .MapDefaultControllerRoute()
        .RequireAuthorization();
});

在您参考的指南中提到:

为了确保身份验证服务在每个请求上执行,请在StartupConfigure中添加UseAuthentication


这个完全有效,谢谢!所以 UseAuthentication() 默认注册了该路由?这看起来似乎与 IdentityServer 没有任何关系..?它是 OIDC 标准/规范的一部分吗?它可以配置吗? - JvR
1
@JvR 是的,没错。UseAuthentication 为路由注册了一个处理程序,这与 IdentityServer 并不特定,更多的是关于 OIDC 协议。您可以使用 CallbackPath 更改路由本身。例如:.AddOpenIdConnect(o => o.CallbackPath = "/some-path") - Kirk Larkin
谢谢!不知道我怎么删掉了UseAuthentication(),但我的startup.cs只有UseAuthorization()。我知道早些时候我有两个中间件。因为预期的事件没有触发,我已经为此困扰了几个小时。即使您多次检查整个configure()方法,忽略琐碎的事情也容易得多。 - Stack Undefined
1
FYI,dotnet 7 不需要这个。因此,如果您首先在 dotnet 7 中设置项目,然后降级到 dotnet 6,这很容易被忽略。至少对我来说是这样的,我在找到这篇文章之前浪费了2个小时! - verbedr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接