简体   繁体   English

如何在 .Net 核心 Web API 中进行 Azure AD 组授权?

[英]How to do Azure AD groups authorization in .Net core web API?

Net core web application. Net 核心 Web 应用程序。 I am trying to implement groups based authorization in my .Net core app.我正在尝试在我的 .Net 核心应用程序中实现基于组的授权。 I am trying to call groups from Microsoft graph.我正在尝试从 Microsoft 图中调用组。 I have some confusion here.我在这里有些困惑。 Below are the steps.下面是步骤。

  1. Created Web API app in .Net core 2.1在 .Net core 2.1 中创建了 Web API 应用程序
  2. Added swashbuckle swagger support to it.为其添加了 swashbuckle swagger 支持。
  3. created app in Azure AD for swagger在 Azure AD 中为 swagger 创建了应用程序
  4. Created app in Azure AD for back end .Net core API (Name is WebServicesAPP).在 Azure AD 中为后端 .Net 核心 API 创建了应用程序(名称为 WebServicesAPP)。
  5. In WebServicesAPP app -> Expose an API-> Add client application -> Added my swagger app.在 WebServicesAPP 应用程序 -> 公开 API -> 添加客户端应用程序 -> 添加我的 swagger 应用程序。
  6. In WebServicesAPP app -> API Permissions -> Add Permission -> Microsoft graph API -> Application Permission -> Group.ReadAll在 WebServicesAPP app -> API Permissions -> Add Permission -> Microsoft graph API -> Application Permission -> Group.ReadAll
  7. changed Oauthimplicitflow to True in manifest.在清单中将 Oauthimplicitflow 更改为 True。

These are the steps I taken.这些是我采取的步骤。 After this I have added relevant code to implement swagger as below.在此之后,我添加了相关代码来实现 swagger,如下所示。 In startup I have added在启动时我添加了

public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services
               .AddAuthentication(o =>
               {
                   o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;

               })
               .AddJwtBearer(o =>
               {
                   o.Authority = azureActiveDirectoryOptions.Authority;

                   o.TokenValidationParameters = new TokenValidationParameters
                   {

                       ValidAudiences = new List<string>
                       {
                          azureActiveDirectoryOptions.AppIdUri,
                          azureActiveDirectoryOptions.ClientId
                       },
                       ValidateIssuer = true
                   };
               });
            services.AddScoped<IAuthorizationHandler, GroupsCheckHandler>();
            services.AddAuthorization(options =>
            {   
                options.AddPolicy("GroupsCheck", policy =>
                {
                    policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
                    policy.RequireAuthenticatedUser();
                    policy.Requirements.Add(new GroupsCheckRequirement("9da02036-fc14-4e97-ac58-2293bddae44d"));
                });
            });
            services.AddMvc(options =>
            {

                var policy = new AuthorizationPolicyBuilder()
                    .RequireAuthenticatedUser()
                    .Build();
                options.Filters.Add(new AuthorizeFilter(policy));
            })
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });

                c.AddSecurityDefinition("oauth2", new OAuth2Scheme
                {
                    Type = "oauth2",
                    Flow = "implicit",
                    AuthorizationUrl = swaggerUIOptions.AuthorizationUrl,
                    TokenUrl = swaggerUIOptions.TokenUrl
                });
                c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
                {
                        { "oauth2", new[] { "readAccess", "writeAccess" } }
                });
            });
        }


        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }
            app.UseHttpsRedirection();

            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {

                c.OAuthClientId(swaggerUIOptions.ClientId);
                c.OAuthClientSecret(swaggerUIOptions.ClientSecret);
                c.OAuthRealm(azureActiveDirectoryOptions.ClientId);
                c.OAuthAppName("Swagger");
                c.OAuthAdditionalQueryStringParams(new { resource = azureActiveDirectoryOptions.ClientId });
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
            });
            app.UseAuthentication();
            app.UseMvc();
        }

Now with my above code I am generating swagger.现在使用我上面的代码,我正在生成招摇。 In swagger I clicked on Authorize Tab-> Added my login details and I tried to hit below sample API.我在 swagger 中点击了 Authorize Tab-> 添加了我的登录详细信息,然后我尝试点击下面的示例 API。

 [Authorize]
    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase

With Application permission and client credential I am using below code to get token for MS graph使用应用程序权限和客户端凭据,我使用下面的代码来获取 MS 图形的令牌

AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenAsync(graphResource, clientCred).ConfigureAwait(false);
            var token = authenticationResult.AccessToken;

Once I get toke from above code I am successfully getting groups like below一旦我从上面的代码中获得了令牌,我就成功地获得了如下组

GraphServiceClient client = await MicrosoftGraphClient.GetGraphServiceClient();
            var groupList = await client.Users[userId].MemberOf.Request().GetAsync(); 

I am able to hit API and I am having no issue.我能够点击 API 并且我没有问题。

Now I want to get all the groups from Microsoft graph API end point.现在我想从 Microsoft 图形 API 端点获取所有组。 I need little clarification on below.我需要在下面澄清一点。

  1. Now I already have token and can I use same token to call Microsoft graph API?现在我已经有了令牌,我可以使用相同的令牌来调用 Microsoft 图形 API 吗?
  2. Now I am trying to get current logged in users group so when adding Microsoft graph we have two options delegated permission and application permission.现在我正在尝试获取当前登录的用户组,因此在添加 Microsoft 图形时,我们有两个选项委派权限和应用程序权限。 delegated permission -> Used to call graph API on behalf of user Application permission -> App itself calls Microsoft graph API.委托权限 -> 用于代表用户调用图 API 应用权限 -> 应用本身调用微软图 API。 Using client credentials flow It generates token and passes to Microsoft graph and authenticates.使用客户端凭据流 它生成令牌并传递给 Microsoft 图形并进行身份验证。
  3. In my case I have logged in user ad I am trying to hit Microsoft graph.就我而言,我已登录用户广告,我试图点击 Microsoft 图表。 So which One I should use Delegated Permission or Application Permission?那么我应该使用委托权限还是应用程序权限呢?

I am finding very hard to understand these since quite time and I do not see any relevant document for my approach.我发现很难理解这些,因为很长时间以来我没有看到任何与我的方法相关的文件。 Can someone help me to understand this?有人可以帮助我理解这一点吗? Really any suggestions will really help me.真的任何建议都会真正帮助我。 Thanks a lot.非常感谢。

Now I already have token and can I use same token to call Microsoft graph API?现在我已经有了令牌,我可以使用相同的令牌来调用 Microsoft 图形 API 吗?

No. The token is for your API.否。令牌用于您的 API。 You need to get another token for MS Graph API using eg the MSAL library ( https://www.nuget.org/packages/Microsoft.Identity.Client/ ).您需要使用例如 MSAL 库 ( https://www.nuget.org/packages/Microsoft.Identity.Client/ ) 为 MS Graph API 获取另一个令牌。

Now I am trying to get current logged in users group so when adding Microsoft graph we have two options delegated permission and application permission.现在我正在尝试获取当前登录的用户组,因此在添加 Microsoft 图形时,我们有两个选项委派权限和应用程序权限。 delegated permission -> Used to call graph API on behalf of user Application permission -> App itself calls Microsoft graph API.委托权限 -> 用于代表用户调用图 API 应用权限 -> 应用本身调用微软图 API。 Using client credentials flow It generates token and passes to Microsoft graph and authenticates.使用客户端凭据流 它生成令牌并传递给 Microsoft 图形并进行身份验证。

In my case I have logged in user ad I am trying to hit Microsoft graph.就我而言,我已登录用户广告,我试图点击 Microsoft 图表。 So which One I should use Delegated Permission or Application Permission?那么我应该使用委托权限还是应用程序权限呢?

It's a good question.这是个好问题。 Either will most likely work.要么很可能会奏效。 I tend to prefer delegated permissions whenever possible, as that limits the scope of things my app can access.我倾向于尽可能倾向于委托权限,因为这限制了我的应用程序可以访问的范围。

Application permissions are typically easier to use, but grant your app tenant-wide access.应用程序权限通常更易于使用,但授予您的应用程序租户范围的访问权限。 Since the token acquired with app permissions is the same regardless which user is calling your API, it can be shared and used in different requests.由于无论哪个用户调用您的 API,通过应用权限获取的令牌都是相同的,因此可以在不同的请求中共享和使用。

Delegated permissions require a bit more effort to use.委派的权限需要更多的努力才能使用。 In this case you would need to exchange the access token your API received for a token to MS Graph API.在这种情况下,您需要将您的 API 收到的访问令牌换成 MS Graph API 的令牌。 But that token will be specific to that user, so they cannot be shared.但该令牌将特定于该用户,因此无法共享。

If you use application permissions, you can get the token using the scopes ["https://graph.microsoft.com/.default"] and your client id + secret/certificate.如果您使用应用程序权限,则可以使用范围["https://graph.microsoft.com/.default"]和您的客户端 ID + 机密/证书获取令牌。

With delegated permissions, you can use the same scopes.通过委派权限,您可以使用相同的范围。 .default will use the permissions assigned to the app in the registration. .default将使用注册中分配给应用程序的权限。 But you will also have to include the access token that your API received.但是您还必须包含您的 API 收到的访问令牌。

One more issue that you can hit with delegated permissions is that if the user cannot access the data you are trying to access, it will fail.您可以使用委派权限解决的另一个问题是,如果用户无法访问您尝试访问的数据,它将失败。 It's quite a nice property since you cannot get data the user cannot get.这是一个非常好的属性,因为您无法获得用户无法获得的数据。

There is no best option here.这里没有最好的选择。 Application permissions are definitely easier.应用程序权限肯定更容易。 And if this app is only used in your organization and its okay from the administrators' side that your app can access any user's groups, then that might be what I'd go with.如果这个应用程序只在你的组织中使用,并且从管理员的角度来看你的应用程序可以访问任何用户的组,那么这可能是我会去的。

But if permissions need to be limited, go with delegated.但如果需要限制权限,请使用委派。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何根据Azure AD组进行授权? - How to do Authorization based on Azure AD groups? ASP.NET Core 2.0 Web API Azure Ad v2令牌授权无效 - ASP.NET Core 2.0 Web API Azure Ad v2 Token Authorization not working 使用 Vue JS 和 .Net Core Web API 之类的堆栈 - 我在哪里实施身份验证(Azure AD)? - With a stack like Vue JS and .Net Core Web API - where do I implement auth (Azure AD)? .NET Core 2-Web Api-Azure AD-用户为NULL - .NET Core 2 - Web Api - Azure AD - User is NULL .NET Core Web Api Azure AD and Swagger not authenticating - .NET Core Web Api Azure AD and Swagger not authenticating 带有 JWT 令牌的 Azure AD 多租户、.Net Core Web API - Azure AD Multi Tenant ,.Net Core Web API with JWT Token .Net Core Azure AD Cloud 如何登录用户并访问他们的 Azure AD 安全组以确定他们是否在一个组中 - .Net Core Azure AD Cloud how to get logged in user and access their Azure AD Security Groups to determine if they are in a group 如何在 .net 核心应用程序中进行基于组的授权? - How to do authorization based on groups in .net core app? Azure AD:从其他 .net Core Web API 调用 .net Core Web API - Azure AD: Call .net Core Web API from other .net Core Web API Azure AD B2C 声明能否用于 .NET Core Web 应用程序中的授权目的? - Can Azure AD B2C Claims be used for authorization purposes in a .NET Core Web App?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM