9

Vorrei creare un'applicazione Web MVC che comunichi con un'applicazione Web API e utilizzi ADFS 2.0 (su Windows 2008 R2) per l'autenticazione.ADFS 2.0 API Web Windows 2008 R2

Sono riuscito a rendere l'applicazione Web MVC per l'autenticazione tramite ADFS.

D: Ma non so come devo federare il mio ADFS 2.0 (su Windows 2008 R2) da MVC Web a Web API (supponendo che verranno distribuiti in server separati)?

Browser-ADFS 2.0-Web MVC-Backend Web API

ho trovato un sacco di articoli su come fare questo con WCF o Windows Server 2012 R2, ma non con API Web e ADFS 2.0 in Windows Server 2008 R2


Modifica, Alla fine sono andato su poor man delegation (passando lo stesso token che ricevo dal front-end al backend (come non avrebbe senso chiamare di nuovo gli adfs)

FrontEnd -> Chiama GetToken e immetti l'autorizzazione header (lo codifico a base64)

public string GetToken() 
{ 
    BootstrapContext bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as BootstrapContext; 
    string token = bootstrapContext.Token; 

    if (string.IsNullOrEmpty(token)) 
     token = ToTokenXmlString(bootstrapContext.SecurityToken as SamlSecurityToken); 

    return token; 
} 

string ToTokenXmlString(SecurityToken token) 
{ 
    var genericToken = token as GenericXmlSecurityToken; 

    if (genericToken != null) 
     return genericToken.TokenXml.OuterXml; 

    var handler = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection(); 
    return ToTokenXmlString(token, handler); 
} 

string ToTokenXmlString(SecurityToken token, SecurityTokenHandlerCollection handler) 
{ 
    if (!handler.CanWriteToken(token)) 
     throw new InvalidOperationException("Token type not suppoted"); 

    var sb = new StringBuilder(128); 
    using (StringWriter stringWriter = new StringWriter(sb)) 
    { 
     using (var textWriter = new XmlTextWriter(stringWriter)) 
     { 
      handler.WriteToken(textWriter, token); 
      return sb.ToString(); 
     } 
    } 
} 

Backend-> analizzare e convalidare il Token>

public ClaimsIdentity GetIdentityFromToken(string tokenBase64) 
{ 
    if (string.IsNullOrEmpty(tokenBase64)) 
     return null; 

    byte[] tokenByteArray = Convert.FromBase64String(tokenBase64); 
    string decodedToken = Encoding.UTF8.GetString(tokenByteArray); 

    if (string.IsNullOrWhiteSpace(decodedToken)) 
     return null; 
    try 
    { 
     var handlers = FederatedAuthentication.FederationConfiguration.IdentityConfiguration.SecurityTokenHandlers; 
     SecurityToken token; 
     using (StringReader stringReader = new StringReader(decodedToken)) 
     { 
      using (XmlTextReader xmlReader = new XmlTextReader(stringReader)) 
      { 
       token = handlers.ReadToken(xmlReader); 
      } 
     } 

     if (token == null) 
      return null; 

     return handlers.ValidateToken(token).FirstOrDefault(); 
    } 
    catch (Exception e) 
    { 
     logger.Error(new AuthenticationException("Error validating the token from ADFS", e)); 

     return null; 
    } 
} 

risposta

1

ho implementato questo facendo passare il token portatore che ho ricevuto da ADFS nell'intestazione autorizzazione della chiamata API Web, e quindi utilizzando il pacchetto nuget Microsoft.Owin.Security.Jwt per tradurre il token nell'identità corrente di httpcontext durante l'avvio di owin nel progetto web api.

Questo esempio utilizza un token jwt come token al portatore. Scegliere il pacchetto NuGet appropriato per il tipo di token che si desidera utilizzare.

Costruisce l'WebRequest controller MVC

BootstrapContext bc = ClaimsPrincipal.Current.Identities.First().BootstrapContext as BootstrapContext; 
HttpWebRequest request = WebRequest.Create(ConfigurationManager.AppSettings["ApiUrl"]) as HttpWebRequest; 
request.Method = "GET"; 
request.Headers["Authorization"] = "Bearer " + bc.Token; 

file di Owin Startup.cs in Web API Prima linea app.UseWebApi (config).

app.UseJwtBearerAuthentication(
      new JwtBearerAuthenticationOptions 
      { 
       AuthenticationMode = AuthenticationMode.Active, 
       AllowedAudiences = new[] { ConfigurationSettings.AppSettings["ida:Realm"] }, 
       IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[] 
        { 
         new SymmetricKeyIssuerSecurityTokenProvider(
          ConfigurationSettings.AppSettings["ida:ValidIssuer"], 
          ConfigurationSettings.AppSettings["ida:SymmetricKey"]) 
        }, 
       Provider = new OAuthBearerAuthenticationProvider 
       { 
        OnValidateIdentity = context => 
        { 
         return System.Threading.Tasks.Task.FromResult<object>(null); 
        } 
       } 
      }); 
+1

Il problema è che non si può fare ADFS 2008 R2 per inviare JWT token e talvolta bc.Token è nullo. Se sei interessato, guarda la modifica della soluzione che ho usato –