認証にADFSを使用しているASP.NETWebApiにアクセスする必要がある状況にあります。 ADFSログインポータルを経由して関連するFedAuthCookieを取得することにより、ブラウザーから確実にヒットできます。残念ながら、モバイルアプリで使用するには、専用ブラウザの外部からアクセスする必要があります。このプロジェクトは、職場および学校の認証(オンプレミス)用にセットアップされ、Cookie認証用にセットアップされた標準のVisual Studio WebAPIテンプレートのわずかに変更されたバージョンです。
startup.Auth.csからのコードのビット:
public void Configuration(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseWsFederationAuthentication(
new WsFederationAuthenticationOptions
{
Wtrealm = realm,
MetadataAddress = adfsMetadata
});
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType
});
}
どこから始めればいいのかわからないようです。 ADFSからアクセストークンをリクエストしようとしましたが、関連するログイン情報を使用してさまざまなバージョンのSAMLアサーションを取得できますが、WebAPIによって拒否されます。それがどのように機能するのか誤解しましたか?
私の理解から、それは次のようになるはずです: 私はそれがどのように機能すると思うか
これは、正しいトークンを取得する方法を見つけようとしているときに私が今持っているものです。
using System;
using System.IdentityModel.Protocols.WSTrust;
using System.IdentityModel.Tokens;
using System.Net;
using System.Net.Http;
using System.ServiceModel;
using System.ServiceModel.Security;
using Thinktecture.IdentityModel.Extensions;
using Thinktecture.IdentityModel.WSTrust;
namespace ConsoleApplication1
{
class Program
{
private const string UserName = "USERNAME";
private const string Password = "PASSWORD";
private const string Domain = "DOMAIN";
private const string ADFSEndpoint = "ADFS ENDPOINT";
private const string ApiBaseUri = "THE API";
private const string ApiEndPoint = "AN ENDPOINT";
static void Main(string[] args)
{
SecurityToken token = RequestSecurityToken(); // Obtain security token from ADFS.
CallApi(token); // Call api.
Console.ReadKey(); // Stop console from closing
}
private static SecurityToken RequestSecurityToken()
{
var trustChannelFactory =
new WSTrustChannelFactory(new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
new EndpointAddress(new Uri(ADFSEndpoint)))
{
TrustVersion = TrustVersion.WSTrust13,
Credentials = { UserName = { UserName = UserName + "@" + Domain, Password = Password } },
};
var requestSecurityToken = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
KeyType = KeyTypes.Bearer,
AppliesTo = new EndpointReference(ApiBaseUri)
};
RequestSecurityTokenResponse response;
var securityToken = trustChannelFactory.CreateChannel().Issue(requestSecurityToken, out response);
return securityToken;
}
private static async void CallApi(SecurityToken securityToken)
{
using (var handler = new HttpClientHandler { CookieContainer = new CookieContainer() })
{
using (var client = new HttpClient(handler))
{
handler.CookieContainer.MaxCookieSize = 8000; // Trying to make sure I can fit it in the cookie
var cookie = new Cookie {
Name = "FedAuth",
Value = Base64Encode(securityToken.ToTokenXmlString()),
HttpOnly = true,
Secure = true
};
handler.CookieContainer.Add(new Uri(ApiBaseUri), cookie);
var response = client.GetAsync(new Uri(ApiBaseUri + ApiEndPoint)).Result;
string result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
}
}
public static string Base64Encode(string plainText)
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes);
}
}
}
自分の例に基づいたコードを完全に思い出せませんが、誰かが私を正しい方向に向けたり、どこでめちゃくちゃにしたか教えてくれたら、ありがたいです。
編集:申し訳ありませんが、私が得ているものを追加するのを忘れました。 Web Apiは、例外がスローされたために大量のデバッグ情報を吐き出し、明らかに取得しているsaml:Assertionの代わりにSecurityContextTokenが必要であることを通知します。たぶん私のgooglefooは十分に強力ではありませんが、これからどこから始めればよいのか理解できないようです。 SAMLアサーションを受け入れるようにAPIを設定できますか、それとも別の方法でトークンをリクエストする必要がありますか?
WS-Fedを使用してWebAPIを呼び出すことはできません。 OpenID Connect/OAuthのように AzureADとOpenIDConnectを使用してWebアプリでWebAPIを呼び出す が必要です。
これはAzureAD用ですが、フローを示しています。
ADFSのどのバージョンですか?