簡體   English   中英

.Net Core MVC 應用與 IdentityServer4,使用 Azure Active Directory 登錄。 管理員同意和權限問題

[英].Net Core MVC app with IdentityServer4, login with Azure Active Directory. Problem with admin consent and permissions

我正在嘗試為使用 IdentityServer4 制作的 MVC web 應用程序與 AAD 集成。 我想要一個代碼身份驗證流程 [https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow]。 在我對現有代碼進行更改后(當前代碼將在帖子后面顯示),一切似乎都正常工作。 但是,經過一些測試后,我發現當我嘗試使用沒有分配任何管理員角色的帳戶登錄時,會顯示下面的彈出窗口。 為沒有管理員角色的用戶顯示彈出窗口

當我嘗試使用具有管理員角色的帳戶登錄應用程序時,此彈出窗口顯示為具有管理員角色的用戶顯示的彈出窗口

這對我來說似乎是正確的行為,因為其中一項權限需要管理員同意。

但是當我代表我的組織同意權限時問題就開始了(以具有管理員全局管理員角色的用戶身份登錄)。 我的預期行為是,在獲得其中一位管理員的同意后,普通用戶可以訪問該應用程序。

實際結果是彈出數字1仍然呈現給用戶,他們無法進入我的應用程序。

當用戶成功登錄時,我的代碼中發生了什么?

基本上,當用戶第一次使用 AAD 登錄我的應用程序時,我想將他添加到數據庫中的用戶表中。 如果這不是他第一次登錄,我想根據個人資料和用戶分配的組更新一些信息。 為此,我需要使用 Microsoft Graph API 讀取基本用戶信息和組名稱。

我為應用程序配置的權限(類型=委托):

  • GroupMember.Read.All
  • 用戶讀

GroupMember.Read.All 需要管理員同意。 我發現我需要這個“GroupMember.Read.All”來檢索具有諸如 DisplayName 填充的屬性的組。 似乎此權限導致了登錄問題。(僅使用 User.Read 登錄工作正常,但顯然我無權訪問組名稱等,只有組 ID)

我用於登錄用戶組信息的代碼:

        var accessToken = authResult.Properties.GetTokenValue("access_token");

        GraphServiceClient graphClient = GetClient(accessToken);

        var groupsList = (await graphClient.Me.MemberOf.Request().GetAsync()).ToList();

如您所見,訪問令牌是從“AuthenticateResult”的屬性中檢索的。

獲取此 access_token 以使用圖形資源的邏輯在下面的 Startup.cs 文件中。 返回身份驗證代碼后,我獲得 Microsoft Graph 的 access_token,然后將其傳遞給身份驗證結果,我可以在我的服務代碼中進一步使用,如上面所示(獲取用戶所屬的組)。

if (aadSettings.IsValid)
        {
            services.AddAuthentication()
            .AddOpenIdConnect("aad", "Active Directory", options =>
            {
                options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                options.SignOutScheme = IdentityServerConstants.SignoutScheme;

                options.Authority = aadSettings.ADAuthority;
                options.ClientId = aadSettings.ADClientId;
                options.ClientSecret = aadSettings.ApplicationSecret;

                options.CallbackPath = aadSettings.CallbackPath;
                options.SignedOutCallbackPath = aadSettings.SignedOutCallbackPath;
                options.RemoteSignOutPath = aadSettings.RemoteSignOutPath;
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    NameClaimType = "name",
                    RoleClaimType = "role"
                };
                options.Prompt = "consent";
                options.Scope.Add("https://graph.microsoft.com/User.Read");
                options.Scope.Add("https://graph.microsoft.com/GroupMember.Read.All");

                options.ResponseType = "code id_token";
                options.Resource = "https://graph.microsoft.com/";
                options.SaveTokens = true;

                options.Events.OnAuthorizationCodeReceived = async contex => {
                    var authCode = contex.ProtocolMessage.Code;
                    var credential = new ClientCredential(aadSettings.ADClientId, aadSettings.ApplicationSecret);
                    var currentUri = UriHelper.BuildAbsolute(contex.Request.Scheme, contex.Request.Host, contex.Request.PathBase, contex.Request.Path);
                    var authContext = new AuthenticationContext(aadSettings.ADAuthority);

                    AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(authCode, new Uri(currentUri), credential, options.Resource);
                    contex.HandleCodeRedemption(result.AccessToken, result.IdToken);
                };
            });

URL when sending request for auth code: https://login.microsoftonline.com/{tenant_id}/oauth2/authorize?client_id={client_id}&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2Fsignin-oidc&resource=https%3A %2F%2Fgraph.microsoft.com%2F&response_type=code%20id_token&prompt=consent&scope=openid%20profile%20https%3A%2F%2Fgraph.microsoft.com%2FUser.Read%20https%3A%2F%2Fgraph.microsoft.com%2FGroupMember .Read.All&response_mode=form_post&nonce=...&state=..

所以問題是:如何解決沒有管理員角色的用戶登錄的問題? 以及如何獲取用戶分配到的組? 我是否缺少 AAD 中的某些配置? 或者也許我使用了錯誤的權限?

您已指定options.Prompt = "consent"; ,無論用戶是否同意,每次都會觸發同意對話框。 由於您使用的是“v1”授權端點,因此您無需在 scope 參數中指定 Graph API scope URI(它會查看您的應用注冊中的權限)。 刪除提示參數應該允許用戶在已經同意的情況下無需同意權限即可登錄。

v1 端點的一個缺點是,如果已同意任何權限,則不會再次觸發同意,即使您向應用注冊添加新權限也是如此。 這更適用於 v2 端點,您可以在其中指定 scope 參數中所需的權限(並省略資源參數)。 在 v2 中,如果未同意所有請求的范圍,則會觸發同意。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM