Reputation: 2229
Net core web application. I am trying to implement groups based authorization in my .Net core app. I am trying to call groups from Microsoft graph. I have some confusion here. Below are the steps.
These are the steps I taken. After this I have added relevant code to implement swagger as below. 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.
[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
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.
Now I want to get all the groups from Microsoft graph API end point. I need little clarification on below.
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.
Upvotes: 0
Views: 824
Reputation: 58723
Now I already have token and can I use same token to call Microsoft graph API?
No. The token is for your API. You need to get another token for MS Graph API using e.g. the MSAL library (https://www.nuget.org/packages/Microsoft.Identity.Client/).
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. delegated permission -> Used to call graph API on behalf of user Application permission -> App itself calls Microsoft graph API. Using client credentials flow It generates token and passes to Microsoft graph and authenticates.
In my case I have logged in user ad I am trying to hit Microsoft graph. 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.
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. 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.
With delegated permissions, you can use the same scopes.
.default
will use the permissions assigned to the app in the registration.
But you will also have to include the access token that your API received.
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.
Upvotes: 1