首页 > 解决方案 > 为什么 Openiddict 会自动验证 client_id?

问题描述

我想生成一个带有四个参数 client_id、client_secret、用户名和用户密码的令牌。Client_Id 和 client_secret 是可选要求。当我使用用户名和用户密码生成令牌时,它工作正常,但是当我尝试传递 client_id 时,它失败并出现 500 内部服务器错误。

当我检查日志并发现:

没有为此 DbContext 配置数据库提供程序。

我的服务配置

 public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        services.AddDbContext<DbContext>(options =>
        {
            options.UseOpenIddict();
        });

        services.AddOpenIddict()
            // Register the OpenIddict core services.
            .AddCore(options =>
            {
                options.UseEntityFrameworkCore().UseDbContext<DbContext>();
            })
          
            .AddServer(options =>
            {
                options.UseMvc();
                options.EnableTokenEndpoint("/connect/token");
                options.AllowPasswordFlow().AllowRefreshTokenFlow();
                options.SetAccessTokenLifetime(TimeSpan.FromMinutes(10));
                options.SetRefreshTokenLifetime(TimeSpan.FromHours(4));
                options.AcceptAnonymousClients();
                options.DisableHttpsRequirement();
               
            })
            .AddValidation();
        services.AddAuthentication(options =>
        {
            options.DefaultScheme = OpenIddictValidationDefaults.AuthenticationScheme;
        });
    }

日志

  fail: Microsoft.AspNetCore.Server.Kestrel[13]
  Connection id "0HLJJPK2L74A1", Request id "0HLJJPK2L74A1:00000003": An 
  unhandled exception was thrown by the application.
  System.InvalidOperationException: No database provider has been 
  configured for this DbContext. A provider can be configured by 
  overriding the DbContext.OnConfiguring method or by using AddDbContext 
  on the application service provider. If AddDbContext is used, then also 
  ensure that your DbContext type accepts a DbContextOptions<TContext> 
  object in its constructor and passes it to the base constructor for 
  DbContext.

 
  at System.Threading.Tasks.ValueTask`1.get_Result()
  at 
  OpenIddict.Core.OpenIddictApplicationManager`1.FindByClientIdAsync(String 
  identifier, CancellationToken cancellationToken)
  at OpenIddict.Core.OpenIddictApplicationManager`1. 
  OpenIddict.Abstractions.IOpenIddictApplicationManager. 
  FindByClientIdAsync(String identifier, CancellationToken 
  cancellationToken)

           

问题是只有当我在令牌请求中传递 client_id 时才会发生这种情况。我认为这个 client_Id 是由 openiddict 自动验证的。我想在我的“/connect/token”方法上验证这个 client_id。

我没有在我的应用程序中配置任何 dbcontext。有没有办法使用 client_id & client_secret & user id & user Pass 生成令牌而无需在下面配置,或者是否有任何其他配置可以做到这一点

  .AddCore(options =>
            {
                options.UseEntityFrameworkCore().UseDbContext<DbContext>();
            })

我正在为我的应用程序使用 oracle 数据库。

标签: asp.net-coreopenid-connectopeniddict

解决方案


Client_Id 和 client_secret 是可选要求。

它们是:公共客户端确实可以避免发送其客户端标识符,如 OAuth2 规范所允许的那样。如果您已将 OpenIddict 配置为禁用客户端标识要求(默认强制执行),则如果client_id不存在,则该请求将被视为有效。

也就是说,如果您指定 a client_id,那么它必须对应于实际应用程序。OpenIddict 通过询问底层存储(在您的情况下为 EF Core)是否client_id存在具有指定的应用程序来验证这一点。如果未正确配置 DB 提供程序,您将收到与您正在查看的异常类似的异常。

OpenIddict 并非设计为在没有后备数据库的情况下使用(用于存储应用程序、授权或令牌)。

如果您更喜欢(几乎)无状态的体验,您可能想尝试一下 ASOS(OpenIddict 背后的低级 OIDC 服务器处理程序):https ://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server 。它将支持您的方案,而不会强迫您创建数据库。


推荐阅读