cudreg-saml2/App_Code/SAMLHelper.vb
2025-06-08 17:37:21 +07:00

83 lines
3.7 KiB
VB.net

Imports System.IO
Imports System.Text
Imports System.Xml
Imports System.Security.Cryptography
Imports System.Security.Cryptography.X509Certificates
Imports System.Security.Cryptography.Xml
Imports System.IO.Compression
Namespace SAML
Public Class SamlHelper
Public Shared Function CreateAuthRequest(issuer As String, assertionConsumerServiceUrl As String) As String
Dim id = "_" & Guid.NewGuid().ToString()
Dim issueInstant = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")
Dim requestXml As String = String.Format( _
"<samlp:AuthnRequest xmlns:samlp=""urn:oasis:names:tc:SAML:2.0:protocol"" ID=""{0}"" Version=""2.0"" IssueInstant=""{1}"" ProtocolBinding=""urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"" AssertionConsumerServiceURL=""{2}"">" & vbCrLf & _
" <saml:Issuer xmlns:saml=""urn:oasis:names:tc:SAML:2.0:assertion"">{3}</saml:Issuer>" & vbCrLf & _
"</samlp:AuthnRequest>", _
id, issueInstant, assertionConsumerServiceUrl, issuer _
)
Dim bytes = Encoding.UTF8.GetBytes(requestXml)
Using ms = New MemoryStream()
Using zip = New DeflateStream(ms, CompressionMode.Compress, True)
zip.Write(bytes, 0, bytes.Length)
End Using
Dim compressedBytes = ms.ToArray()
Return Convert.ToBase64String(compressedBytes)
End Using
End Function
Public Class Response
Private ReadOnly _xml As XmlDocument
Private ReadOnly _certificate As X509Certificate2
Public Sub New(certString As String, base64Response As String)
Dim decoded = Convert.FromBase64String(base64Response)
Dim xmlString = Encoding.UTF8.GetString(decoded)
_xml = New XmlDocument()
_xml.PreserveWhitespace = True
_xml.LoadXml(xmlString)
_certificate = New X509Certificate2(Encoding.UTF8.GetBytes(certString))
End Sub
Public Function IsValid() As Boolean
Dim ns = New XmlNamespaceManager(_xml.NameTable)
ns.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#")
Dim signatureNode = _xml.SelectSingleNode("//ds:Signature", ns)
If signatureNode Is Nothing Then Return False
Dim signedXml = New SignedXml(_xml)
signedXml.LoadXml(CType(signatureNode, XmlElement))
Return signedXml.CheckSignature(_certificate, True)
End Function
Public Function GetEmail() As String
Return GetAttributeValue("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress")
End Function
Public Function GetFirstName() As String
Return GetAttributeValue("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname")
End Function
Public Function GetLastName() As String
Return GetAttributeValue("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname")
End Function
Private Function GetAttributeValue(attributeName As String) As String
Dim nsmgr = New XmlNamespaceManager(_xml.NameTable)
nsmgr.AddNamespace("saml", "urn:oasis:names:tc:SAML:2.0:assertion")
Dim attrNode = _xml.SelectSingleNode(String.Format("//saml:Attribute[@Name='{0}']/saml:AttributeValue", attributeName), nsmgr)
Return If(attrNode IsNot Nothing, attrNode.InnerText, String.Empty)
End Function
End Class
End Class
End Namespace