C# Azure AD B2C-身份验证质询未触发身份验证

C# Azure AD B2C-身份验证质询未触发身份验证,c#,asp.net-mvc,authentication,azure-active-directory,azure-ad-b2c,C#,Asp.net Mvc,Authentication,Azure Active Directory,Azure Ad B2c,我在玩Azure广告B2C,我有一个奇怪的行为。我根据这个示例创建了一个新的应用程序:它就像一个符咒 然后我将代码移植到一个现有的应用程序中,我遇到了一个问题。在控制器中,我有以下方法: [PolicyAuthorize(Policy = "b2c_1_signin01")] public ActionResult Index() { var vm = new IndexModel { FundsDocumentsModel = new FundsDocument

我在玩Azure广告B2C,我有一个奇怪的行为。我根据这个示例创建了一个新的应用程序:它就像一个符咒

然后我将代码移植到一个现有的应用程序中,我遇到了一个问题。在控制器中,我有以下方法:

[PolicyAuthorize(Policy = "b2c_1_signin01")]
public ActionResult Index()
{
    var vm = new IndexModel
    {
        FundsDocumentsModel = new FundsDocumentsModel { DocumentTypes = this.DocumentTypes_ReadDictionary() }
    };

    if (this.FundId != Guid.Empty)
    {
        var data = new FinanceDataProvider();
        var fund = data.GetFundById(this.FundId);

        if (fund != null)
        {
            this.ViewBag.LocalSubTitle = "for " + fund.Name;
        }
    }

    return this.View("~/Areas/DataRoom/Views/Index.cshtml", vm);
}
PolicyAuthorize属性的代码与上面提到的示例中的代码相同:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class PolicyAuthorize : AuthorizeAttribute
{
    public string Policy { get; set; }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        filterContext.HttpContext.GetOwinContext().Authentication.Challenge(
                new AuthenticationProperties(
                    new Dictionary<string, string>
                    {
                        { Constants.POLICY_KEY, this.Policy }
                    })
                {
                    RedirectUri = "/",
                }, OpenIdConnectAuthenticationDefaults.AuthenticationType);
    }
}
Web.config:

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=301880
  -->
<configuration>
  <appSettings>

    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />

    <!-- Azure AD B2C -->
    <add key="ida:Tenant" value="xxx" />
    <add key="ida:ClientId" value="xxx" />
    <add key="ida:ClientSecret" value="xxx"/>
    <add key="ida:AadInstance" value="https://login.microsoftonline.com/{0}{1}{2}" />
    <add key="ida:RedirectUri" value="https://localhost:44300/" />
    <add key="ida:PostLogoutRedirectUri" value="https://localhost:44300/" />
    <add key="ida:SignUpPolicyId" value="b2c_1_signup01" />
    <add key="ida:SignInPolicyId" value="b2c_1_signin01" />
    <add key="ida:UserProfilePolicyId" value="b2c_1_profile01" />
    <!-- /Azure AD B2C -->

    <add key="appinsights:instrumentationKey" value="xxx" />

  </appSettings>
  <system.web>
    <customErrors mode="Off" />
    <compilation debug="true" targetFramework="4.6.1" />
    <httpRuntime targetFramework="4.6.1" maxRequestLength="1048576" />
    <pages>
      <namespaces>
        <add namespace="Kendo.Mvc.UI" />
      </namespaces>
    </pages>
    <httpModules>
      <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
    </httpModules>
  </system.web>
  <system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="1073741824" />
      </requestFiltering>
    </security>
    <staticContent>
      <remove fileExtension=".json" />
      <mimeMap fileExtension=".json" mimeType="application/json" />
    </staticContent>
    <rewrite>
      <rules>
        <!-- Enfore HTTPS -->
        <rule name="Force HTTPS" enabled="true">
          <match url="(.*)" ignoreCase="false" />
          <conditions>
            <add input="{HTTPS}" pattern="off" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" appendQueryString="true" redirectType="Permanent" />
        </rule>
      </rules>
    </rewrite>
    <validation validateIntegratedModeConfiguration="false" />
    <modules>
      <remove name="ApplicationInsightsWebTracking" />
      <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
    </modules>
  </system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
        <bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.ApplicationInsights" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.0.0.4220" newVersion="1.0.0.4220" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.20622.1351" newVersion="4.0.20622.1351" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.IdentityModel.Protocol.Extensions" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.0.2.33" newVersion="1.0.2.33" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.AI.Agent.Intercept" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.2.1.0" newVersion="1.2.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.7.0.0" newVersion="5.7.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.7.0.0" newVersion="5.7.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.7.0.0" newVersion="5.7.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
    </compilers>
  </system.codedom>
</configuration>

但它并不完美,调试器仍然进入我的控制器方法,但随后我被重定向到登录页面。所以现在我正在使用它,即使不是完美的。

当你说“然后我将代码移植到现有的应用程序”时,你可能错过了什么吗?演示应用程序中有几个类对身份验证过程具有重要意义。我对他们的理解不够深入,无法为你指出影响你问题的正确答案。但是像Startup.Auth.cs、Startup.c甚至Global.asax.cs这样的文件都有与身份验证机制的完整功能相关的代码。您是否检查了应用程序中的所有代码,以确保它们与运行的演示应用程序中的相应代码相似

检查配置中的重定向uri是否正确

您可以添加一个
authorizationCodeReceived
事件处理程序,以查看质询后返回的内容。 与示例中一样-即
ConfigureAuth()


是的,我把所有东西都搬走了。我更新了初始帖子以显示其他代码。配置中的重定向uri正确吗?也许您可以添加AuthorizationCodeReceived事件处理程序,以查看质询后返回的内容。如示例(ConfigureAuth()):@BobLokerse感谢您的想法!现在我截获了AuthorizationCodeReceived事件,它似乎按照预期工作。我怎样才能将你的评论标记为答案?很高兴听到。我添加了它作为答案。我有一个类似的问题,但我的解决方案是在Azure B2C设置中我的重定向URI后添加一个尾随斜杠(即“not”)。在这样做之后,我能够启动“AuthorizationCodeReceived”handlder。这是引导我找到解决方案的链接/帖子:如果重定向URL没有最终斜杠,则不会调用AuthorizationCodeReceived事件!?"
public class HttpDocumentRetriever : IDocumentRetriever
{
    private readonly HttpClient _httpClient;

    public HttpDocumentRetriever()
        : this(new HttpClient())
    { }

    public HttpDocumentRetriever(HttpClient httpClient)
    {
        Guard.AgainstNullArgument(nameof(httpClient), httpClient);

        this._httpClient = httpClient;
    }

    public async Task<string> GetDocumentAsync(string address, CancellationToken cancel)
    {
        Guard.AgainstNullArgument(nameof(address), address);

        try
        {
            HttpResponseMessage response = await this._httpClient.GetAsync(address, cancel).ConfigureAwait(false);
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
        }
        catch (Exception ex)
        {
            throw new IOException("Unable to get document from: " + address, ex);
        }
    }
}
// This class is a temporary workaround for AAD B2C,
// while our current libraries are unable to support B2C
// out of the box.  For the original source code (with comments)
// visit https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/master/src/Microsoft.IdentityModel.Protocol.Extensions/Configuration/ConfigurationManager.cs
public class PolicyConfigurationManager : IConfigurationManager<OpenIdConnectConfiguration>
{
    public static readonly TimeSpan DefaultAutomaticRefreshInterval = new TimeSpan(5, 0, 0, 0);

    public static readonly TimeSpan DefaultRefreshInterval = new TimeSpan(0, 0, 0, 30);

    public static readonly TimeSpan MinimumAutomaticRefreshInterval = new TimeSpan(0, 0, 5, 0);

    public static readonly TimeSpan MinimumRefreshInterval = new TimeSpan(0, 0, 0, 1);

    private const string policyParameter = "p";

    private TimeSpan _automaticRefreshInterval = DefaultAutomaticRefreshInterval;
    private TimeSpan _refreshInterval = DefaultRefreshInterval;
    private Dictionary<string, DateTimeOffset> _syncAfter;
    private Dictionary<string, DateTimeOffset> _lastRefresh;

    private readonly SemaphoreSlim _refreshLock;
    private readonly string _metadataAddress;
    private readonly IDocumentRetriever _docRetriever;
    private readonly OpenIdConnectConfigurationRetriever _configRetriever;
    private Dictionary<string, OpenIdConnectConfiguration> _currentConfiguration;

    public PolicyConfigurationManager(string metadataAddress, string[] policies)
        : this(metadataAddress, policies, new HttpDocumentRetriever())
    {
    }

    public PolicyConfigurationManager(string metadataAddress, string[] policies, IDocumentRetriever docRetriever)
    {
        if (string.IsNullOrWhiteSpace(metadataAddress))
        {
            throw new ArgumentNullException("metadataAddress");
        }

        if (docRetriever == null)
        {
            throw new ArgumentNullException("retriever");
        }

        _metadataAddress = metadataAddress;
        _docRetriever = docRetriever;
        _configRetriever = new OpenIdConnectConfigurationRetriever();
        _refreshLock = new SemaphoreSlim(1);
        _syncAfter = new Dictionary<string, DateTimeOffset>();
        _lastRefresh = new Dictionary<string, DateTimeOffset>();
        _currentConfiguration = new Dictionary<string, OpenIdConnectConfiguration>();

        foreach (string policy in policies)
        {
            _currentConfiguration.Add(policy, null);
        }
    }

    public TimeSpan AutomaticRefreshInterval
    {
        get { return _automaticRefreshInterval; }
        set
        {
            if (value < MinimumAutomaticRefreshInterval)
            {
                throw new ArgumentOutOfRangeException("value", value, string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10107, MinimumAutomaticRefreshInterval, value));
            }
            _automaticRefreshInterval = value;
        }
    }

    public TimeSpan RefreshInterval
    {
        get { return _refreshInterval; }
        set
        {
            if (value < MinimumRefreshInterval)
            {
                throw new ArgumentOutOfRangeException("value", value, string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10106, MinimumRefreshInterval, value));
            }
            _refreshInterval = value;
        }
    }

    // Takes the ohter and copies it to source, preserving the source's multi-valued attributes as a running sum.
    private OpenIdConnectConfiguration MergeConfig(OpenIdConnectConfiguration source, OpenIdConnectConfiguration other)
    {
        ICollection<SecurityToken> existingSigningTokens = source.SigningTokens;
        ICollection<string> existingAlgs = source.IdTokenSigningAlgValuesSupported;
        ICollection<SecurityKey> existingSigningKeys = source.SigningKeys;

        foreach (SecurityToken token in existingSigningTokens)
        {
            other.SigningTokens.Add(token);
        }

        foreach (string alg in existingAlgs)
        {
            other.IdTokenSigningAlgValuesSupported.Add(alg);
        }

        foreach (SecurityKey key in existingSigningKeys)
        {
            other.SigningKeys.Add(key);
        }

        return other;
    }

    // This non-policy specific method effectively gets the metadata for all policies specified in the constructor,
    // and merges their signing key metadata.  It selects the other metadata from one of the policies at random.
    // This is done so that the middleware can take an incoming id_token and validate it against all signing keys
    // for the app, selecting the appropriate signing key based on the key identifiers.
    public async Task<OpenIdConnectConfiguration> GetConfigurationAsync(CancellationToken cancel)
    {
        OpenIdConnectConfiguration configUnion = new OpenIdConnectConfiguration();
        Dictionary<string, OpenIdConnectConfiguration> clone = new Dictionary<string, OpenIdConnectConfiguration>(_currentConfiguration);
        foreach (KeyValuePair<string, OpenIdConnectConfiguration> entry in clone)
        {
            OpenIdConnectConfiguration config = await GetConfigurationByPolicyAsync(cancel, entry.Key);
            configUnion = MergeConfig(configUnion, config);
        }

        return configUnion;
    }

    public async Task<OpenIdConnectConfiguration> GetConfigurationByPolicyAsync(CancellationToken cancel, string policyId)
    {
        DateTimeOffset now = DateTimeOffset.UtcNow;

        DateTimeOffset sync;
        if (!_syncAfter.TryGetValue(policyId, out sync))
        {
            sync = DateTimeOffset.MinValue;
        }

        OpenIdConnectConfiguration config;
        if (!_currentConfiguration.TryGetValue(policyId, out config))
        {
            config = null;
        }

        if (config != null && sync > now)
        {
            return config;
        }

        await _refreshLock.WaitAsync(cancel);
        try
        {
            Exception retrieveEx = null;
            if (sync <= now)
            {
                try
                {
                    // We're assuming the metadata address provided in the constructor does not contain qp's
                    config = await OpenIdConnectConfigurationRetriever.GetAsync(String.Format(_metadataAddress + "?{0}={1}", policyParameter, policyId), _docRetriever, cancel);
                    _currentConfiguration[policyId] = config;
                    Contract.Assert(_currentConfiguration[policyId] != null);
                    _lastRefresh[policyId] = now;
                    _syncAfter[policyId] = now.UtcDateTime.Add(_automaticRefreshInterval);
                }
                catch (Exception ex)
                {
                    retrieveEx = ex;
                    _syncAfter[policyId] = now.UtcDateTime.Add(_automaticRefreshInterval < _refreshInterval ? _automaticRefreshInterval : _refreshInterval);
                }
            }

            if (config == null)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10803, _metadataAddress ?? "null"), retrieveEx);
            }

            return config;
        }
        finally
        {
            _refreshLock.Release();
        }
    }

    public void RequestRefresh(string policyId)
    {
        DateTimeOffset now = DateTimeOffset.UtcNow;
        DateTimeOffset refresh;
        if (!_lastRefresh.TryGetValue(policyId, out refresh) || now >= _lastRefresh[policyId].UtcDateTime.Add(RefreshInterval))
        {
            _syncAfter[policyId] = now;
        }
    }

    public void RequestRefresh()
    {
        foreach (KeyValuePair<string, OpenIdConnectConfiguration> entry in _currentConfiguration)
        {
            RequestRefresh(entry.Key);
        }
    }
}
public class MvcApplication : HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
}
<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=301880
  -->
<configuration>
  <appSettings>

    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />

    <!-- Azure AD B2C -->
    <add key="ida:Tenant" value="xxx" />
    <add key="ida:ClientId" value="xxx" />
    <add key="ida:ClientSecret" value="xxx"/>
    <add key="ida:AadInstance" value="https://login.microsoftonline.com/{0}{1}{2}" />
    <add key="ida:RedirectUri" value="https://localhost:44300/" />
    <add key="ida:PostLogoutRedirectUri" value="https://localhost:44300/" />
    <add key="ida:SignUpPolicyId" value="b2c_1_signup01" />
    <add key="ida:SignInPolicyId" value="b2c_1_signin01" />
    <add key="ida:UserProfilePolicyId" value="b2c_1_profile01" />
    <!-- /Azure AD B2C -->

    <add key="appinsights:instrumentationKey" value="xxx" />

  </appSettings>
  <system.web>
    <customErrors mode="Off" />
    <compilation debug="true" targetFramework="4.6.1" />
    <httpRuntime targetFramework="4.6.1" maxRequestLength="1048576" />
    <pages>
      <namespaces>
        <add namespace="Kendo.Mvc.UI" />
      </namespaces>
    </pages>
    <httpModules>
      <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
    </httpModules>
  </system.web>
  <system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="1073741824" />
      </requestFiltering>
    </security>
    <staticContent>
      <remove fileExtension=".json" />
      <mimeMap fileExtension=".json" mimeType="application/json" />
    </staticContent>
    <rewrite>
      <rules>
        <!-- Enfore HTTPS -->
        <rule name="Force HTTPS" enabled="true">
          <match url="(.*)" ignoreCase="false" />
          <conditions>
            <add input="{HTTPS}" pattern="off" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" appendQueryString="true" redirectType="Permanent" />
        </rule>
      </rules>
    </rewrite>
    <validation validateIntegratedModeConfiguration="false" />
    <modules>
      <remove name="ApplicationInsightsWebTracking" />
      <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
    </modules>
  </system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
        <bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.ApplicationInsights" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.0.0.4220" newVersion="1.0.0.4220" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.20622.1351" newVersion="4.0.20622.1351" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.IdentityModel.Protocol.Extensions" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.0.2.33" newVersion="1.0.2.33" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.AI.Agent.Intercept" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.2.1.0" newVersion="1.2.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.7.0.0" newVersion="5.7.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.7.0.0" newVersion="5.7.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.7.0.0" newVersion="5.7.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
    </compilers>
  </system.codedom>
</configuration>
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
    if (this.Policy.Equals(ConfigurationHelper.Authentication.SIGNIN_POLICY_ID, StringComparison.InvariantCultureIgnoreCase))
    {
        filterContext.HttpContext.Response.Redirect("/Account/SignIn", true);
    }
    else if (this.Policy.Equals(ConfigurationHelper.Authentication.SIGNUP_POLICY_ID, StringComparison.InvariantCultureIgnoreCase))
    {
        filterContext.HttpContext.Response.Redirect("/Account/SignUp", true);
    }
    else
    {
        throw new NotSupportedException($"Policy ID {this.Policy} is not supported.");
    }
}