Azure AD B2C - Authentication Challenge not triggering authentication
<p>I am playing around with Azure AD B2C and I have a weird behavior. I created a new app following this sample: <a href="https://github.com/AzureADQuickStarts/B2C-WebApp-OpenIdConnect-DotNet/tree/complete/WebApp-B2C-DotNet" rel="nofollow">AzureADQuickStarts/B2C-WebApp-OpenIdConnect-DotNet </a> and it works like a charm.</p>

<p>Then I ported the code to an existing app and I get a problem. In a Controller, I have the following method:</p>

<pre><code>[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);
}
</code></pre>

<p>The code of the PolicyAuthorize attribute is the same as in the sample mentionned above:</p>

<pre><code>[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&lt;string, string&gt;
                    {
                        { Constants.POLICY_KEY, this.Policy }
                    })
                {
                    RedirectUri = "/",
                }, OpenIdConnectAuthenticationDefaults.AuthenticationType);
    }
}
</code></pre>

<p>When I access my web app in debug, I am automatically taken to the Index method of the controller. Then I go in the HandleUnauthorizedRequest of the attribute and the Challenge method is called.</p>

<p>But I am not redirected to the B2C login page. Instead, the debugger comes back to the Index method like if I was authenticated, which I do not want.</p>

<p>Now, if I go to /Account/SignIn (which have the same implementation as in the sample app), I get redirected to the B2C login page.</p>

<p>The problem is that in the sample app, whenever I use the PolicyAuthorize attribute, I get redirected to the B2C login page.</p>

<p>So I do not understand where this difference can come from. Do you guys have any idea?</p>

<p><strong>UPDATE:</strong></p>

<p>Here is more code, to show everything has been ported.</p>

<p>Startup.Auth.cs:</p>

<pre><code>public partial class Startup
{
    public void ConfigureAuth(IAppBuilder app)
    {
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions());

        var options = new OpenIdConnectAuthenticationOptions
        {
            // These are standard OpenID Connect parameters, with values pulled from web.config
            ClientId = ConfigurationHelper.Authentication.CLIENT_ID,
            RedirectUri = ConfigurationHelper.Authentication.REDIRECT_URI,
            PostLogoutRedirectUri = ConfigurationHelper.Authentication.REDIRECT_URI,
            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                AuthenticationFailed = this.AuthenticationFailed,
                RedirectToIdentityProvider = this.OnRedirectToIdentityProvider
            },
            Scope = "openid",
            ResponseType = "id_token",

            // The PolicyConfigurationManager takes care of getting the correct Azure AD authentication
            // endpoints from the OpenID Connect metadata endpoint.  It is included in the PolicyAuthHelpers folder.
            ConfigurationManager = new PolicyConfigurationManager(
                string.Format(CultureInfo.InvariantCulture, ConfigurationHelper.Authentication.AAD_INSTANCE, ConfigurationHelper.Authentication.TENANT, "/v2.0", Constants.OIDC_METADATA_SUFFIX),
                new[] { ConfigurationHelper.Authentication.SIGNUP_POLICY_ID, ConfigurationHelper.Authentication.SIGNIN_POLICY_ID, ConfigurationHelper.Authentication.PROFILE_POLICY_ID }),

            // This piece is optional - it is used for displaying the user's name in the navigation bar.
            TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = "name",
            },
        };

        app.UseOpenIdConnectAuthentication(options);

    }

    /// &lt;summary&gt;
    /// This notification can be used to manipulate the OIDC request before it is sent. Here we use it to send the correct policy.
    /// &lt;/summary&gt;
    /// &lt;param name="notification"&gt;The notification.&lt;/param&gt;
    private async Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification&lt;OpenIdConnectMessage, OpenIdConnectAuthenticationOptions&gt; notification)
    {
        PolicyConfigurationManager mgr = notification.Options.ConfigurationManager as PolicyConfigurationManager;
        if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
        {
            OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, notification.OwinContext.Authentication.AuthenticationResponseRevoke.Properties.Dictionary[Constants.POLICY_KEY]);
            notification.ProtocolMessage.IssuerAddress = config.EndSessionEndpoint;
        }
        else
        {
            OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, notification.OwinContext.Authentication.AuthenticationResponseChallenge.Properties.Dictionary[Constants.POLICY_KEY]);
            notification.ProtocolMessage.IssuerAddress = config.AuthorizationEndpoint;
        }
    }

    /// &lt;summary&gt;
    /// Used for avoiding yellow-screen-of-death
    /// &lt;/summary&gt;
    /// &lt;param name="notification"&gt;The notification.&lt;/param&gt;
    private Task AuthenticationFailed(AuthenticationFailedNotification&lt;OpenIdConnectMessage, OpenIdConnectAuthenticationOptions&gt; notification)
    {
        notification.HandleResponse();
        notification.Response.Redirect("/Home/Error?message=" + notification.Exception.Message);
        return Task.FromResult(0);
    }
}
</code></pre>

<p>HttpDocumentRetriever.cs:</p>

<pre><code>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&lt;string&gt; 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);
        }
    }
}
</code></pre>

<p>PolicyConfigurationManager.cs:</p>

<pre><code>// 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&lt;OpenIdConnectConfiguration&gt;
{
    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&lt;string, DateTimeOffset&gt; _syncAfter;
    private Dictionary&lt;string, DateTimeOffset&gt; _lastRefresh;

    private readonly SemaphoreSlim _refreshLock;
    private readonly string _metadataAddress;
    private readonly IDocumentRetriever _docRetriever;
    private readonly OpenIdConnectConfigurationRetriever _configRetriever;
    private Dictionary&lt;string, OpenIdConnectConfiguration&gt; _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&lt;string, DateTimeOffset&gt;();
        _lastRefresh = new Dictionary&lt;string, DateTimeOffset&gt;();
        _currentConfiguration = new Dictionary&lt;string, OpenIdConnectConfiguration&gt;();

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

    public TimeSpan AutomaticRefreshInterval
    {
        get { return _automaticRefreshInterval; }
        set
        {
            if (value &lt; 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 &lt; 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&lt;SecurityToken&gt; existingSigningTokens = source.SigningTokens;
        ICollection&lt;string&gt; existingAlgs = source.IdTokenSigningAlgValuesSupported;
        ICollection&lt;SecurityKey&gt; 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&lt;OpenIdConnectConfiguration&gt; GetConfigurationAsync(CancellationToken cancel)
    {
        OpenIdConnectConfiguration configUnion = new OpenIdConnectConfiguration();
        Dictionary&lt;string, OpenIdConnectConfiguration&gt; clone = new Dictionary&lt;string, OpenIdConnectConfiguration&gt;(_currentConfiguration);
        foreach (KeyValuePair&lt;string, OpenIdConnectConfiguration&gt; entry in clone)
        {
            OpenIdConnectConfiguration config = await GetConfigurationByPolicyAsync(cancel, entry.Key);
            configUnion = MergeConfig(configUnion, config);
        }

        return configUnion;
    }

    public async Task&lt;OpenIdConnectConfiguration&gt; 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 &amp;&amp; sync &gt; now)
        {
            return config;
        }

        await _refreshLock.WaitAsync(cancel);
        try
        {
            Exception retrieveEx = null;
            if (sync &lt;= 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 &lt; _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 &gt;= _lastRefresh[policyId].UtcDateTime.Add(RefreshInterval))
        {
            _syncAfter[policyId] = now;
        }
    }

    public void RequestRefresh()
    {
        foreach (KeyValuePair&lt;string, OpenIdConnectConfiguration&gt; entry in _currentConfiguration)
        {
            RequestRefresh(entry.Key);
        }
    }
}
</code></pre>

<p>Global.asax.cs:</p>

<pre><code>public class MvcApplication : HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
}
</code></pre>

<p>Web.config:</p>

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

    &lt;add key="webpages:Version" value="3.0.0.0" /&gt;
    &lt;add key="webpages:Enabled" value="false" /&gt;
    &lt;add key="ClientValidationEnabled" value="true" /&gt;
    &lt;add key="UnobtrusiveJavaScriptEnabled" value="true" /&gt;

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

    &lt;add key="appinsights:instrumentationKey" value="xxx" /&gt;

  &lt;/appSettings&gt;
  &lt;system.web&gt;
    &lt;customErrors mode="Off" /&gt;
    &lt;compilation debug="true" targetFramework="4.6.1" /&gt;
    &lt;httpRuntime targetFramework="4.6.1" maxRequestLength="1048576" /&gt;
    &lt;pages&gt;
      &lt;namespaces&gt;
        &lt;add namespace="Kendo.Mvc.UI" /&gt;
      &lt;/namespaces&gt;
    &lt;/pages&gt;
    &lt;httpModules&gt;
      &lt;add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" /&gt;
    &lt;/httpModules&gt;
  &lt;/system.web&gt;
  &lt;system.webServer&gt;
    &lt;security&gt;
      &lt;requestFiltering&gt;
        &lt;requestLimits maxAllowedContentLength="1073741824" /&gt;
      &lt;/requestFiltering&gt;
    &lt;/security&gt;
    &lt;staticContent&gt;
      &lt;remove fileExtension=".json" /&gt;
      &lt;mimeMap fileExtension=".json" mimeType="application/json" /&gt;
    &lt;/staticContent&gt;
    &lt;rewrite&gt;
      &lt;rules&gt;
        &lt;!-- Enfore HTTPS --&gt;
        &lt;rule name="Force HTTPS" enabled="true"&gt;
          &lt;match url="(.*)" ignoreCase="false" /&gt;
          &lt;conditions&gt;
            &lt;add input="{HTTPS}" pattern="off" /&gt;
          &lt;/conditions&gt;
          &lt;action type="Redirect" url="https://{HTTP_HOST}/{R:1}" appendQueryString="true" redirectType="Permanent" /&gt;
        &lt;/rule&gt;
      &lt;/rules&gt;
    &lt;/rewrite&gt;
    &lt;validation validateIntegratedModeConfiguration="false" /&gt;
    &lt;modules&gt;
      &lt;remove name="ApplicationInsightsWebTracking" /&gt;
      &lt;add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" /&gt;
    &lt;/modules&gt;
  &lt;/system.webServer&gt;
  &lt;runtime&gt;
    &lt;assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"&gt;
      &lt;dependentAssembly&gt;
        &lt;assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" /&gt;
        &lt;bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" /&gt;
      &lt;/dependentAssembly&gt;
      &lt;dependentAssembly&gt;
        &lt;assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" /&gt;
        &lt;bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" /&gt;
      &lt;/dependentAssembly&gt;
      &lt;dependentAssembly&gt;
        &lt;assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" /&gt;
        &lt;bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" /&gt;
      &lt;/dependentAssembly&gt;
      &lt;dependentAssembly&gt;
        &lt;assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" /&gt;
        &lt;bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" /&gt;
      &lt;/dependentAssembly&gt;
      &lt;dependentAssembly&gt;
        &lt;assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /&gt;
        &lt;bindingRedirect oldVersion="1.0.0.0-5.1.0.0" newVersion="5.1.0.0" /&gt;
      &lt;/dependentAssembly&gt;
      &lt;dependentAssembly&gt;
        &lt;assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" /&gt;
        &lt;bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" /&gt;
      &lt;/dependentAssembly&gt;
      &lt;dependentAssembly&gt;
        &lt;assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f" culture="neutral" /&gt;
        &lt;bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2" /&gt;
      &lt;/dependentAssembly&gt;
      &lt;dependentAssembly&gt;
        &lt;assemblyIdentity name="Microsoft.ApplicationInsights" publicKeyToken="31bf3856ad364e35" culture="neutral" /&gt;
        &lt;bindingRedirect oldVersion="0.0.0.0-1.0.0.4220" newVersion="1.0.0.4220" /&gt;
      &lt;/dependentAssembly&gt;
      &lt;dependentAssembly&gt;
        &lt;assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" /&gt;
        &lt;bindingRedirect oldVersion="0.0.0.0-4.0.20622.1351" newVersion="4.0.20622.1351" /&gt;
      &lt;/dependentAssembly&gt;
      &lt;dependentAssembly&gt;
        &lt;assemblyIdentity name="Microsoft.IdentityModel.Protocol.Extensions" publicKeyToken="31bf3856ad364e35" culture="neutral" /&gt;
        &lt;bindingRedirect oldVersion="0.0.0.0-1.0.2.33" newVersion="1.0.2.33" /&gt;
      &lt;/dependentAssembly&gt;
      &lt;dependentAssembly&gt;
        &lt;assemblyIdentity name="Microsoft.AI.Agent.Intercept" publicKeyToken="31bf3856ad364e35" culture="neutral" /&gt;
        &lt;bindingRedirect oldVersion="0.0.0.0-1.2.1.0" newVersion="1.2.1.0" /&gt;
      &lt;/dependentAssembly&gt;
      &lt;dependentAssembly&gt;
        &lt;assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" /&gt;
        &lt;bindingRedirect oldVersion="0.0.0.0-5.7.0.0" newVersion="5.7.0.0" /&gt;
      &lt;/dependentAssembly&gt;
      &lt;dependentAssembly&gt;
        &lt;assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" /&gt;
        &lt;bindingRedirect oldVersion="0.0.0.0-5.7.0.0" newVersion="5.7.0.0" /&gt;
      &lt;/dependentAssembly&gt;
      &lt;dependentAssembly&gt;
        &lt;assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" /&gt;
        &lt;bindingRedirect oldVersion="0.0.0.0-5.7.0.0" newVersion="5.7.0.0" /&gt;
      &lt;/dependentAssembly&gt;
    &lt;/assemblyBinding&gt;
  &lt;/runtime&gt;
  &lt;system.codedom&gt;
    &lt;compilers&gt;
      &lt;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" /&gt;
      &lt;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=\&amp;quot;Web\&amp;quot; /optionInfer+" /&gt;
    &lt;/compilers&gt;
  &lt;/system.codedom&gt;
&lt;/configuration&gt;
</code></pre>

<p>For now, I have a "dirty" workaround for the PolicyAuthorize:</p>

<pre><code>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.");
    }
}
</code></pre>

<p>But it is not perfect, the debugger still enters my Controller method but then I am redirected to the login page. So for now I am using this even if not perfect.</p>