Autentica chiamata WCF a ADFS tramite proxy dell'applicazione Web (WAP)

0

Attualmente autenticiamo le chiamate WCF a un servizio tramite ADFS, utilizzando la seguente procedura:

In primo luogo, otteniamo un token SAML da ADFS

using (var factory = new WSTrustChannelFactory(
   new UserNameWSTrustBinding(System.ServiceModel.SecurityMode.TransportWithMessageCredential),
   new System.ServiceModel.EndpointAddress(new Uri(_aDFSUsernameMixedUri))))
    {
        System.IdentityModel.Configuration.SecurityTokenServiceConfiguration serviceConfig = new System.IdentityModel.Configuration.SecurityTokenServiceConfiguration();
        factory.Credentials.UserName.UserName = _apiUser;
        factory.Credentials.UserName.Password = _apiPassword;
        factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = serviceConfig.CertificateValidationMode;
        factory.TrustVersion = System.ServiceModel.Security.TrustVersion.WSTrust13;
        WSTrustChannel channel = null;
        try
        {
            var rst = new RequestSecurityToken
            {
                RequestType = WSTrust13Constants.RequestTypes.Issue,
                AppliesTo = new System.ServiceModel.EndpointAddress(_endpointUri),
                TokenType = "urn:oasis:names:tc:SAML:2.0:assertion",
                //KeyType = KeyTypes.Symmetric
                KeyType = KeyTypes.Bearer

            };

            var token = factory.CreateChannel().Issue(rst) as System.IdentityModel.Tokens.GenericXmlSecurityToken;

Usiamo il / adfs / services / trust / 13 / usernamemixed endpoint (variabile _aDFSUsernameMixedUri). Questo endpoint è abilitato per il proxy.

In secondo luogo, utilizziamo questo token SAML per contattare il nostro servizio:

using (HttpClient httpClient = new HttpClient() { BaseAddress = baseAddress })
        {
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("SAML", saml);
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            string jsonString = JsonConvert.SerializeObject(model);
            HttpResponseMessage response = await httpClient.PostAsync(Url, new StringContent(jsonString, Encoding.UTF8, "application/json"));
            return response;

        }

Vale la pena ricordare che il servizio accetta solo richieste autenticate e leggerà i dettagli dell'autorizzazione dal token SAML (che è firmato e crittografato). È così che il servizio è protetto.

Ora vogliamo proteggere il nostro server ADFS utilizzando un proxy ADFS (proxy dell'applicazione Web). La chiamata a ADFS per il token SAML funziona ancora e restituisce un token SAML. Tuttavia, il secondo passaggio non riesce . HTTPRequest è bloccato dal server proxy ADFS e reindirizza la chiamata alla pagina di accesso ADFS , che ovviamente non è quello che voglio.

Ho già provato a impostare passiveRedirectEnabled="false", ma questo non aiuta. Qualche idea su dove devo mettere il token SAML in HTTPRequest per far sapere al proxy che si tratta di una richiesta autenticata?

UPDATE

Il proxy ADFS utilizza un EdgeAccessCookie per decidere se reindirizzare o meno la richiesta al server ADFS. Nel caso in cui potessi aggiungere questo EdgeAccessCookie alla richiesta, il proxy probabilmente interromperebbe il blocco della richiesta. Come posso recuperare questo EdgeAccessCookie in una richiesta WCF?

    
posta Michael 11.08.2014 - 17:48
fonte

2 risposte

1

Il Proxy dell'applicazione Web utilizza un token di autorizzazione per decidere se impostare o meno EdgeAccessCookie. Se puoi richiedere il token di autorizzazione e inserirlo nell'URL del tuo HTTPRequest, il WAP ti permetterà di passare. Frammenti di codice:

        List<KeyValuePair<string, string>> postData = new List<KeyValuePair<string, string>>();
        postData.Add(new KeyValuePair<string, string>("UserName", username));
        postData.Add(new KeyValuePair<string, string>("Password", pw));
        postData.Add(new KeyValuePair<string, string>("AuthMethod", "FormsAuthentication"));
        HttpContent content = new FormUrlEncodedContent(postData);

        WebRequestHandler webRequestHandler = new WebRequestHandler();
        webRequestHandler.AllowAutoRedirect = true;
        webRequestHandler.MaxAutomaticRedirections = 1;

        HttpResponseMessage response;
        using (HttpClient client = new HttpClient(webRequestHandler))
        {
            response = client.PostAsync(https://FQDNADFS/adfs/ls?version=1.0&action=signin&realm=urn:AppProxy:com&appRealm=REALMOFAPI&returnUrl=RETURNURL&RedirectToIdentityProvider=IDENTITYPROVIDER, content).Result;
        }

        authToken = HttpUtility.ParseQueryString(response.Headers.Location.Query)["authToken"];
        return authToken;

Lo snippet sopra riportato ti darà il codice di autorizzazione, che dovresti includere nell'URL della tua richiesta HTTP:

HttpResponseMessage response = await httpClient.PostAsync(Url + "/?authToken=" + authToken, new StringContent(jsonString, Encoding.UTF8, "application/json"));

In combinazione con il codice della mia domanda (nessuna modifica), WebAPI è protetto dal WAP. Buona fortuna.

    
risposta data 19.08.2014 - 16:05
fonte
0

In che modo esattamente il secondo passo è bloccato dal proxy ADFS? Il proxy dovrebbe bloccare solo le chiamate ADFS, non le chiamate al tuo servizio. Dal momento che le chiamate per ottenere il token funzionano correttamente, direi che l'installazione funziona come dovrebbe ADFS-saggio.

Dove le cose diventano difficili è nella configurazione del servizio che stai proteggendo. Per caso hai eseguito il tuo servizio tramite una delle app fedutil in Visual Studio durante la riconfigurazione del proxy ADFS? Questo ha bloccato un blocco di autorizzazione passivo in web.config , quindi tutte le richieste devono essere autorizzate, invece di consentire al servizio di gestirle?

Quello che devi fare è tracciare l'origine della risposta di reindirizzamento. Nulla nel servizio dovrebbe essere forzato perché le fondamenta del servizio (di solito) lo sanno meglio. Alcuni dei soliti colpevoli sono FormsAuthenticationModule , SessionAuthenticationModule + WSFederationAuthenticationModule , ecc.

    
risposta data 11.08.2014 - 18:26
fonte

Leggi altre domande sui tag