web-dev-qa-db-fra.com

Utiliser le package OWIN Ws-Federation pour s'authentifier auprès d'ADFS 3.0

J'ai un site intranet MVC qui doit utiliser des comptes AD pour l'authentification. 

J'ai installé ADFS 3.0 (Win Server 2012 R2) et suivi this pour configurer la confiance ADFS Relying Party. 

Ceci autre message introduit les composants OWIN de Ws-Federation et j'aimerais les utiliser. Il indique comment se connecter à Azure AD mais rien concernant ADFS. 

J'ai essayé de définir les propriétés de configuration "MetadataAddress" et "Wtrealm" pour correspondre à ce que j'ai configuré dans ADFS, mais lors de l'exécution, une erreur s'est produite:

A default value for SignInAsAuthenticationType was not found in IAppBuilder Properties. 
This can happen if your authentication middleware are added in the wrong order, or if one is missing.

Je cherche le bon moyen de supprimer cette erreur

14
oscarmorasu

Ouais .. Je suis tombé sur le même problème. Faites juste ce qui suit et ça devrait marcher:

    app.SetDefaultSignInAsAuthenticationType(WsFederationAuthenticationDefaults.AuthenticationType );

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
       AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType
    });
25
LyphTEC

Cela fait un moment que j'essaie de comprendre ce que je pense et plus particulièrement à Lars Kemmann et Tratcher , je crois que la méthode habituelle est la suivante:

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

app.UseCookieAuthentication(
    new CookieAuthenticationOptions { }
);

app.UseWsFederationAuthentication(
    new WsFederationAuthenticationOptions
    {
        Wtrealm = ConfigurationManager.AppSettings["ida:Wtrealm"],
        MetadataAddress = ConfigurationManager.AppSettings["ida:FedMetadataURI"]
    }
);

Il semble contre-intuitif que vous configuriez le type d'authentification par défaut comme "Authentification par cookie" pour que WsFederation fonctionne. Cependant, il ne s'agit en fait que de chaînes utilisées pour identifier chaque middleware (cela vous permet d'enregistrer le même type de middleware plusieurs fois). fois, par exemple), ils évaluent comme suit:

  • CookieAuthenticationDefaults.AuthenticationType = "Cookies"
  • WsFederationAuthenticationDefaults.AuthenticationType = "Fédération"

Ce qui se passe ici, c’est que nous disons à OWIN que le middleware étiqueté "Cookies" doit être utilisé par défaut pour authentifier les demandes. Nous ajoutons ensuite le middleware CookieAuthentication (par défaut, il est étiqueté "Cookies" à partir de la valeur CookieAuthenticationDefaults.AuthenticationType. Nous n'avons pas besoin d'écrire de code supplémentaire pour le configurer), enfin nous ajoutons le middleware FederationAuthentication (étiqueté par WsFederationAuthenticationDefaults.AuthenticationType - c.-à-d. "Fédération"). Je comprends que le middleware Federation utilise le middleware Cookie pour gérer ses cookies liés à l'authentification. .

Il ne vous reste plus qu'à configurer votre application pour qu'elle appelle le middleware à l'heure de votre choix. Vous pouvez y parvenir de plusieurs manières, dont certaines sont les suivantes:

  • En renvoyant une réponse HTTP 401
  • En utilisant l'attribut [Authorize] sur un contrôleur MVC
  • En appelant la méthode IAuthenticationManager du contexte OWIN Challenge (en passant l'étiquette de votre middleware de fédération)

Lorsque j'ai posé cette question ici , Lars a répondu avec un bel exemple de demande d'authentification pour toutes les demandes. Je l'ai ensuite intégrée au pipeline OWIN comme suit:

app.Use(
    (context, continuation) =>
    {
        if (
            (context.Authentication.User != null) &&
            (context.Authentication.User.Identity != null) &&
            (context.Authentication.User.Identity.IsAuthenticated)
        )
        {
            return continuation();
        }
        else
        {
            context.Authentication.Challenge(WsFederationAuthenticationDefaults.AuthenticationType);

            return Task.Delay(0);
        }
    }
);

Notez que dans le premier exemple ci-dessus, j'ai déplacé les valeurs Wtrealm et MetadataAddress dans mon fichier de configuration pour faciliter la maintenance, il ne s'agit que de simples paramètres d'application:

<appSettings>
    <add key="ida:Wtrealm" value="[app-uri]" />
    <add key="ida:FedMetadataURI" value="https://[adfs-server]/federationmetadata/2007-06/federationmetadata.xml" />
</appSettings>

J'espère que ça aide.

14
Tom Tregenna

En fait, vous manquez juste cette ligne qui est généralement avant l'appel de la méthode UseCookieAuthentication.

app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

dans votre cas ce serait

app.UseExternalSignInCookie(WsFederationAuthenticationDefaults.AuthenticationType);

C'est ce qui est réellement exécuté lorsque vous appelez UseExternalSignInCookie (...), externalAuthenticationType est ce que vous transmettez en tant que paramètre de chaîne.

app.SetDefaultSignInAsAuthenticationType(externalAuthenticationType);
CookieAuthenticationOptions options = new CookieAuthenticationOptions();
options.AuthenticationType = externalAuthenticationType;
options.AuthenticationMode = AuthenticationMode.Passive;
options.CookieName = ".AspNet." + externalAuthenticationType;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5.0);
app.UseCookieAuthentication(options);

Donc, si vous ne définissez que le type AuthenticationType, vous pouvez simplement appeler UseExternalSignInCookie comme il le fait pour vous.

1
John C