本文介绍了如何验证ADFS SAML令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我目前从这样的ADFS产生SAML令牌:I am currently generating SAML tokens from ADFS like this: WSTrustChannelFactory factory = null; try { // use a UserName Trust Binding for username authentication factory = new WSTrustChannelFactory( new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential), new EndpointAddress("https://adfs.company.com/adfs/services/trust/13/usernamemixed")); factory.TrustVersion = TrustVersion.WSTrust13; factory.Credentials.UserName.UserName = "user"; factory.Credentials.UserName.Password = "pw"; var rst = new RequestSecurityToken { RequestType = RequestTypes.Issue, AppliesTo = new EndpointReference(relyingPartyId), KeyType = KeyTypes.Bearer }; IWSTrustChannelContract channel = factory.CreateChannel(); GenericXmlSecurityToken genericToken = channel.Issue(rst) as GenericXmlSecurityToken; } finally { if (factory != null) { try { factory.Close(); } catch (CommunicationObjectFaultedException) { factory.Abort(); } } }现在让我们说我建一个使用这些令牌身份验证的Web应用程序。据我知道的工作流程应该是这样的:Now let's say I build a web application that uses these tokens for authentication. As far as I know the workflow should be like this: 生成令牌 客户端获取生成令牌(有效登录后) 客户端缓存标记 客户端使用令牌下次登录 Web应用程序验证带道理,不必调用ADFSGenerate tokenclient gets generated token (after valid login)client caches tokenclient uses token for next loginweb application validates token, does not have to call ADFS我如何可以验证客户出示令牌是有效的?我需要的ADFS服务器解密令牌的证书?How can I validate that the token the client presents is valid? Do I need the certificate of the ADFS server to decrypt the token?推荐答案看优秀thinktecture身份服务器代码(后 https://github.com/thinktecture/Thinktecture.IdentityServer .V2 /树/主/ src目录/库/ Thinktecture.IdentityServer.Protocols / AdfsIntegration )我提取的解决方案:After looking at the excellent thinktecture identity server code ( https://github.com/thinktecture/Thinktecture.IdentityServer.v2/tree/master/src/Libraries/Thinktecture.IdentityServer.Protocols/AdfsIntegration ) I extracted the solution:using Newtonsoft.Json;using System;using System.IdentityModel.Protocols.WSTrust;using System.IdentityModel.Selectors;using System.IdentityModel.Tokens;using System.IO;using System.Linq;using System.Security.Claims;using System.Security.Cryptography.X509Certificates;using System.ServiceModel;using System.ServiceModel.Security;using System.Text;using System.Xml;using Thinktecture.IdentityModel.Extensions;using Thinktecture.IdentityModel.WSTrust;namespace SimpleWebConsole{internal class ADFS{ public static void tokenTest() { string relyingPartyId = "https://party.mycomp.com"; WSTrustChannelFactory factory = null; try { // use a UserName Trust Binding for username authentication factory = new WSTrustChannelFactory( new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential), new EndpointAddress("https://adfs.mycomp.com/adfs/services/trust/13/usernamemixed")); factory.TrustVersion = TrustVersion.WSTrust13; factory.Credentials.UserName.UserName = "test"; factory.Credentials.UserName.Password = "test"; var rst = new RequestSecurityToken { RequestType = RequestTypes.Issue, AppliesTo = new EndpointReference(relyingPartyId), KeyType = KeyTypes.Bearer }; IWSTrustChannelContract channel = factory.CreateChannel(); GenericXmlSecurityToken genericToken = channel.Issue(rst) as GenericXmlSecurityToken; //MessageSecurityException -> PW falsch var _handler = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection(); var tokenString = genericToken.ToTokenXmlString(); var samlToken2 = _handler.ReadToken(new XmlTextReader(new StringReader(tokenString))); ValidateSamlToken(samlToken2); X509Certificate2 certificate = null; X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly); certificate = store.Certificates.Find(X509FindType.FindByThumbprint, "thumb", false)[0]; var jwt=ConvertSamlToJwt(samlToken2, "https://party.mycomp.com", certificate); } finally { if (factory != null) { try { factory.Close(); } catch (CommunicationObjectFaultedException) { factory.Abort(); } } } } public static TokenResponse ConvertSamlToJwt(SecurityToken securityToken, string scope, X509Certificate2 SigningCertificate) { var subject = ValidateSamlToken(securityToken); var descriptor = new SecurityTokenDescriptor { Subject = subject, AppliesToAddress = scope, SigningCredentials = new X509SigningCredentials(SigningCertificate), TokenIssuerName = "https://panav.mycomp.com", Lifetime = new Lifetime(DateTime.UtcNow, DateTime.UtcNow.AddMinutes(10080)) }; var jwtHandler = new JwtSecurityTokenHandler(); var jwt = jwtHandler.CreateToken(descriptor); return new TokenResponse { AccessToken = jwtHandler.WriteToken(jwt), ExpiresIn = 10080 }; } public static ClaimsIdentity ValidateSamlToken(SecurityToken securityToken) { var configuration = new SecurityTokenHandlerConfiguration(); configuration.AudienceRestriction.AudienceMode = AudienceUriMode.Never; configuration.CertificateValidationMode = X509CertificateValidationMode.None; configuration.RevocationMode = X509RevocationMode.NoCheck; configuration.CertificateValidator = X509CertificateValidator.None; var registry = new ConfigurationBasedIssuerNameRegistry(); registry.AddTrustedIssuer("thumb", "ADFS Signing - mycomp.com"); configuration.IssuerNameRegistry = registry; var handler = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection(configuration); var identity = handler.ValidateToken(securityToken).First(); return identity; } public class TokenResponse { [JsonProperty(PropertyName = "access_token")] public string AccessToken { get; set; } [JsonProperty(PropertyName = "token_type")] public string TokenType { get; set; } [JsonProperty(PropertyName = "expires_in")] public int ExpiresIn { get; set; } [JsonProperty(PropertyName = "refresh_token")] public string RefreshToken { get; set; } }}} 这篇关于如何验证ADFS SAML令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
07-30 11:57