2016-03-28 4 views
1

J'ai une application MVC que j'essaye d'authentifier à Azure AD B2C. Je veux utiliser le deny = "?" attribut dans mon web.config. Tout va bien jusqu'à ce que je sois redirigé vers mon application après authentification, dans ce cas, asp.net ne voit pas que mon utilisateur est autorisé et je suis renvoyé à la page de connexion B2C, ce qui entraîne une boucle sans fin.Azure B2C deny = "?" dans 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> 

Répondre

1

Raison de cette question:

Pour de DotNet OpenID Connect, l'authentification et la redirection sont effectués au même temps. Dans votre cas, l'authentification est toujours plus lente que la redirection. Et, l'URI de redirection dans votre application est "https://localhost:44316/", qui nécessitent une authentification à nouveau car Request.IsAuthenticated n'est pas encore définie pour être vrai. La nouvelle authentification remplacera l'ancienne authentification. par conséquent, il continue à boucler encore et encore.

La solution est simple. Changez votre URI de redirection vers une page qui n'a pas besoin d'authentification. Par exemple:

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

... 

Note: Ici, https://localhost:44316/Home/loginsuccess devrait être une page qui montre l'utilisateur sur son statut d'authentification. En passant, vous devez ajouter cet URI de redirection à votre application AD dans le nouveau portail.