Access Sharepoint files using Graph in my .net core web application

Andy Casey 40 Reputation points
2023-02-15T00:32:26.2333333+00:00

I have a web application written using asp.net core and it authenticates via Identity. Everyone who accesses our web app has an azure/microsoft ID. I have the app registration set up, with regard to API Permissions, as delegated. From what I understand, this means that when a user logs into my web application, and accesses Sharepoint files from the web application, that it is their credentials that are used to access the files on the sharepoint site. So, if they don't have access, they can't get the files. If they do, they can. I have been trying to find a simple code example that shows me how to access sharepoint files using Microsoft Graph, that are actually up to date. I took a pluralsite course on it, which was horribly out of date. I've looked at code examples on the Microsoft Graph site and all of them date from 2016 to 2020. The closest information I can find is an example dated early 2022, and that doesn't even help. I've seen lot's of Postman solutions, but that doesn't help because my users are not accessing my website using Postman. The code below is code I got from a StackOverflow answer, which doesn't work. I've tried variations of the code and I just can't get it to work. What I need is a simple, a to z sample code that goes from getting the access, to getting the files on the Sharepoint site. I can't find anything current. Can anyone help me?

            //var scopes = new[] { "https://mysite.sharepoint.com/.default" };
            //var scopes = new[] { "https://graph.microsoft.com/.default" };
            var scopes = new[] { "https://graph.microsoft.com/User.ReadWrite.All" };

            var tenantId = "MyTenantId";
            var clientId = "MyClientId";
            var clientSecret = "ShhhItsASecret";

            var client = new RestClient("https://login.microsoftonline.com/mysiteID/oauth2/v2.0/token");
            var request = new RestRequest();
            request.Method = Method.Post;
            request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
            request.AddParameter("client_id", clientId);
            request.AddParameter("client_secret", clientSecret);
            request.AddParameter("scope", "https://graph.microsoft.com/User.ReadWrite.All");
            request.AddParameter("response_type", "code");
            request.AddParameter("grant_type", "client_credentials");
            RestResponse response = client.Execute(request);

            TokenModel tokenModel = new TokenModel();

            JsonConvert.PopulateObject(response.Content, tokenModel);

            var authorizationCode = tokenModel.access_token;

            // using Azure.Identity;
            var options = new TokenCredentialOptions
            {
                AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
            };

            // https://learn.microsoft.com/dotnet/api/azure.identity.authorizationcodecredential
            var authCodeCredential = new AuthorizationCodeCredential(tenantId, clientId, clientSecret, authorizationCode, options);

            Azure.Core.AccessToken accessToken = new Azure.Core.AccessToken();

            try
            {
                 accessToken = await authCodeCredential.GetTokenAsync(new Azure.Core.TokenRequestContext(scopes) { });
            }
            catch (System.Exception ex)
            {

                throw;
            }
Microsoft 365 and Office | SharePoint | For business | Windows
Microsoft Security | Microsoft Graph
Developer technologies | C#
{count} votes

2 answers

Sort by: Most helpful
  1. RaytheonXie_MSFT 40,471 Reputation points Microsoft External Staff
    2023-02-15T08:07:21.9366667+00:00

    Hi @Andy Casey

    Here is a sample demonstrates about how to use the Microsoft Graph .NET SDK to access data in Office 365 from ASP.NET Core apps. You can refer to the code in the github

    https://github.com/microsoftgraph/msgraph-sample-aspnet-core


    If the answer is helpful, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

  2. Andy Casey 40 Reputation points
    2023-05-09T18:42:44.3366667+00:00

    The code below is what I was able to use to get this to work. The only drawback to this solution is that everything must be managed in Azure. This means, roles, users, etc... Which is fine if everyone using your app is in the same organization, but you can't add external users unless you make them part of your Azure AD instance. For now, this works because this is an internal application. However, we do have another application, which is used by external users as will as internal users, and we want to provide the SharePoint access that we have in the other app. There doesn't seem to be a way to connect an Azure AD account managed in the cloud, with one managed in a local DB. Ideally, we want to authenticate with Azure AD, but we want to Authorize, using identity roles, claims, etc.. at the local DB level. I think for that, we will need to use a Managed Identity.

    However, this code will work for an internal application. If I'm wrong, please show me where I'm wrong.

    using Microsoft.AspNetCore.Authentication.OpenIdConnect;
    using Microsoft.AspNetCore.Authorization
    using Microsoft.AspNetCore.Mvc.Authorization;
    using Microsoft.AspNetCore.Rewrite;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Identity.Web;
    using Microsoft.Identity.Web.UI;
    
    var builder = WebApplication.CreateBuilder(args);
    
    var initialScopes = builder.Configuration["DownstreamApi:Scopes"]?.Split(' ') ?? builder.Configuration["MicrosoftGraph:Scopes"]?.Split(' ');
    
    builder.Services.AddDbContext<InvoiceAuditingContext>(options =>
                    options.UseSqlServer(
                        builder.Configuration.GetConnectionString("DefaultConnection")));
    //builder.Services.AddDatabaseDeveloperPageExceptionFilter();
    
    // Add services to the container.
    builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
        .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
            .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
                .AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph"))
                .AddInMemoryTokenCaches();
    
    builder.Services.AddAuthorization(options =>
    
    {
        options.FallbackPolicy = options.DefaultPolicy;
    });
    
    #region Interfaces
    builder.Services.AddScoped<IIARepo, IARepo>();
    
    #region IA
    
    builder.Services.AddTransient<IIAObservationLogProvider, IAObservationLogProvider>();
    builder.Services.AddTransient<IIADataImportExportProvider, IADataImportExportProvider>();
    
    #endregion
    
    #region Global
    builder.Services.AddTransient<IImportColumnProvider, ImportColumnProvider>();
    
    #endregion
    
    #region CB Components
    //Excel
    builder.Services.AddTransient<IExcelExtensionsProvider, ExcelExtensionsProvider>();
    builder.Services.AddTransient<IExcelFileAndSheetValidationProvider, ExcelFileAndSheetValidationProvider>();
    builder.Services.AddTransient<IExcelExportProvider, ExcelExportProvider>();
    #endregion
    
    #endregion
    
    builder.Services.AddControllersWithViews(options =>
    {
        var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();
        options.Filters.Add(new AuthorizeFilter(policy));
    });
    builder.Services.AddRazorPages()
        .AddMicrosoftIdentityUI();
    
    var app = builder.Build();
    
    // Configure the HTTP request pipeline.
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Home/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }
    
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    
    app.UseRouting();
    
    app.UseAuthentication();
    app.UseAuthorization();
    
    app.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
    app.MapRazorPages();
    app.MapControllers();
    
    app.Run();
    
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.