9

我想制作一个MVC Web应用程序,该应用程序可与Web API应用程序对话并使用ADFS 2.0(在Windows 2008 R2上)进行身份验证。ADFS 2.0 Windows 2008 R2 Web API

我设法让MVC Web应用程序使用ADFS进行身份验证。问:但我不知道我应该如何将我的ADFS 2.0(在Windows 2008 R2上)从MVC Web联合到Web API(假设他们将部署在不同的服务器中)?

Browser-ADFS 2.0-Web MVC-Backend Web API

我发现了很多关于如何使用WCF或Windows Server 2012 R2,而不是在Windows Server 2008 R2


编辑Web API和ADFS 2.0做到这一点的文章,最后,我去了poor man delegation(将前端收到的同一个标记传递给后端(因为再次调用adfs没有任何意义)

FrontEnd - >调用GetToken并将授权标题(我编码它为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->解析和验证令牌的所述>

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

回答

1

我通过使我是从ADF的接收到web API调用的授权报头中的承载的令牌实现这一点,然后使用Microsoft.Owin.Security.Jwt nuget包将令牌转换为httpcontext当前标识,以便在web api项目的owin启动过程中进行。

本示例使用jwt令牌作为载体令牌。为要使用的令牌类型选择适当的NuGet包。

构建的WebRequest在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; 

Owin Startup.cs文件的Web API 的app.UseWebApi(配置)前行。

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

问题是您无法使ADFS 2008 R2发送JWT令牌,有时bc.Token为空。如果您有兴趣查看我使用的解决方案的编辑 –