【问题标题】:How to do Azure AD groups based authorization?如何进行基于 Azure AD 组的授权?
【发布时间】:2024-01-22 13:41:01
【问题描述】:

net core web api 应用程序。我已经为我的 web api 应用程序配置了招摇。我正在从 swagger 进行身份验证和授权,但我没有 webapp 或 SPA。现在我想根据组进行授权。当我看到 JWT 令牌时,我看到了 hasgroups: true 而不是组 ID。如果超过 5 个组与用户关联,则会更改此设置。如果我的理解有误,请纠正我。所以我现在有了hasgroups:真的。所以要获得组,我需要调用 graph api。从图形 API 获取组后,我需要创建策略。这是我的理解,如果我走错了路,请纠正我。现在我有了下面的 web api 应用程序。

Startup.cs

public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
            azureActiveDirectoryOptions = Configuration.GetSection("AzureAd").Get<AzureActiveDirectoryOptions>();
            swaggerUIOptions = Configuration.GetSection("Swagger").Get<SwaggerUIOptions>();
        }

        public IConfiguration Configuration { get; }
        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
                       },
                   };
               });

            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();
        }
    }

我有如下 API。

[Authorize]
    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        private IHttpContextAccessor _httpContextAccessor;
        public ValuesController(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }
        // GET api/values
        [HttpGet]
        public ActionResult<string> Get()
        {
            string owner = (User.FindFirst(ClaimTypes.Name))?.Value;
            var accessToken = _httpContextAccessor.HttpContext.Request.Headers["Authorization"];
            return owner;
        }
    }

现在登录后我可以访问 API。现在我想根据我想要控制授权的组来拥有类似 Authorize(admin/user) 的东西。现在我遇到了麻烦,我应该在哪里调用graph api并获取组。有人可以帮助我理解这一点吗?任何帮助,将不胜感激。谢谢

【问题讨论】:

    标签: asp.net-core .net-core azure-active-directory authorization microsoft-graph-api


    【解决方案1】:

    您正在使用哪个协议和哪个流程。 ?

    【讨论】:

    • Azure v2 协议和隐式流
    【解决方案2】:

    是的,隐含流对组声明有限制。要使用 Microsoft Graph 获取当前用户的群组,您可以尝试以下方式:

    1. 使用on-behalf-of grant获取访问令牌,允许API以用户身份调用MS Graph,here是代码示例。

    2. 使用client credentials flow在web api中获取Microsoft Graph的访问令牌,此流程使用应用程序的权限,没有用户上下文。代码示例 here 适用于使用 ADAL 的 Azure AD V1.0。 here 是使用 MSAL 的 Azure AD V2.0 的代码示例。

    【讨论】:

      最近更新 更多