UPN claim is missing during authentication with a multi tenant app registration.

Mohammed Nagpur 1 Reputation point
2020-11-24T14:38:28.713+00:00

I am currently working on a C# webapp that is uses multi tenant authentication via UseCookieAuthentication to authenticate our webapp against Azure AD. The issue that I am encountering is that after authentication, the UPN claim is not populated in the ExternalLoginInfo.ExternalIdentity object.

Does anyone know what steps I will need to take in order to get the UPN Claim to appear in a multi tenant authentication request?

Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
20,094 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. 2020-11-24T18:31:00.663+00:00

    Hello @Mohammed Nagpur , please share the code where you setup Azure AD authentication and what version of .NET are you using. UseCookieAuthentication is used to setup the cookie middleware but not Azure AD authentication.

    0 comments No comments

  2. Mohammed Nagpur 1 Reputation point
    2020-11-25T06:18:04.16+00:00

    Hello anonymous user-msft, .NET version is .net framework 4.7.2 and below is the code

    public void Configuration(IAppBuilder app)  
            {              
                app.CreatePerOwinContext<AppUserManager>(AppUserManager.Create);  
                app.CreatePerOwinContext<AppSignInManager>(AppSignInManager.Create);  
      
                app.UseCookieAuthentication(new CookieAuthenticationOptions  
                {  
                    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,  
                    LoginPath = new PathString("/User/Login"),  
                    Provider = new CookieAuthenticationProvider  
                    {  
                        OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<AppUserManager, AppUserDTO>(  
                            validateInterval: TimeSpan.FromMinutes(30),  
                            regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))  
                    }  
                });  
                app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);  
      
                app.UseMicrosoftAccountAuthentication(  
                    clientId: "",  
                    clientSecret: "");  
            }  
    

    public class AppUserManager : UserManager<AppUserDTO>
    {
    public AppUserManager(IUserStore<AppUserDTO> store)
    : base(store)
    { }
    public static AppUserManager Create(IdentityFactoryOptions<AppUserManager> options, IOwinContext context)
    {
    //AppUserManager manager = null;
    var manager = new AppUserManager(new AppUserStore<AppUserDTO>());
    return manager;
    }
    }

    public class AppSignInManager : SignInManager<AppUserDTO, string>
    {
    public AppSignInManager(AppUserManager userManager, IAuthenticationManager authenticationManager)
    : base(userManager, authenticationManager)
    {
    }

        public override Task<ClaimsIdentity> CreateUserIdentityAsync(AppUserDTO user)  
        {  
            return user.GenerateUserIdentityAsync((AppUserManager)UserManager);  
        }  
    
        public static AppSignInManager Create(IdentityFactoryOptions<AppSignInManager> options, IOwinContext context)  
        {  
            var x = options;  
            return new AppSignInManager(context.GetUserManager<AppUserManager>(), context.Authentication);  
        }  
    }  
    

    public class AppUserStore<TUser> :
    IUserStore<TUser>,
    IUserStore<TUser, string>,
    IDisposable,
    IUserLockoutStore<TUser, string>
    where TUser : AppUserDTO, new()
    {
    public IQueryable<TUser> Users => throw new NotImplementedException();

        public AppUserStore()  
        {  
        }  
        public System.Threading.Tasks.Task CreateAsync(TUser user)  
        {  
            throw new NotImplementedException();  
        }  
    
        public System.Threading.Tasks.Task DeleteAsync(TUser user)  
        {  
            throw new NotImplementedException();  
        }  
    
        
    
        public Task<TUser> FindByIdAsync(string userId)  
        {  
            var x = new TUser  
            {  
                Id = userId,  
                UserName = userId  
            };  
            return System.Threading.Tasks.Task.FromResult(x);  
        }  
    
        public Task<TUser> FindByNameAsync(string userName)  
        {  
            var x = new TUser  
            {  
                Id = userName,  
                UserName = userName  
            };  
            return System.Threading.Tasks.Task.FromResult(x);  
    
            //throw new NotImplementedException();  
        }  
    
        public System.Threading.Tasks.Task<int> GetAccessFailedCountAsync(TUser user)  
        {  
            return System.Threading.Tasks.Task.FromResult(0);  
        }  
    
        public System.Threading.Tasks.Task<bool> GetLockoutEnabledAsync(TUser user)  
        {  
            return System.Threading.Tasks.Task.FromResult(false);  
        }  
    
        public System.Threading.Tasks.Task<DateTimeOffset> GetLockoutEndDateAsync(TUser user)  
        {  
            return System.Threading.Tasks.Task.FromResult(DateTimeOffset.Now);  
        }  
    
        public System.Threading.Tasks.Task<int> IncrementAccessFailedCountAsync(TUser user)  
        {  
            return System.Threading.Tasks.Task.FromResult(0);  
        }  
    
        public System.Threading.Tasks.Task ResetAccessFailedCountAsync(TUser user)  
        {  
            return System.Threading.Tasks.Task.FromResult(0);  
        }  
    
        public System.Threading.Tasks.Task SetLockoutEnabledAsync(TUser user, bool enabled)  
        {              
            return System.Threading.Tasks.Task.FromResult(0);  
        }  
    
        public System.Threading.Tasks.Task SetLockoutEndDateAsync(TUser user, DateTimeOffset lockoutEnd)  
        {  
            return System.Threading.Tasks.Task.FromResult(0);  
        }  
    
        public System.Threading.Tasks.Task UpdateAsync(TUser user)  
        {  
            return System.Threading.Tasks.Task.FromResult(0);  
        }  
        public void Dispose()  
        {  
            //throw new NotImplementedException();  
        }  
    }  
    

    }

    public class ChallengeResult : HttpUnauthorizedResult
    {
    #region Properties
    public string LoginProvider { get; set; }
    public string RedirectUri { get; set; }
    public string UserId { get; set; }
    private const string XsrfKey = "XsrfId";
    #endregion

        #region Constructor  
        public ChallengeResult(string provider, string redirectUri)  
            : this(provider, redirectUri, null)  
        {  
        }  
    
        public ChallengeResult(string provider, string redirectUri, string userId)  
        {  
            LoginProvider = provider;  
            RedirectUri = redirectUri;  
            UserId = userId;  
        }  
        #endregion  
    
        #region Override  
        public override void ExecuteResult(ControllerContext context)  
        {  
            var properties = new AuthenticationProperties { RedirectUri = RedirectUri };  
            if (UserId != null)  
            {  
                properties.Dictionary[XsrfKey] = UserId;  
            }  
            context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);  
        }  
        #endregion  
    }  
    

    Controller

    [HttpPost]
    [AllowAnonymous]
    public ActionResult ExternalLogin(string provider, string returnUrl)
    {
    // Request a redirect to the external login provider
    return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "User", new { ReturnUrl = returnUrl }));
    }

    public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
    {
    bool? loginSuccessful = null;
    ExternalLoginInfo loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
    if (loginInfo == null || !loginInfo.ExternalIdentity.IsAuthenticated)
    {
    return RedirectToAction("Login");
    }
    loginSuccessful = true;

            return RedirectToAction("Index", "Home");    
        }  
    

    cshtml
    using (Html.BeginForm("ExternalLogin", "User", new { provider = "Microsoft", returnUrl = "" }))
    {
    <button type="submit" class="external-button" id="Microsoft" name="provider" value="Microsoft" title="Log in using your Microsoft account"></button>
    }

    42513-externallogininfo.png

    In Image it is ExternalLoginInfo Object which I am getting after login. In Claims there is nameidentifier,name,emailaddress I want one additional claim here UPN(User Principal Name).
    How to add this additional claim?

    0 comments No comments