Azuread and Identity authentication in the same Project

Asked

Viewed 24 times

1

Applying: Built in . NET Core 2.2

Is it possible to have two forms of authentication in a single C# project? I found myself in the following scenario:

1 - Users who are employees of the company use Azuread to perform authentication, and this works properly;

2 - Users who are not collaborators, but partners, must perform the authentication in a way other than via Azure.

PS: I don’t have the option to create Guest users in Azuread.

3 - Both employees and partners access the same application.

I tried to add a new form of authentication in the Application Startup, but I don’t know if it’s the best strategy. The section below is Azuread authentication, which is OK.

services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
            .AddAzureAD(options => Configuration.Bind("AzureAd", options));

services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
        {
            options.Events = new OpenIdConnectEvents
            {
                OnRedirectToIdentityProvider = async ctxt =>
                {
                    await Task.Yield();
                },
                OnMessageReceived = async ctxt =>
                {
                    await Task.Yield();
                },
                OnTicketReceived = async ctxt =>
                {
                    if (ctxt.Principal.Identity is ClaimsIdentity identity)
                    {
                        //alguma funcionalidade
                    }

                    await Task.Yield();
                },
            };
        });

I also read about creating Users via Identity, but I was wondering if the application will understand where to perform the User.Identity verification, whether in Azuread or in another authentication schema.

Task SignInAsync(ApplicationUser user, bool isPersistent)

Someone’s been through something similar ?

1 answer

0

After some research, I arrived at the following solution:

Documentation: https://docs.microsoft.com/pt-br/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-3.0&tabs=aspnetcore2x

For Ports that will be authenticated to "partners" indicated in the question, I have opted for authentication via Cookies.

The first step is to define the authentication Schemas your application will use. In my case, in Configureservices in Startup.Cs of my Webapp, it was as follows:

public void ConfigureServices(IServiceCollection services)
{
    //Código inicial omitido...

    services.AddAuthentication(sharedOptions =>
    {
        sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        sharedOptions.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    }
    )
    .AddAzureAD(options => Configuration.Bind("AzureAd", options))
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme);

    services.AddAuthorization(options =>
    {
        var policy = new AuthorizationPolicyBuilder(AzureADDefaults.AuthenticationScheme, CookieAuthenticationDefaults.AuthenticationScheme);
        policy = policy.RequireAuthenticatedUser();
        options.DefaultPolicy = policy.Build();
    });
}

Once this is done, we will add the authorization. Here it adds the policys for one form of authentication or another:

public void ConfigureServices(IServiceCollection services)
{
    //Código inicial omitido...

    services.AddAuthorization(options =>
    {
        var policy = new AuthorizationPolicyBuilder(AzureADDefaults.AuthenticationScheme, CookieAuthenticationDefaults.AuthenticationScheme);
        policy = policy.RequireAuthenticatedUser();
        options.DefaultPolicy = policy.Build();
    });
}

And to authenticate users via Cookies, I have created a Controller that will create my Identity in Runtime. In this case, note the [Allowanonymous] decoration, so that the authentication scope is ignored for this Action.

[AllowAnonymous]
[HttpPost]
public IActionResult Index()
{
    //Dados vindos de um Post Qualquer...
    string email = string.IsNullOrEmpty(Request.Form["Email"]) ? string.Empty : Request.Form["Email"].ToString();
    string senha = CloudlabFunctions.GetHashMd5(string.IsNullOrEmpty(Request.Form["Password"]) ? string.Empty : Request.Form["Password"].ToString());

    Usuario ClasseDoUsuario = null;

    using (BusUsuario Bus = new BusUsuario(_config))
    {
        ClasseDoUsuario = Bus.GetUsuario(email, senha);
    }

    if (ClasseDoUsuario != null)
    {
        var claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, ClasseDoUsuario.Nome),
                    new Claim("Endereco", ClasseDoUsuario.Endereco),
                    new Claim("Cep", ClasseDoUsuario.Cep),

                    //E outras Claims que você precisar.
                };

        var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);

        var authProperties = new AuthenticationProperties
        {
            //Pode-se adicionar propriedades de autenticação específicas, como por exemplo, se o cookie é peristente entre sessões, data de expiração, se permite atualização, etc.
        };

        ClaimsPrincipal Usuario = new ClaimsPrincipal(claimsIdentity);

        Task res = HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, Usuario, authProperties);
        res.Wait();


        return RedirectToAction("Index", "Home");
    }
    else
    {
        return Redirect("PaginaDeErroQualquer");
    }
}

That’s more or less the path of the stones.

Abçs !

Browser other questions tagged

You are not signed in. Login or sign up in order to post.