我正在尝试以编程方式检索 SAML 令牌,出于各种原因(好奇心和测试将它们发送到 Web 服务是主要的原因),并且正在努力从 Windows Azure ACS 检索令牌。
我已经使用 Thinktecture 的 IdentityServer 设置了一个身份提供程序,并且能够使用以下代码从中检索 SAML 令牌:
public static string GetSamlTokenForUsername(string issuerUrl,
string username, string password)
{
var trustChannelFactory =
new Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannelFactory(
new Microsoft.IdentityModel.Protocols.WSTrust.Bindings.UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
new EndpointAddress(new Uri(issuerUrl)));
trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;
trustChannelFactory.Credentials.UserName.UserName = username;
trustChannelFactory.Credentials.UserName.Password = password;
try
{
var tokenString = RequestToken(trustChannelFactory);
trustChannelFactory.Close();
return tokenString;
}
catch (Exception)
{
trustChannelFactory.Abort();
throw;
}
}
private static string RequestToken(Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannelFactory trustChannelFactory)
{
var rst =
new RequestSecurityToken(Thinktecture.IdentityModel.Constants.WSTrust13Constants.RequestTypes.Issue,
Thinktecture.IdentityModel.Constants.WSTrust13Constants.KeyTypes.Bearer);
rst.AppliesTo = new EndpointAddress("https://localhost/");
rst.TokenType = Microsoft.IdentityModel.Tokens.SecurityTokenTypes.Saml2TokenProfile11;
var channel = (Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannel)trustChannelFactory.CreateChannel();
var token = channel.Issue(rst) as GenericXmlSecurityToken;
var tokenString = token.TokenXml.OuterXml;
return tokenString;
}
然而,在 ACS 中,我将我的应用程序设置为 RP,并将其配置为使用两个身份提供程序,其中一个是我的 Thinktecture IP。
当我尝试使用上述代码从 Azure ACS 检索令牌时,它不再起作用,并且我收到了一个异常。我相信这是因为我对 ACS 角色的理解是错误的,而且 ACS 是“联邦者”,所以我不能简单地向它索要令牌。我现在相信它应该通知我可用的身份提供者,并给我足够的信息来定位它们并获得一个我应该返回给 ACS 的令牌。
我究竟如何从代码中做到这一点?这是 WS-Federation 而不是 WS-Trust(我还不太了解这些术语)?假设我已经可以从身份提供者那里获得 SAML 令牌,我如何让 ACS 接受令牌并给我一个联合令牌?