我正在测试使用自定义STS服务验证用途的产品。以前的工作方式是,当用户使用浏览器点击网站时,我们会发出重定向来点击STS服务。 STS服务通过按AD来验证用户,然后发出SAML令牌,其中包含一些用户的自定义声明。然后,该网站再次点击STS以获得ActAs令牌,以便我们可以与数据服务进行通信。
我有一个可以模仿这种行为并且在生产中工作正常的自动化。
我们没有修改STS以使用ADFS进行身份验证,而不是直接命中AD。所以现在当我点击网站时,请求被重定向到ADFS端点,该端点对用户进行身份验证并发出令牌。然后我们点击自定义STS服务,该服务将使用令牌对用户进行身份验证(而不是点击AD),添加自定义声明并为用户发出SAML令牌。然后我们使用它生成一个ActAs令牌,最终命中数据服务。
我正在尝试更新此更改行为的自动化。所以我现在正在做的是点击ADFS服务,获取一个令牌并将令牌传递给STS服务,这样它就可以发给我一个SAML令牌。
对于Windows身份识别服务我是一个非常业余的人,所以我很难尝试这项工作。我已成功从ADFS获取令牌(Bearer Token),但我无法弄清楚如何将此令牌传递给我的自定义STS,因此它可以向我发出SAML令牌。
任何帮助都将受到高度赞赏。谢谢!
这是我正在使用的代码
public static SecurityToken GetSecurityToken()
{
var endPoint = new EndpointAddress(new Uri(@"ADFS endpoint"));
var msgBinding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential, false);
msgBinding.Security.Message.EstablishSecurityContext = false;
msgBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
var factory = new WSTrustChannelFactory(msgBinding, endPoint);
factory.TrustVersion = TrustVersion.WSTrust13;
factory.Credentials.SupportInteractive = true;
factory.Credentials.UserName.UserName = "user";
factory.Credentials.UserName.Password = "pwd";
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
KeyType = KeyTypes.Bearer,
AppliesTo = new EndpointReference(@"custom STS endpoint")
};
return factory.CreateChannel().Issue(rst);
}
public static void GetUserClaimsFromSecurityTokenService(SecurityToken secToken)
{
var securityTokenManager = new SecurityTokenHandlerCollectionManager(string.Empty);
securityTokenManager[string.Empty] = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection();
var trustChannelFactory = new WSTrustChannelFactory(Binding, new EndpointAddress("custom STS endpoint"))
{
TrustVersion = TrustVersion.WSTrust13,
SecurityTokenHandlerCollectionManager = securityTokenManager,
};
var rst = new RequestSecurityToken(RequestTypes.Issue)
{
AppliesTo = new EndpointReference("website url"),
TokenType = SamlSecurityTokenHandler.Assertion
};
var channel = (WSTrustChannel)trustChannelFactory.CreateChannel();
channel.Open(TimeSpan.FromMinutes(15));
try
{
RequestSecurityTokenResponse rstr;
SecurityToken token = channel.Issue(rst, out rstr);
var genericToken = (GenericXmlSecurityToken)token;
var req = new SamlSecurityTokenRequirement();
var handler = new SamlSecurityTokenHandler(req)
{
Configuration = new SecurityTokenHandlerConfiguration()
};
var newToken = handler.ReadToken(new XmlNodeReader(genericToken.TokenXml));
}
finally
{
channel.Close();
}
}