我正在尝试以编程方式检索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接受令牌并给我一个联合令牌?