2

我正在玩Azure AD B2C,我有一個奇怪的行爲。我在此示例之後創建了一個新應用程序:AzureADQuickStarts/B2C-WebApp-OpenIdConnect-DotNet,它的功能類似於魅力。Azure AD 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屬性的代碼是如在樣品中的與上述相同mentionned:

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

當訪問我的網絡應用程序中的調試,我我會自動轉到控制器的Index方法。然後我進入屬性的HandleUnauthorizedRequest並調用Challenge方法。

但我沒有重定向到B2C登錄頁面。相反,調試器會返回到Index方法,就像我已經過身份驗證一樣,這是我不想要的。

現在,如果我轉到/ Account/SignIn(與示例應用程序具有相同的實現),我將重定向到B2C登錄頁面。

問題是,在示例應用程序中,無論何時使用PolicyAuthorize屬性,我都會重定向到B2C登錄頁面。

所以我不明白這種差異可以從哪裏來。你們有什麼想法嗎?

UPDATE:

這裏有更多的代碼,以顯示一切都已經被移植。

Startup.Auth.cs:

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); 

    } 

    /// <summary> 
    /// This notification can be used to manipulate the OIDC request before it is sent. Here we use it to send the correct policy. 
    /// </summary> 
    /// <param name="notification">The notification.</param> 
    private async Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> 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; 
     } 
    } 

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

HttpDocumentRetriever.cs:

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); 
     } 
    } 
} 

PolicyConfigurationManager.cs:

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

的Global.asax.cs:

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

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> 

現在,我對PolicyAuthorize「髒」的解決方法:

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

但它並不完美,調試器仍然進入我的控制方法,但隨後我被重定向到登錄頁面。所以現在我使用這個,即使不完美。

+2

是您的重定向uri的配置是否正確? 也許您可以添加AuthorizationCodeRecieved事件處理程序,以查看在挑戰後返回的內容。就像在示例中一樣(ConfigureAuth()):https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-devquickstarts-web-api-dotnet/ –

+1

@BobLokerse感謝您的想法!現在我攔截了AuthorizationCodeReceived事件,它似乎按預期工作。我怎樣才能將你的評論標記爲答案? – DotNetMatt

+0

很高興聽到。我將其添加爲答案。 –

回答

1

檢查您的重定向uri在配置中是否正確。

您可以添加AuthorizationCodeRecieved事件處理程序,以查看在挑戰後返回的內容。 像在示例中一樣(ConfigureAuth()):
B2C quickstart Web-api-dotnet - with AuthorizationCodeRecieved eventHandler

+1

我有類似的問題,但我的解決方案是在Azure B2C設置(即「https:// localhost/TaskService /」而不是「https:// localhost/TaskService」)中的重定向URI之後放置一個尾部斜線。 )。做完這些之後,我能夠獲得「AuthorizationCodeReceived」手牌。這是導致我找到解決方案的鏈接/帖子:https://github.com/aspnet/Security/issues/445「如果RedirectUrl沒有最終斜槓,那麼AuthorizationCodeReceived事件不會被調用!」? –

0

當你說「然後我將代碼移植到現有的應用程序」是否有可能錯過了某些東西?演示程序中有幾個類對認證過程有重要意義。我對它們的理解不夠深,不足以讓你指出影響你的問題的正確答案。但像Startup.Auth.cs,Startup.c或甚至Global.asax.cs這樣的文件具有與認證機制的全部功能相關的代碼。你是否已經在應用程序中檢查了它們,以確保它們與演示應用程序中相應的代碼相似?

+0

是的,我移植了一切。我更新了最初的帖子以顯示其他代碼段。 – DotNetMatt