Net основной проект веб-API. Я зарегистрировал приложение в azure AD для приложения Web API. Я настроил swagger и зарегистрировал еще одно приложение в Azure AD. Я пытаюсь сделать авторизацию на моем веб-сайте по группам. В appsettings. json У меня есть все значения.
Ниже мой стартап выглядит так.
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("2a39995a-8fd1-410e-99e2-11cf6046090d"));
});
});
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();
}
Когда я запускаю приложение, используя https://localhost: 44319 / swagger
Теперь у меня есть кнопка Авторизоваться в моем чванство. Всякий раз, когда я пытаюсь авторизоваться, мне будет предложено ввести имя пользователя и пароль. Аутентификация работает как положено. Далее я хочу нажать / api / values / users / {id}. контроллер выглядит ниже.
[Authorize(Policy = "GroupsCheck")]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
}
Мне нужна групповая авторизация. При запуске я добавил политику.
services.AddAuthorization(options =>
{
options.AddPolicy("GroupsCheck", policy =>
{
policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
policy.RequireAuthenticatedUser();
policy.Requirements.Add(new GroupsCheckRequirement("2a39995a-8fd1-410e-99e2-11cf6046090d"));
});
});
Ниже - мой GroupsCheckHandler.cs
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context,
GroupsCheckRequirement requirement)
{
GraphServiceClient client = await MicrosoftGraphClient.GetGraphServiceClient();
//Tried to get user and dint work for me
var user = await client.Me.Request().GetAsync();
//Here exception occurs
var groupList = await client.Groups.Request().GetAsync();
var result = false;
foreach (var group in groupList)
{
if (requirement.groups.Equals(group.Id))
{
result = true;
}
}
if (result)
{
context.Succeed(requirement);
}
}
Ниже - мой MicrosoftGraphClient.cs
public static async Task<GraphServiceClient> GetGraphServiceClient()
{
// Get Access Token and Microsoft Graph Client using access token and microsoft graph v1.0 endpoint
var delegateAuthProvider = await GetAuthProvider();
// Initializing the GraphServiceClient
graphClient = new GraphServiceClient(graphAPIEndpoint, delegateAuthProvider);
return graphClient;
}
private static async Task<IAuthenticationProvider> GetAuthProvider()
{
AuthenticationContext authenticationContext = new AuthenticationContext(authority);
ClientCredential clientCred = new ClientCredential(clientId, clientSecret);
// ADAL includes an in memory cache, so this call will only send a message to the server if the cached token is expired.
AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenAsync(graphResource, clientCred).ConfigureAwait(false);
var token = authenticationResult.AccessToken;
var delegateAuthProvider = new DelegateAuthenticationProvider((requestMessage) =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token.ToString());
return Task.FromResult(0);
});
return delegateAuthProvider;
}
Now При каждом запуске при попытке получить доступ к моему API получаю исключение в groupshandler.cs
Microsoft.Graph.ServiceException: Code: Authorization_RequestDenied
Message: Insufficient privileges to complete the operation.
Я добавил разрешение графика Microsoft в свое приложение в azure AD. Мне нравится читать группы, нам нужно согласие администратора. Здесь я борюсь. Ниже разрешения я вижу в приложении для предприятий в azure объявлении на вкладке согласия пользователя.
![Enterprise Apps in Azure AD](https://i.stack.imgur.com/qcX7b.png)
Ниже представлен формат токена, созданный с помощью authenticationContext.AcquireTokenAsyn c method
Другая сторона, этот токен также выглядит странно для меня, и в нем пропущено много полей.
Теперь кто-то, пожалуйста, помогите мне, какие неправильные шаги я сделал в приведенной выше реализации. Может ли кто-то помочь в этом отношении. Любая помощь будет очень полезна для меня. Большое спасибо