0
votes

I am a complete newbie to React and MSAL. I created an ASP.Net Core MVC WebApplication which connects to a Database in Azure. It uses .Net Core 3 and Identity UI. Now I have to create a react webapplication which uses the API of my MVC WebApplication.

I have a requirement to use our existing Azure AD to authenticate and to create a React Webapplication as an User Interface. My problem is where and how to start. The React Application should do the login process. The roles of the users should be managed in the existing database. Before the requirement the MVC Application handled the registration and login via identity UI and stored users and roles in the azure database. Now the users should authenticate via azure ad.

As far as I understand msal, the react application should redirect to the azure ad login and will aquire a token and the azure service will after successful login redirect back to the react app.

How does the react app give the token to my MVC Webapplication? How do i have to change the controllers that a token is passed and validated? do i have to setup some things for MSAL or authentication in the startup.cs?

I created a controller for testing purposes:

public class TestAPIController : Controller
{
    private readonly IBaseRepository<Articles> _BaseRepository;

    public TestAPIController(IBaseRepository<Articles> _BaseRepository)
    {
        this._BaseRepository = _BaseRepository;
    }

    // GET
    [HttpGet]
    [Route("GetArticles")]
    public async Task<IActionResult> GetArticles()
    {
        return Ok(JsonConvert.SerializeObject(await _BaseRepository.GetAllAsync()));
    }
}

My startup.cs looks like this:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<BaseContext>(opts => opts.UseSqlServer(Configuration.GetConnectionString("My_ConnectionString")));

        //CookiePolice
        services.Configure<CookiePolicyOptions>(options =>
        {
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddIdentity<ApplicationUser, IdentityRole>(options => 
        {
            options.SignIn.RequireConfirmedEmail = true;
            options.Stores.MaxLengthForKeys = 128;
        })
            .AddEntityFrameworkStores<BaseContext>()
            .AddDefaultUI()
            .AddDefaultTokenProviders();

        services.ConfigureApplicationCookie(options =>
        {
            options.Cookie.HttpOnly = true;
            options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
            options.LoginPath = $"/Identity/Account/Login";
            options.LogoutPath = $"/Identity/Account/Logout";
            options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
            options.SlidingExpiration = true;
            options.Cookie.Name = Common.Common_Ressources.LoginCookieName;
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
            .AddRazorPagesOptions(options =>
            {
                options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
                options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
            });
    }

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

        app.UseRouting();
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseAuthentication();
        app.UseCookiePolicy();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
            endpoints.MapControllers();
            endpoints.MapRazorPages();
        });
    }
}

Is there a small piece of code that will show me how the react app should aquire the token and pass it to the MVC Application? Could you please provide some details that i have to know before implementing this? I hope i can find the best way to achieve the goal of the requirement. Every little piece of code could help me understand it a little better.

Thanks in advance

1
@TonyJu unfortunately I need time for a different project and so this project must be continued later. I will come back to this thread later.Sebastian Siemens

1 Answers

0
votes

There are two main steps.

1.Protect your webapi(server) with azure ad. You can refer to this sample(TodoListService).

2.Get access token from your react app(client), then access webapi with the token.

Here is a complete video tutorial and source code on how to use MSAL with React to call Microsoft Graph.

The only different in your case will be that instead of calling Microsoft Graph, you will call your own API.