如何在不使用 Microsoft.AspNetCore.Identity.UI 的情况下设置 OpenIddict 以依赖 AzureAd

问题描述

我们的角色模型不同,所以我们不能使用现有的 Microsoft 身份数据库模型以及与之配套的所有 UX,更遗憾的是。

我想做的就是

  • 使用 OpenIdDict
  • 让 AzureAd 进行身份验证
  • 将我自己的声明放入声明主体中,以便在 OpenIdDict 创建时将其放入身份令牌

出于各种原因,我对 IdentityServer 不感兴趣。

我完成了一个教程,并且使用在 AccountController 中处理的基于 cookie 的身份验证轻松构建所有这些,但我不知道如何切换到 Azure 并且真的可以使用一些帮助。

启动看起来像这样

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

      // services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
      //     .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,options =>
      //     {
      //       options.LoginPath = "/account/login";
      //     });

      services.AddAuthentication()
          .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"));
          // from package `Microsoft.Identity.Web`

      services.AddDbContext<DbContext>(options =>
          {
            // Configure the context to use an in-memory store.
            options.UseInMemoryDatabase(nameof(DbContext));

            // Register the entity sets needed by OpenIddict.
            options.USEOpenIddict();
          });

      services.AddHostedService<TestData>();

      var openiddictBuilder = services.AddOpenIddict();

      // Register the OpenIddict core components.
      openiddictBuilder.AddCore(options =>
      {
        // Configure OpenIddict to use the EF Core stores/models.
        options.UseEntityFrameworkCore()
        .UseDbContext<DbContext>();
      });

      // Register the OpenIddict server components.
      openiddictBuilder.AddServer(options =>
      {
        options
        .AllowAuthorizationCodeFlow().RequireProofKeyForCodeExchange()
        .AllowClientCredentialsFlow()
        .AllowRefreshTokenFlow()
        .SetAuthorizationEndpointUris("/connect/authorize")
        .SetTokenEndpointUris("/connect/token")

        // Encryption and signing of tokens
        .AddEphemeralEncryptionKey()
        .AddEphemeralSigningKey()
        .disableAccesstokenEncryption()

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

        // Register the ASP.NET Core host and configure the ASP.NET Core-specific options.
        .UseAspNetCore()
        .EnabletokenEndpointPassthrough()
        .EnableAuthorizationEndpointPassthrough()
        ;
      });
    }

一个 AuthorizeController 和一个像这样的 Authorize 方法

    [HttpGet("~/connect/authorize")]
    [HttpPost("~/connect/authorize")]
    [IgnoreAntiforgeryToken]
    public async Task<IActionResult> Authorize()
    {
      var request = HttpContext.GetopenIddictServerRequest() ??
          throw new InvalidOperationException("The OpenID Connect request cannot be retrieved.");

      // Retrieve the user principal stored in the authentication cookie.
      // var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
      var result = await HttpContext.AuthenticateAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);

      // If the user principal can't be extracted,redirect the user to the login page.
      if (!result.Succeeded)
      {
        var authprops = new AuthenticationProperties
        {
          RedirectUri = Request.PathBase + Request.Path + QueryString.Create(
                    Request.HasFormContentType ? Request.Form.ToList() : Request.Query.ToList())
        };
        return Challenge(
            authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,properties: authprops);
      }

      // Create a new claims principal
      var claims = new List<Claim>
      {
          // 'subject' claim which is required
          new Claim(OpenIddictConstants.Claims.Subject,result.Principal.Identity.Name),new Claim(OpenIddictConstants.Claims.Role,"admin").SetDestinations(
            OpenIddictConstants.Destinations.IdentityToken),"gerbil wrangler").SetDestinations(
            OpenIddictConstants.Destinations.IdentityToken)
    };

      var claimsIdentity = new ClaimsIdentity(claims,OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);

      var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);

      // Set requested scopes (this is not done automatically)
      claimsPrincipal.SetScopes(request.GetScopes());

      // Signing in with the OpenIdDict authentiction scheme causes OpenIdDict 
      // to issue a code which can be exchanged for an access token
      return SignIn(claimsPrincipal,OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
    }

据我了解操作原理,OpenIddict 代理身份验证,然后发出新令牌。这意味着 AzureAd redirect_uri 应该设置为 OpenIddict 提供的端点,可能类似于 signin-openiddict 并假设我对所有这些都是正确的,与 OpenIddict 交谈的客户端将反过来提供一个完全不同且不相关的重定向_uri。但我还没有找到任何涉及这方面的文档,所以请随时教育我。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)