Windows XP 以降で実行する必要がある WPF クライアント アプリケーションで、ユーザーの SAML トークンを取得しようとしています。WS-Trust を使用して ID プロバイダーから SAML を取得し、それを Azure Access Control Service に渡します。Azure Access Control Service は、O-Auth を使用してシンプルな Web トークンを返します。これを使用して、クライアントでユーザーを認証し、安全な API を呼び出します。 ACS を信頼する Azure で。
私のコードは WIF (Windows Identity Foundation) を使用しており、windows-xp 以上のオペレーティング システムで正常に動作します。これについて私が見た唯一の例は、WIF を使用してセキュリティ トークン サービスから SAML トークンを要求していますが、WIF は windows-xp ではサポートされていないため、行き詰まっています。私はいくつかの調査を試みましたが、WIF を使用せずに上記のシナリオを達成する方法を見つけることができませんでした。Windows XP クライアントでこれを行う方法はありますか? そうでない場合、私は何を別の方法で行う必要がありますか?
トークンを取得するために使用するコードは次のとおりです。
//UserCredential を使用して ACS レルムの STS から SamlToken を取得します。これは WIF を使用します
private SecurityToken GetSamlToken(string realm, string stsEndpoint, UserCredential userCredential)
{
Logger.Info("Getting Saml Token from Identity provider...");
using (var factory = new WSTrustChannelFactory(new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential), new EndpointAddress(new Uri(stsEndpoint))))
{
factory.Credentials.UserName.UserName = userCredential.UserName;
factory.Credentials.UserName.Password = userCredential.Password;
factory.TrustVersion = TrustVersion.WSTrust13;
WSTrustChannel channel = null;
try
{
var rst = new RequestSecurityToken
{
RequestType = WSTrust13Constants.RequestTypes.Issue,
AppliesTo = new EndpointAddress(realm),
KeyType = KeyTypes.Bearer,
};
channel = (WSTrustChannel)factory.CreateChannel();
RequestSecurityTokenResponse response;
var token = channel.Issue(rst, out response);
Logger.Info("Got Saml Token from Identity provider.");
return token;
}
finally
{
if (channel != null)
{
channel.Abort();
}
factory.Abort();
}
}
}
//STS から取得した xmlSamlToken を使用して、ACS serviceEndpoint から OAuthToken を取得します。
private NameValueCollection GetOAuthToken(string xmlSamlToken, string serviceEndpoint, string acsRelyingParty)
{
Logger.Info("Passing Saml token to ACS...");
WebClient client = new WebClient { BaseAddress = serviceEndpoint };
var values = new NameValueCollection
{
{ "grant_type", "urn:oasis:names:tc:SAML:2.0:assertion" },
{ "assertion", xmlSamlToken },
{ "scope", acsRelyingParty }
};
byte[] acsTokenResponse = client.UploadValues("v2/OAuth2-13", "POST", values);
string acsToken = Encoding.UTF8.GetString(acsTokenResponse);
var tokens = new NameValueCollection();
var parsed = new JavaScriptSerializer().DeserializeObject(acsToken) as Dictionary<string, object>;
Logger.Info("Parsed OAuth token.");
foreach (var item in parsed)
{
tokens.Add(item.Key, item.Value.ToString());
}
Logger.Info("Returning OAuth token.");
return tokens;
}