C# 如何检查当前登录的用户是否为Azure Active Directory B2C“;全球管理员;?ASP.NETMVC

C# 如何检查当前登录的用户是否为Azure Active Directory B2C“;全球管理员;?ASP.NETMVC,c#,asp.net-mvc,authentication,azure-active-directory,C#,Asp.net Mvc,Authentication,Azure Active Directory,我希望只有在我的Azure Active Directory B2C租户中目录角色为“全局管理员”的用户才能访问控制器。因此,在实例化/运行控制器类之前,我希望执行类似于以下内容的检查: [Authorize(Roles = "Global Administrator")] public class UserProfileController : Controller { .... controller class .... } 我理解,为了调用上面的“Authorize”命令,我需要

我希望只有在我的Azure Active Directory B2C租户中目录角色为“全局管理员”的用户才能访问控制器。因此,在实例化/运行控制器类之前,我希望执行类似于以下内容的检查:

[Authorize(Roles = "Global Administrator")]
public class UserProfileController : Controller
{
    .... controller class ....
}
我理解,为了调用上面的“Authorize”命令,我需要启用角色管理器与Azure Active Directory B2C同步,如Web.config中所示:

<authentication mode="Windows"/>
<roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider">
  <providers>
    <clear />
    <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
  </providers>
</roleManager>
这告诉我,在UserProfileController上使用“Authorize”命令检查当前登录的用户是否是“全局管理员”是错误的

因此,我的问题是:

  • 如何检查当前登录的用户是否为“全局管理员”,并防止他们使用UserProfileController(如果不是)
  • 我是否应该禁用角色管理器,因为在这种情况下无法使用它
  • 有没有办法检查当前登录的用户是否也是.cshtml中的“全局管理员”?我只想为全局管理员显示一个按钮
  • ======================================================

    编辑以添加Startup.Auth.cs类的代码:

    public partial class Startup
    {
        private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
        private static string appKey = ConfigurationManager.AppSettings["ida:ClientSecret"];
        private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
        private static string tenantId = ConfigurationManager.AppSettings["ida:TenantId"];
        private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
        // This is the resource ID of the AAD Graph API.  We'll need this to request a token to call the Graph API.
        private static string graphResourceId = "https://graph.microsoft.com";
        private static readonly string Authority = aadInstance + tenantId;
        public static GraphServiceClient graphClient = null;
    
        public static GraphServiceClient GetGraphServiceClient()
        {
            return graphClient;
        }
    
        public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    
            app.UseCookieAuthentication(new CookieAuthenticationOptions());
    
            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    ClientId = clientId,
                    Authority = Authority,
                    PostLogoutRedirectUri = postLogoutRedirectUri,
    
                    Notifications = new OpenIdConnectAuthenticationNotifications()
                    {
                        // If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
                       AuthorizationCodeReceived = (context) => 
                       {
                           var code = context.Code;
                           ClientCredential credential = new ClientCredential(clientId, appKey);
                           string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
    
                           TokenCache userTokenCache = new ADALTokenCache(signedInUserID);
    
                           AuthenticationContext authContext = new AuthenticationContext(Authority, userTokenCache);
                           AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
                               code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId);
    
                           string token = result.AccessToken;
    
                           try
                           {
                               graphClient = new GraphServiceClient(
                                   new DelegateAuthenticationProvider(
                                       (requestMessage) =>
                                       {
                                           requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", token);
    
                                           return Task.FromResult(0);
                                       }));
                           }
                           catch (Exception e)
                           {
                               System.Diagnostics.Debug.WriteLine("Failed to create graph client: " + e.Message);
                           }
    
                           return Task.FromResult(0);
                       }
                    }
                });
        }
    }
    
    ========================================

    这个答案非常完整,回答了这个问题:我发现这个问题的答案非常有用:

    问题在于,您正在使用为Active Directory创建的API,并试图使用Azure Active Directory。Azure Active Directory对于内置的成员资格提供程序根本不起作用

    支持您的场景的方式是通过OAuth 2.0/OpenId Connect。阅读“”,了解在ASP.NET应用程序中使用Azure AD的基本知识。
    由于省略了代码中最相关的部分,因此Startup.Auth文件如下所示:

    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    app.UseCookieAuthentication(new CookieAuthenticationOptions());
    
    app.UseOpenIdConnectAuthentication(
        new OpenIdConnectAuthenticationOptions
        {
            ClientId = clientId,
            Authority = Authority,
            PostLogoutRedirectUri = postLogoutRedirectUri
        });
    
    您使用的确切配置将根据您是否需要使用用户凭据访问其他Azure API而有所不同,因此请务必查看手册以了解所需的情况

    记住这一点:

    • 身份验证模式:Windows=>Active Directory
    • OAuth 2.0/OpenId Connect=>Azure Active Directory

    一旦配置正确,您就可以毫无问题地使用
    [Authorize(Roles=“Global Administrator”)]

    此问题的答案解决了我的问题


    首先说Active Directory,然后说Azure Active Directory。是哪一个?就认证apisthank而言,它们是两种完全不同的产品。我已经澄清我正在使用Azure Active Directory B2C。谢谢。当您澄清AD与Azure AD的身份验证协议时,它真的很有帮助。我已经编辑了原始问题,以包括Startup.Auth.cs的代码,其中包括您的建议。但是,我仍然遇到同样的错误:“只有当用户名参数与当前Windows标识中的用户名匹配时,才支持该方法。”我已经查看了提供的文档链接(太棒了,谢谢!),肯定需要继续查看,但你能更具体地指出我还缺少什么配置吗?@Emilia很高兴这有帮助。是否删除了web.config部分?我发现很可能有某个提供程序仍在运行,并且它优先于OWIN设置的身份验证。也就是说,您可能会发现使用域帐户创建一个新的MVC项目并从Template复制相关部分更容易。此外,如果您对我将graphClient对象传递给其他控制器类的更好方法有任何建议,我将很高兴听到。让graphClient对象驻留在Startup类中,并使用名为GetGraphServiceClient()的getter方法似乎很麻烦,因为控制器类可以接收空graphClient或带有过期或接近过期令牌的graphClient。非常感谢你!卡米洛,你是说角色经理应该被禁用吗?如果从Web.config中删除整个代码段,则登录将挂起。但是,如果我仍然保留,那么我会得到相同的错误。我当然可以将其作为创建新MVC项目的一个选项,但我知道这将需要大量工作。@Emilia我会将其保留为
    enabled=“false”
    或完全删除,与
    authentication mode=“windows”
    相同。该(成员资格)与OWIN不起作用。我需要查看该登录,因为它很可能无法与Azure一起使用OOB
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    app.UseCookieAuthentication(new CookieAuthenticationOptions());
    
    app.UseOpenIdConnectAuthentication(
        new OpenIdConnectAuthenticationOptions
        {
            ClientId = clientId,
            Authority = Authority,
            PostLogoutRedirectUri = postLogoutRedirectUri
        });