3

I currently have and application that is using Identity to authorize users. I need to change it to use Azure AD to login. After being authenticated through azure I need to use the information of the logged in user that we have in the identity database. After the user is authenticated I get a NullReferenceException: Object reference not set to an instance of an object. and fails at this point: ApplicationUser user = await manager.FindByNameAsync(context.Principal.Identity.Name);

enter image description here

```
    public void ConfigureServices(IServiceCollection services)
{
  services.AddAuthentication().AddOpenIdConnect(c =>
  {
      c.Authority = "https://login.microsoftonline.com/common";
      c.ClientId = "<insert-registered-guid>";
      c.TokenValidationParameters = new TokenValidationParameters
      {
          ValidateIssuer = false
      };
      c.Events.OnTokenValidated = async context =>
      {
          UserManager<ApplicationUser> manager = context.HttpContext.RequestServices.GetService<UserManager<ApplicationUser>>();
          SignInManager<ApplicationUser> signIn = context.HttpContext.RequestServices.GetService<SignInManager<ApplicationUser>>();
          ApplicationUser user = await manager.FindByNameAsync(context.Principal.Identity.Name);
          if (user != null)
          {
              await signIn.SignInAsync(user, false);
          }
      };
  });
}

// HomeController.cs
using Microsoft.AspNetCore.Authentication.OpenIdConnect;

public class HomeController : Controller
{
  [AllowAnonymous]
  public IActionResult LoginWithAzure()
  {
      string redirectUrl = Url.Content("~/");
      return Challenge(new AuthenticationProperties { RedirectUri = redirectUrl }, OpenIdConnectDefaults.AuthenticationScheme);
  }
}
```

UPDATE:

I was able to get past the error because I was missing

services.AddIdentity

Now the issue is that it gets stuck in a loop inside the OnTokenValidated.

 UserManager<ApplicationUser> manager = context.HttpContext.RequestServices.GetService<UserManager<ApplicationUser>>();
                SignInManager<ApplicationUser> signIn = context.HttpContext.RequestServices.GetService<SignInManager<ApplicationUser>>();
                ApplicationUser user = await manager.FindByNameAsync(context.Principal.Identity.Name);

          


                if (user != null)
                {
                    await signIn.SignInAsync(user, false);
                }

after the if statement it goes back to the manager line.

Fer
  • 41
  • 5

1 Answers1

1

The above solution was not working so I changed it.

Startup.cs was changed to the following:

        //  Add Azure AD authentication
        services.AddAuthentication(defaultScheme: AzureADDefaults.AuthenticationScheme)
            .AddAzureAD(options => Configuration.Bind("AzureAd", options));

AccountController.cs was changed to this:

 [AllowAnonymous]
    [HttpGet]
    public ChallengeResult InternalSignIn(string returnUrl = "/")
    {
        var redirectUrl = Url.Action(nameof(ExternalLoginCallback));
        var properties = signInManager.ConfigureExternalAuthenticationProperties(AzureADDefaults.AuthenticationScheme, redirectUrl);
        return new ChallengeResult(AzureADDefaults.AuthenticationScheme, properties);
    }


   
    [HttpGet]
    public async Task<IActionResult> ExternalLoginCallback()
    {
        var info = await signInManager.GetExternalLoginInfoAsync();

       
        if (info is null)
        {
            
            return BadRequest();
        }
      
        var signInResult = await signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: false);
       
      
        var email = info.Principal.FindFirstValue(ClaimTypes.Name);


        var user = await userManager.FindByEmailAsync(email);
        IdentityResult result;
        if (user != null)
        {
            var logins = await userManager.GetLoginsAsync(user);
            if (!logins.Any())
            {
                result = await userManager.AddLoginAsync(user, info);
                if (!result.Succeeded)
                {
                   
                    return View();
                }
            }

            await signInManager.SignInAsync(user, isPersistent: false);
            return RedirectToAction(nameof(HomeController.Index),"Home");
        }


        return StatusCode(500, "Internal server error");
    }
Fer
  • 41
  • 5