0

我正在使用 Microsoft Graph 并获取需要管理员同意的用户信息。由于我不希望弹出页面出现在同意页面中,因此我将使用 Client credentail 来避免用户同意页面。通过查看 Microsoft 团队从 GitHub 创建的一些代码调用“Group Manager”和“userSync”,我得到了所需的结果,并且我对代码进行了一些更改。但我收到一些错误如下:

“无法验证 'id_token',找不到合适的 ISecurityTokenValidator:''如何验证”

请注意,我不仅是 Microsoft Graph 的新手,而且还是身份验证和授权的新手。我得到的错误我无法弄清楚。但是,我认为我为

OnAuthorizationCodeReceivedAsync

它不适用于客户凭证。你们中的一个人可以看看它并帮助了解它是否可以或不适合parituclar原因。

此外,在OnSecurityTokenValidated()下,特别是Globals.ConsumerTenantId 将是什么。我不知道那是什么。

请注意,我已经在 azure 中为 ID-Token 注册了我的应用程序。并且在配置中响应类型是 ResponseType = OpenIdConnectResponseType.CodeIdToken,

请看下面的代码:

  public void Configuration(IAppBuilder app)
    {
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions());
        app.UseOpenIdConnectAuthentication(
        new OpenIdConnectAuthenticationOptions
        {
                  ClientId = clientId,
            Authority = authority,
            RedirectUri = redirectUri,
            // PostLogoutRedirectUri is the page that users will be redirected to after sign-out. In this case, it is using the home page
            PostLogoutRedirectUri = redirectUri,
            Scope = OpenIdConnectScope.OpenIdProfile,

            // ResponseType is set to request the code id_token - which contains basic information about the signed-in user
            ResponseType = OpenIdConnectResponseType.CodeIdToken,
            
            //ResponseType = OpenIdConnectResponseType.IdToken,
            // OpenIdConnectAuthenticationNotifications configures OWIN to send notification of failed authentications to OnAuthenticationFailed method
            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                AuthenticationFailed = OnAuthenticationFailed,
                AuthorizationCodeReceived = OnAuthorizationCodeReceivedAsync,
                SecurityTokenValidated = OnSecurityTokenValidatedAsync

            }
        }
    );
    }

    /// <summary>
    /// Handle failed authentication requests by redirecting the user to the home page with an error in the query string
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    private Task OnAuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
    {
        context.HandleResponse();
        context.Response.Redirect("Error/AccessDenied/?errormessage = " + context.Exception.Message);
        return Task.FromResult(0);
    }


    private async Task OnAuthorizationCodeReceivedAsync(AuthorizationCodeReceivedNotification notification)
    {
        notification.HandleCodeRedemption();

        // var authority= "https://login.microsoftonline.com/{"+tenant+"}/adminconsent?client_id={"+clientId+"}";
        var idClient = ConfidentialClientApplicationBuilder.Create(clientId)
            //.WithRedirectUri(redirectUri)
            .WithClientSecret(clientSecret)

            .WithAuthority(authority)
            .WithTenantId(tenant)
            .Build();

        

        var signedInUser = new ClaimsPrincipal(notification.AuthenticationTicket.Identity);
        var tokenStore = new SessionTokenStore(idClient.UserTokenCache, HttpContext.Current, signedInUser);

        try
        {
            string[] scopes = new string[] { "https://graph.microsoft.com/.default" };
            AuthenticationResult result = null;
            result = await idClient.AcquireTokenForClient(scopes)
                             .ExecuteAsync();
            var check = result.AccessToken;
            var check2 = result.IdToken;

            var userDetails = await GraphHelper.GetUserDetailsAsync(result.AccessToken);
            tokenStore.SaveUserDetails(userDetails);
            notification.HandleCodeRedemption(null, result.IdToken)//this is original;
           
        }
        catch (MsalException ex)
        {
            string message = "AcquireTokenByAuthorizationCodeAsync threw an exception";
            notification.HandleResponse();
            notification.Response.Redirect($"/Home/Error?message={message}&debug={ex.Message}");
        }
        catch (Microsoft.Graph.ServiceException ex)
        {
            string message = "GetUserDetailsAsync threw an exception";
            notification.HandleResponse();
            notification.Response.Redirect($"/Home/Error?message={message}&debug={ex.Message}");
        }
    }

    private Task OnSecurityTokenValidated(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
    {
        // Verify the user signing in is a business user, not a consumer user.
        string[] issuer = context.AuthenticationTicket.Identity.FindFirst(Globals.IssuerClaim).Value.Split('/');
        string tenantId = issuer[(issuer.Length - 2)];
        if (tenantId == Globals.ConsumerTenantId)
        {
            throw new SecurityTokenValidationException("Consumer accounts are not supported for the Group Manager App.  Please log in with your work account.");
        }

        return Task.FromResult(0);
4

0 回答 0