2016-05-23 15 views
3

Ich benutze Azure AD B2C zur Authentifizierung in einer AspNetCore RC2 MVC-Anwendung. Dies funktioniert teilweise, wenn ich zu einer Aktion navigiere, die eine Authentifizierung erfordert, werde ich entsprechend zur B2C-Anmeldeseite weitergeleitet. Wenn ich mich erfolgreich anmelde, werde ich korrekt auf meine Anwendungsseite umgeleitet (und ich kann das ID_Token-Feld sehen, das in den Abfrageparametern entsprechend vorgesehen ist). Leider scheint die Pipeline-Authentifizierungs-Middleware die Umleitungsparameter nicht korrekt zu verarbeiten, da sie mich sofort auf die Anmeldeseite weiterleitet. Kann jemand beraten?AspNetCore UseOpenIdConnectAuthentication

Der Code ich benutze ist unten:

public static void UseOAuth(this IApplicationBuilder app) 
{ 
    // By default, all middleware are passive/not automatic. Making cookie middleware automatic so that it acts on all the messages. 
    app.UseCookieAuthentication(new CookieAuthenticationOptions{ AutomaticAuthenticate = true, CookieSecure = CookieSecureOption.Never }); 

    app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions { 
     ClientId = B2CAuthentication.ClientId, 
     ResponseType = OpenIdConnectResponseTypes.IdToken, 
     Authority = string.Format(CultureInfo.InvariantCulture, B2CAuthentication.AadInstance, B2CAuthentication.PortalTenant, string.Empty, string.Empty), 
     AuthenticationScheme = "Cookies", 
     Events = new OpenIdConnectEvents 
     { 
      OnAuthenticationFailed = OnAuthenticationFailed, 
      OnRedirectToIdentityProvider = OnRedirectToIdentityProvider, 
      OnAuthorizationCodeReceived = OnAuthorizationCodeReceived, 
      OnTokenResponseReceived = OnTokenResponseReceived, 
      OnTokenValidated = OnTokenValidated, 
      OnTicketReceived = OnTicketReceived, 
      OnMessageReceived = OnMessageReceived, 
      OnRedirectToIdentityProviderForSignOut = OnRedirectToIdentityProviderForSignOut, 
      OnRemoteFailure = OnRemoteFailure, 
      OnUserInformationReceived = OnUserInformationReceived 
     }, 
     // 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, B2CAuthentication.AadInstance, B2CAuthentication.PortalTenant, "/v2.0", "/" + OpenIdProviderMetadataNames.Discovery), 
      new string[] { B2CAuthentication.ResetPolicy, B2CAuthentication.CommonPolicy, B2CAuthentication.SignInPolicy }) 

    }); 
} 

private static Task OnUserInformationReceived(UserInformationReceivedContext arg) 
{ 
    ...Never called... 
} 

private static Task OnRemoteFailure(FailureContext arg) 
{ 
    ...Never called... 
} 

private static Task OnRedirectToIdentityProviderForSignOut(RedirectContext arg) 
{ 
    ...Never called... 
} 

private static Task OnMessageReceived(MessageReceivedContext arg) 
{ 
    ...Never called... 
} 

private static Task OnTicketReceived(TicketReceivedContext arg) 
{ 
    ...Never called... 
} 

private static Task OnTokenValidated(TokenValidatedContext arg) 
{ 
    ...Never called... 
} 

private static Task OnTokenResponseReceived(TokenResponseReceivedContext arg) 
{ 
    ...Never called... 
} 

private static Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext arg) 
{ 
    ...Never called... 
} 

private static async Task OnRedirectToIdentityProvider(RedirectContext context) 
{ 
    PolicyConfigurationManager mgr = (PolicyConfigurationManager)context.Options.ConfigurationManager; 
    if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) 
    { 
     OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, B2CAuthentication.CommonPolicy); 
     context.ProtocolMessage.IssuerAddress = config.EndSessionEndpoint; 
    } 
    else 
    { 
     OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, B2CAuthentication.CommonPolicy); 
     context.ProtocolMessage.IssuerAddress = config.AuthorizationEndpoint; 
     context.ProtocolMessage.RedirectUri = "http://localhost:8080/Portal/"; 
     context.ProtocolMessage.ResponseType = OpenIdConnectResponseTypes.IdToken; 
     context.ProtocolMessage.ResponseMode = OpenIdConnectResponseModes.Query; 
    } 
} 

private static Task OnAuthenticationFailed(AuthenticationFailedContext context) 
{ 
    context.HandleResponse(); 
    context.Response.Redirect("/Home/Error?message=" + context.Exception.Message); 
    return Task.FromResult(0); 
} 

Antwort

4

Ich habe es geschafft, dies indem Sie folgendermaßen vorgehen, um die Arbeit zu machen:

Grundsätzlich denke ich, die Verwendung des CallbackPath, die Änderung Zu AuthenticationScheme und der Änderung von ResponseMode zu FormPost trugen alle zur Behebung bei.

public static void UseOAuth(this IApplicationBuilder app) 
{ 
    // By default, all middleware are passive/not automatic. Making cookie middleware automatic so that it acts on all the messages. 
    app.UseCookieAuthentication(new CookieAuthenticationOptions 
    { 
     AutomaticAuthenticate = true, 
     CookieName = "MyCookieName", 
     CookieSecure = CookieSecureOption.Never, 
     AuthenticationScheme = "Cookies" 
    }); 

    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap = new Dictionary<string, string>(); 

    app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions { 
     AutomaticAuthenticate = true, 
     Authority = string.Format(CultureInfo.InvariantCulture, B2CAuthentication.AadInstance, B2CAuthentication.PortalTenant, string.Empty, string.Empty), 
     ClientId = B2CAuthentication.ClientId, 
     ResponseType = OpenIdConnectResponseTypes.IdToken, 
     AuthenticationScheme = "oidc", 
     ResponseMode = OpenIdConnectResponseModes.FormPost, 
     CallbackPath = "/", 
     Scope = { "openid" }, 
     Events = new OpenIdConnectEvents 
     { 
      OnAuthenticationFailed = OnAuthenticationFailed, 
      OnRedirectToIdentityProvider = OnRedirectToIdentityProvider, 
      OnTokenValidated = OnTokenValidated, 
      OnRemoteFailure = OnRemoteFailure 
     }, 
     // 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, B2CAuthentication.AadInstance, B2CAuthentication.PortalTenant, "/v2.0", "/" + OpenIdProviderMetadataNames.Discovery), 
      new string[] { B2CAuthentication.ResetPolicy, B2CAuthentication.CommonPolicy, B2CAuthentication.SignInPolicy }) 

    }); 
} 
+0

Kurze Frage, da ich kann nicht die Antwort zu finden scheinen, und Sie scheinen es zu haben, zu arbeiten. Hat "OnTokenValidated" "AuthenticationValidated" im Übergang von RC1 zu RC2 ersetzt? – Brandon

+0

BTW, FormPost ist der Standardwert, so dass es nicht festgelegt werden muss. Es muss einfach nicht außer Kraft gesetzt werden. – spottedmahn

4

Mit

ResponseType = OpenIdConnectResponseType.Code 

innen

app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions 
{ 
    ... 
}); 

scheint die Middleware-Eingabeaufforderung für die CodeReceived Ereignis zu machen.

Auch Microsoft.AspNetCore.Mvc.Formatters.Xml in den project.json vom Could not load file or assembly System.Private.DataContractSerialization Fehler wegzukommen

+0

Ich würde Sie gerne auf einen Drink einladen, Sir. Obwohl OpenIdConnectResponseType.Code den Trick nicht gemacht hat, scheint OpenIdConnectResponseType.IdToken getan zu haben! Vielen Dank –