0

After spending couple of days and trying various solutions reccomended by the community, I still could not find a solution for this issue.
I have multiple applications which need to implement single sign-on. All the applicatiions has two projects. Front End application and Backend application. Front end applications are written in ReactJS and Backends are written in .Net core 2.2. All the applications are hosted in Azure app services. As an example, User Authentication system has two applications authweb.mydomain.org(ReactJS) and authbackend.mydomain.org(.Net Core). All other applications should be authenticated through this application for an instance, app1 has two web applications app1web.mydomain.org and app1backend.mydomain.org
I selected cookie authentication method to implement this single sign-on (not sure this is the most perfect selection for this scnario). User log in to the auth application (authweb.mydomain.org) using his/her username and password. Then backend(authbackend.mydomain.org) validate the user and genrate auth cookies if credentials are valid. Here I am not going to mention the source code of my ReactJs front end

authbackend.mydomain.org StartUp.cs

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.AddDataProtection()
       .SetApplicationName("SharedCookieApp");

        services.AddAuthentication(options =>
        {
            options.DefaultScheme = "Cookies";
        })
        .AddCookie("Cookies", options =>
        {
            options.Cookie.Name = "auth_cookie";
            options.Cookie.SameSite = SameSiteMode.None;
            options.LoginPath = "/Account/Login/";
            options.LogoutPath = "/Account/Logout/";
            options.Cookie.Domain = ".mydoamin.org";
            options.Events = new CookieAuthenticationEvents
            {
                OnRedirectToLogin = redirectContext =>
                 {
                     redirectContext.HttpContext.Response.StatusCode = 401;
                     return Task.CompletedTask;
                 }
            };
            //options.DataProtectionProvider = DataProtectionProvider.Create(new DirectoryInfo(@"c:\shared-auth-ticket-keys\"));
        });

        services.AddHttpContextAccessor();

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        services.AddCors(options =>
        {
            options.AddPolicy("AllowSpecificOrigin",
                builder => builder.AllowAnyHeader().AllowAnyMethod().SetIsOriginAllowed(_ => true).AllowCredentials());
        });
    }

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

        app.UseCors("AllowSpecificOrigin");
        app.UseAuthentication();

        app.UseMvc();
    }
}

authbackend.mydomain.org AccountController.cs where authenticate the user

[EnableCors("AllowSpecificOrigin")]
[Route("[controller]/[action]")]
[ApiController]
public class AccountController : ControllerBase
{
    [HttpPost]
    [AllowAnonymous]
    public async Task<UserObject> Login([FromBody] UserLogin user)
    {
        try
        {
            if(user.UserName=="demo" && user.Password == "demo")
            {
                UserObject loggedInUser = UserObject.GetUser();

                var identity = new ClaimsIdentity("Cookies");
                identity.AddClaim(new Claim(ClaimTypes.Name, loggedInUser.UserName));
                identity.AddClaim(new Claim(ClaimTypes.GivenName, loggedInUser.FirstName));
                identity.AddClaim(new Claim(ClaimTypes.Surname, loggedInUser.LastName));
                var principal = new ClaimsPrincipal(identity);
                await HttpContext.SignInAsync("Cookies",principal);

                return loggedInUser;
            }
            return null;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    [HttpPost]
    public async Task<bool> Logout()
    {
        await HttpContext.SignOutAsync();
        return true;
    }
}

Once user loged in to the auth app, auth cookies are generated and it rederects the user to the home page of the auth app

authbackend.mydomain.org HomeController.cs

[Authorize(AuthenticationSchemes= "Cookies")]
[EnableCors("AllowSpecificOrigin")]
[Route("[controller]/[action]")]
[ApiController]
public class HomeController : ControllerBase
{
    public string Index()
    {
        var usr = User;
        var cookie = Request.Cookies;
        var headerCookie = Request.HttpContext.Request.Cookies;

        return "User is authenticated";
    }
}

Cookies are generated as expected
enter image description here

Now user wants to access app1web.mydomain.org using same authentication Cookie. These cookiess are apprar on the browser cookie section when I open the app1web.mydomain.org. This application validate the user in it's backend(app1backend.mydomain.org) in order to make sure that user has authenicated.
app1backend.mydomain.org Startup.cs

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.AddDataProtection()
       //.PersistKeysToFileSystem(new DirectoryInfo(@"c:\shared-auth-ticket-keys\"))
       .SetApplicationName("SharedCookieApp");

        services.AddAuthentication(options =>
        {
            options.DefaultScheme = "Cookies";
        })
        .AddCookie("Cookies", options =>
        {
            options.Cookie.Name = "auth_cookie";
            options.Cookie.SameSite = SameSiteMode.None;
            options.LoginPath = "/Account/Login/";
            options.LogoutPath = "/Account/Logout/";
            options.Cookie.Domain = ".mydomain.org";
            options.Events = new CookieAuthenticationEvents
            {
                OnRedirectToLogin = redirectContext =>
                {
                    redirectContext.HttpContext.Response.StatusCode = 401;
                    return Task.CompletedTask;
                }
            };

        });



        services.AddHttpContextAccessor();

        services.AddCors(options =>
        {
            options.AddPolicy("AllowSpecificOrigin",
                builder => builder.AllowAnyHeader().AllowAnyMethod().SetIsOriginAllowed(_ => true).AllowCredentials());
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

    // 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();
        }
        app.UseCors("AllowSpecificOrigin");
        app.UseAuthentication();

        app.UseMvc();

    }
}

app1backend.mydomain.org HomeController.js

[Authorize(AuthenticationSchemes = "Cookies")]
[EnableCors("AllowSpecificOrigin")]
[Route("[controller]/[action]")]
[ApiController]
public class HomeController : ControllerBase
{
    [HttpGet]
    public string Index()
    {
        var usr = User;
        var cookie = Request.Cookies;
        var headerCookie = Request.HttpContext.Request.Cookies;
        return Request.HttpContext.Request.Cookies["auth_cookie"];
    }
}

When I call this above Index method, 401-Unauthorized returns from backend. But cookies are passing to the backend.
This is working fine with localhost but not autheticating the app1 when I hosted applications to Azure App Services. Please someone explain me what I have missed here. Your help is highly appreciated.

Rama
  • 187
  • 1
  • 6
  • 20

0 Answers0