2016-03-28 25 views
1

Ich habe eine MVC-Anwendung, die ich versuche, Azure AD B2C zu authentifizieren. Ich möchte den deny = "?" Attribut in meiner web.config. Alles ist gut und gut, bis ich nach auth zu meiner Anwendung zurückgeleitet werde. In diesem Fall erkennt asp.net nicht, dass mein Benutzer autorisiert ist und ich werde zurück zur B2C-Anmeldeseite geschickt, was zu einer Endlosschleife führt.Azure B2C deny = "?" in asp.net MVC

Startup.Auth.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

// The following using statements were added for this sample 
using Owin; 
using Microsoft.Owin.Security; 
using Microsoft.Owin.Security.Cookies; 
using Microsoft.Owin.Security.OpenIdConnect; 
using System.Threading.Tasks; 
using Microsoft.Owin.Security.Notifications; 
using Microsoft.IdentityModel.Protocols; 
using System.Web.Mvc; 
using System.Configuration; 
using System.IdentityModel.Tokens; 
using WebApp_OpenIDConnect_DotNet_B2C.Policies; 
using System.Threading; 
using System.Globalization; 
using Microsoft.Owin; 

namespace WebApp_OpenIDConnect_DotNet_B2C 
{ 
    public partial class Startup 
    { 
     // The ACR claim is used to indicate which policy was executed 
     public const string AcrClaimType = "http://schemas.microsoft.com/claims/authnclassreference"; 
     public const string PolicyKey = "b2cpolicy"; 
     public const string OIDCMetadataSuffix = "/.well-known/openid-configuration"; 

     // App config settings 
     private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"]; 
     private static string aadInstance = ConfigurationManager.AppSettings["ida:AadInstance"]; 
     private static string tenant = ConfigurationManager.AppSettings["ida:Tenant"]; 
     private static string redirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"]; 

     // B2C policy identifiers 
     public static string SignUpPolicyId = ConfigurationManager.AppSettings["ida:SignUpPolicyId"]; 
     public static string SignInPolicyId = ConfigurationManager.AppSettings["ida:SignInPolicyId"]; 
     public static string ProfilePolicyId = ConfigurationManager.AppSettings["ida:UserProfilePolicyId"]; 

     public void ConfigureAuth(IAppBuilder app) 
     { 
      app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); 
      System.Web.Mvc.UrlHelper url = new System.Web.Mvc.UrlHelper(HttpContext.Current.Request.RequestContext); 

      app.UseCookieAuthentication(new CookieAuthenticationOptions 
      { 
       LoginPath = new PathString(url.Action("SignIn", "Account")) 
      }); 

      OpenIdConnectAuthenticationOptions options = new OpenIdConnectAuthenticationOptions 
      { 
       // These are standard OpenID Connect parameters, with values pulled from web.config 
       ClientId = clientId, 
       RedirectUri = redirectUri, 
       PostLogoutRedirectUri = redirectUri, 
       Notifications = new OpenIdConnectAuthenticationNotifications 
       { 
        AuthenticationFailed = AuthenticationFailed, 
        RedirectToIdentityProvider = 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, aadInstance, tenant, "/v2.0", OIDCMetadataSuffix), 
        new string[] { SignUpPolicyId, SignInPolicyId, ProfilePolicyId }), 

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

     } 

     // This notification can be used to manipulate the OIDC request before it is sent. Here we use it to send the correct policy. 
     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[Startup.PolicyKey]); 
       notification.ProtocolMessage.IssuerAddress = config.EndSessionEndpoint; 
      } 
      else 
      { 
       OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, notification.OwinContext.Authentication.AuthenticationResponseChallenge.Properties.Dictionary[Startup.PolicyKey]); 
       notification.ProtocolMessage.IssuerAddress = config.AuthorizationEndpoint; 
      } 
     } 

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

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" /> 
     <add key="ida:Tenant" value="xxxx.onmicrosoft.com" /> 
     <add key="ida:ClientId" value="Myguid" /> 
     <add key="ida:AadInstance" value="https://login.microsoftonline.com/{0}{1}{2}" /> 
     <add key="ida:RedirectUri" value="https://localhost:44316/" /> 
     <add key="ida:SignUpPolicyId" value="B2C_1_JHA.SignUp" /> 
     <add key="ida:SignInPolicyId" value="B2C_1_JHA.SignIn" /> 
     <add key="ida:UserProfilePolicyId" value="B2C_1_JHA.Profile" /> 
    </appSettings> 
    <location path="account/signin"> 
     <system.web> 
     <authorization> 
      <allow users="*" /> 
     </authorization> 
     </system.web> 
    </location> 
    <system.web> 
     <authorization> 
     <deny users="?" /> 
     </authorization> 
     <compilation debug="true" targetFramework="4.5" /> 
     <httpRuntime targetFramework="4.5" /> 
    </system.web> 
    <runtime> 
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <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.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="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /> 
      <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.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="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.WebPages" 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.2.3.0" newVersion="5.2.3.0" /> 
     </dependentAssembly> 
     <dependentAssembly> 
      <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" /> 
      <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" /> 
     </dependentAssembly> 
     <dependentAssembly> 
      <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" /> 
      <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" /> 
     </dependentAssembly> 
     <dependentAssembly> 
      <assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" /> 
      <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" /> 
     </dependentAssembly> 
     </assemblyBinding> 
    </runtime> 
    </configuration> 

Antwort

1

Grund für dieses Problem:

Für OpenIDConnect von DotNet, die Authentifizierung und die Umleitung auf der gleichen getan Zeit. In Ihrem Fall ist die Authentifizierung immer langsamer als die Umleitung. Außerdem lautet der Umleitungs-URI in Ihrer App "https://localhost:44316/", für den eine erneute Authentifizierung erforderlich ist, da Request.IsAuthenticated noch nicht als wahr festgelegt ist. Die neue Authentifizierung überschreibt die alte Authentifizierung. daher bleibt es immer und immer wieder schleifen.

Die Lösung ist einfach. Ändern Sie den Weiterleitungs-URI auf eine Seite, für die keine Authentifizierung erforderlich ist. Zum Beispiel:

<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" /> 
    <add key="ida:Tenant" value="xxxx.onmicrosoft.com" /> 
    <add key="ida:ClientId" value="Myguid" /> 
    <add key="ida:AadInstance" value="https://login.microsoftonline.com/{0}{1}{2}" /> 
    <add key="ida:RedirectUri" value="https://localhost:44316/Home/loginsuccess" /> 
    <add key="ida:SignUpPolicyId" value="B2C_1_JHA.SignUp" /> 
    <add key="ida:SignInPolicyId" value="B2C_1_JHA.SignIn" /> 
    <add key="ida:UserProfilePolicyId" value="B2C_1_JHA.Profile" /> 
</appSettings> 
<location path="account/signin"> 
    <system.web> 
    <authorization> 
     <allow users="*" /> 
    </authorization> 
    </system.web> 
</location> 
<location path="Home/loginsuccess"> 
    <system.web> 
    <authorization> 
     <allow users="*" /> 
    </authorization> 
    </system.web> 
</location> 
<system.web> 
    <authorization> 
    <deny users="?" /> 
    </authorization> 
    <compilation debug="true" targetFramework="4.5" /> 
    <httpRuntime targetFramework="4.5" /> 
</system.web> 

... 

Hinweis: Hier sollte https://localhost:44316/Home/loginsuccess eine Seite, die die Benutzer über ihren Authentifizierungsstatus zeigt. Übrigens sollten Sie diese Weiterleitungs-URI Ihrer AD-Anwendung im neuen Portal hinzufügen.

Verwandte Themen