Microsoft.Identity.Web TokenAcquirerFactory not using redirect uri

Alexander Miller 0 Reputation points
2025-10-13T09:45:54.66+00:00

Hi,

I'm currently attempting to migrate a SharePoint Add-in project to authenticate via Azure AD. The Project is a .Net Framework 4.7.2 MVC web app. I've registered the TokenAcquirerFactory like so in the ConfigureAuth:

_redirectUri is my localhost 'https://localhost:44322/'

public void ConfigureAuth(IAppBuilder app)
{
    
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        Provider = new CookieAuthenticationProvider
        {
            OnResponseSignIn = context =>
            {
                // Force landing page after cookie is set
                context.Properties.RedirectUri = _redirectUri;
            }
        }
    });

    // Get an TokenAcquirerFactory specialized for OWINS
    OwinTokenAcquirerFactory owinTokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance<OwinTokenAcquirerFactory>();

    // Add the services you need.
    owinTokenAcquirerFactory.Services
        .Configure<ConfidentialClientApplicationOptions>(options =>
        {
            options.RedirectUri = _redirectUri;
        })        
        .AddDistributedTokenCaches();

    owinTokenAcquirerFactory.Services.AddDistributedSqlServerCache(options =>
    {
        options.ConnectionString = ConfigurationManager.AppSettings["Cache"];
        options.SchemaName = "dbo";
        options.TableName = "TokenCache";
        options.DefaultSlidingExpiration = TimeSpan.FromMinutes(90);
    });

    // Configure the web app.
    app.AddMicrosoftIdentityWebApp(owinTokenAcquirerFactory,
                                   updateOptions: options =>
                                   {
                                       options.RedirectUri = _redirectUri;
                                       options.PostLogoutRedirectUri = _redirectUri;
                                       /*options.Notifications = options.Notifications ?? new OpenIdConnectAuthenticationNotifications();
                                       options.Notifications.AuthorizationCodeReceived = context =>
                                       {
                                           context.AuthenticationTicket.Properties.RedirectUri = _redirectUri;
                                           return Task.FromResult(0);
                                       };*/
                                   });

    owinTokenAcquirerFactory.Build();
}

in my appsettings.json I have:

"AzureAd": {
  "Instance": "https://login.microsoftonline.com/",
  "Domain": "domain.onmicrosoft.com",
  "TenantId": "tenantid",
  "ClientId": "clientid",
  "ClientSecret": "secret",
  "RedirectUri": "https://localhost:44322/"
}

When running my app, I can successfully log-in from the home page (https://localhost:44322/) and am able to use the token to authenticate against SharePoint. However if I log-out or clear my cache and try to go to another endpoint on my app; after being prompted to log-in it will return to the same endpoint where the log-in was prompted (ie https://localhost:44322/Dashboard) which results in a Uri-mismatch error. In the Authorize request the redirect uri is always the url that the auth was prompted from. This is an issue as users will be given direct links to pages.

I am using System.Web.Mvc.AuthorizeAttribute [Authorize] to prompt the user to authenticate.

I have https://localhost:44322/ registered in azure entra as a redirect uri.

I have attempted to re-write the redirectUri by overriding the middleware in OpenIdConnectAuthenticationOptions.Notifications, however when the redirect uri is changed, the TokenAcquirerFactory fails to find an identity for the user, so I can't get their token and therefore I cannot authenticate against SharePoint.

The version of Microsoft.Identity.Web i'm using is 3.14.

I am unable to upgrade to .Net Core at the moment due to the size of the project and its dependencies.

Any help would be greatly appreciated,

Thanks.

Developer technologies | ASP.NET | Other
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Alexander Miller 0 Reputation points
    2025-10-13T14:56:33.95+00:00

    I was able to solve this myself by copying the implementation of RedirectToIdentityProvider from GitHub , and swapping the Context.ProtocolMessage.RedirectUri to my own redirect uri like so:

    app.AddMicrosoftIdentityWebApp(owinTokenAcquirerFactory,
                                   updateOptions: options =>
                                   {
                                       options.RedirectUri = _redirectUri;
                                       options.PostLogoutRedirectUri = _redirectUri;
                                       options.Notifications = options.Notifications ?? new OpenIdConnectAuthenticationNotifications();
                                       options.Notifications.RedirectToIdentityProvider = context =>
                                       {
                                           var loginHint = context.ProtocolMessage.GetParameter(OpenIdConnectParameterNames.LoginHint);
                                           if (!string.IsNullOrWhiteSpace(loginHint))
                                           {
                                               context.ProtocolMessage.LoginHint = loginHint;
    
                                               context.ProtocolMessage.SetParameter("x-anchormailbox", $"upn:{loginHint}");
                                               // delete the login_hint from the Properties when we are done otherwise
                                               // it will take up extra space in the cookie.
                                               context.ProtocolMessage.Parameters.Remove(OpenIdConnectParameterNames.LoginHint);
                                           }
    
                                           var domainHint = context.ProtocolMessage.GetParameter(OpenIdConnectParameterNames.DomainHint);
                                           if (!string.IsNullOrWhiteSpace(domainHint))
                                           {
                                               context.ProtocolMessage.DomainHint = domainHint;
    
                                               // delete the domain_hint from the Properties when we are done otherwise
                                               // it will take up extra space in the cookie.
                                               context.ProtocolMessage.Parameters.Remove(OpenIdConnectParameterNames.DomainHint);
                                           }
                                           context.ProtocolMessage.SetParameter(ClaimConstants.ClientInfo, "1");
                                           context.ProtocolMessage.SetParameter("x-client-brkrver", IdHelper.CreateTelemetryInfo());
    
                                           if (context.ProtocolMessage.IssuerAddress != null && context.ProtocolMessage.IssuerAddress.EndsWith("/authorize", StringComparison.OrdinalIgnoreCase))
                                           {
                                               context.ProtocolMessage.RedirectUri = _redirectUri;
                                           }
    
                                           return Task.CompletedTask;
                                       };
                                   });
    
    0 comments No comments

  2. Raymond Huynh (WICLOUD CORPORATION) 2,215 Reputation points Microsoft External Staff
    2025-10-14T04:12:26.3933333+00:00

    Hello Alexander Miller ,

    Thanks for the update! Glad to hear you got it working.

    Just to summarize for anyone else running into the same issue, the problem was that TokenAcquirerFactory didn’t always use the fixed redirect URI you set in the config. When users signed in from a deeper page (like /Dashboard), the login request used that page path as the redirect URI, which caused a mismatch error in Azure AD.

    The fix was to handle this in the RedirectToIdentityProvider notification and manually set the redirect URI before sending the request, for example:

    options.Notifications = options.Notifications ?? new OpenIdConnectAuthenticationNotifications(); options.Notifications.RedirectToIdentityProvider = context => 
    {     
    	if (context.ProtocolMessage.IssuerAddress?.EndsWith("/authorize", StringComparison.OrdinalIgnoreCase) == true)     
    	{         
    		context.ProtocolMessage.RedirectUri = _redirectUri; // your fixed redirect URI     
    	}     
    	return Task.CompletedTask; 
    };
    

    After adding that, the login flow always uses the same redirect URI and the token acquisition works fine.

    If you’re satisfied with the explanation, please kindly accept it.

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.