我正在尝试确定应用程序检索 SAML 令牌的方法,以代表应用程序的当前上下文(作为用户)访问依赖方信任。
常见的建议是使用 WSTrustChannelFactory 检索 SAML 令牌,但提供用户名和密码。我不想这样做,这样对用户来说是无缝的。我觉得 ADFS 应该支持此请求的 SSO 身份验证(使用直通 Windows 身份验证)。这可能吗?
以下是需要凭据的典型推荐代码:
public SecurityToken GetSamlToken()
{
using (var factory = new WSTrustChannelFactory(
new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
new EndpointAddress(new Uri("https://serv/adfs/services/trust/13/usernamemixed"))))
{
factory.Credentials.UserName.UserName = "username";
factory.Credentials.UserName.Password = "password";
factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
factory.TrustVersion = TrustVersion.WSTrust13;
WSTrustChannel channel = null;
try
{
string KeyType;
var rst = new RequestSecurityToken
{
RequestType = WSTrust13Constants.RequestTypes.Issue,
AppliesTo = new EndpointAddress("net.tcp://localhost:xxxx/Service1/mex"),
KeyType = Microsoft.IdentityModel.Protocols.WSTrust.WSTrust13Constants.KeyTypes.Bearer,
};
channel = (WSTrustChannel)factory.CreateChannel();
return channel.Issue(rst);
}
finally
{
if (channel != null)
{
channel.Abort();
}
factory.Abort();
}
}
}
谢谢您的帮助!
如果您使用的是本地 AD FS,您仍然可以使用 .Net 7 及更高版本上 ADFS 的
windowstransport
端点,通过集成 Windows 身份验证 (SPNEGO) 获取令牌:
var binding = new WS2007HttpBinding();
binding.Security.Mode = SecurityMode.Transport;
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Message.NegotiateServiceCredential = false;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
var factory = new WSTrustChannelFactory(binding, new EndpointAddress(
"https://adfs.example.com/adfs/services/trust/13/windowstransport"));
var req = new WsTrustRequest(WsTrustActions.Trust13.Issue)
{
AppliesTo = new AppliesTo(new EndpointReference("urn:example:rp:identity")),
KeyType = WsTrustKeyTypes.Trust13.Bearer,
WsTrustVersion = WsTrustVersion.Trust13,
};
var stschannel = factory.CreateTrustChannel();
var token = (GenericXmlSecurityToken)await stschannel.IssueAsync(req);
Console.WriteLine(token.TokenXml.OuterXml);
您需要添加对以下内容的引用:
<ItemGroup>
<PackageReference Include="System.ServiceModel.Federation" Version="8.0.0" />
<PackageReference Include="System.ServiceModel.Http" Version="8.0.0" />
<PackageReference Include="Microsoft.IdentityModel.Tokens.Saml" Version="7.4.0" />
</ItemGroup>
另一方面,netcore 不支持 windowsmixed
/TransportWithMessageCredential
。