Asp.net-Mvc

ADFS 2.0 Windows 2008 R2 Web API

  • October 6, 2014

我想製作一個與 Web API 應用程序對話並使用 ADFS 2.0(在 Windows 2008 R2 上)進行身份驗證的 MVC Web 應用程序。

我設法使 MVC Web 應用程序使用 ADFS 進行身份驗證。

問:但我不知道我應該如何將我的 ADFS 2.0(在 Windows 2008 R2 上)從 MVC Web 聯合到 Web API(假設它們將部署在不同的伺服器中)?

瀏覽器-ADFS 2.0-Web MVC-後端 Web API

我發現了很多關於如何使用 WCF 或 Windows Server 2012 R2 執行此操作的文章,但沒有使用 Windows Server 2008 R2 中的 Web API 和 ADFS 2.0


編輯,最後我選擇了窮人委託(將我收到的前端令牌傳遞給後端(因為再次呼叫 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();
       }
   }
}

後端-> 解析並驗證令牌->

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

我通過將我從 Adfs 收到的不記名令牌傳遞到 web api 呼叫的授權標頭來實現這一點,然後在 owin 啟動期間使用 Microsoft.Owin.Security.Jwt nuget 包將令牌轉換為 httpcontext 目前身份網路 API 項目。

此範例使用 jwt 令牌作為不記名令牌。為要使用的令牌類型選擇正確的 NuGet 包。

在 mvc 控制器中構造 WebRequest

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;

Web api 中的 Owin Startup.cs 文件 在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);
                   }
               }
           });

引用自:https://stackoverflow.com/questions/24231347