Útmutató: Egyéni jogkivonat létrehozása
Ez a témakör bemutatja, hogyan hozhat létre egyéni biztonsági jogkivonatot az SecurityToken osztály használatával, és hogyan integrálható egy egyéni biztonsági jogkivonat-szolgáltatóval és -hitelesítővel. A teljes példakódért tekintse meg az egyéni jogkivonat mintáját.
A biztonsági jogkivonat lényegében egy XML-elem, amelyet a Windows Communication Foundation (WCF) biztonsági keretrendszer használ a SOAP-üzenetben lévő feladóval kapcsolatos jogcímek megjelenítésére. A WCF-biztonság különböző jogkivonatokat biztosít a rendszer által biztosított hitelesítési módokhoz. Ilyen például egy X.509-tanúsítvány biztonsági jogkivonata, amelyet az osztály vagy az X509SecurityTokenUserNameSecurityToken osztály által képviselt Felhasználónév biztonsági jogkivonat jelöl.
Néha a megadott típusok nem támogatják a hitelesítési módot vagy a hitelesítő adatokat. Ebben az esetben létre kell hoznia egy egyéni biztonsági jogkivonatot, amely xml-reprezentációt biztosít az egyéni hitelesítő adatokról a SOAP-üzenetben.
Az alábbi eljárások bemutatják, hogyan hozhat létre egyéni biztonsági jogkivonatot, és hogyan integrálható a WCF biztonsági infrastruktúrával. Ez a témakör létrehoz egy hitelkártya-jogkivonatot, amellyel adatokat továbbíthat az ügyfél hitelkártyájáról a kiszolgálónak.
További információ az egyéni hitelesítő adatokról és a biztonsági jogkivonat-kezelőről : Útmutató: Egyéni ügyfél- és szolgáltatás hitelesítő adatok létrehozása.
System.IdentityModel.Tokens További biztonsági jogkivonatokat képviselő osztályok névterének megtekintése.
Eljárások
Az ügyfélalkalmazásoknak meg kell adni a biztonsági infrastruktúra hitelkártyaadatainak megadásának módját. Ezeket az információkat egy egyéni ügyfél-hitelesítőadat-osztály teszi elérhetővé az alkalmazás számára. Az első lépés egy osztály létrehozása, amely az egyéni ügyfél hitelesítő adatainak hitelkártyaadatait jeleníti meg.
Olyan osztály létrehozása, amely hitelkártyaadatokat jelöl az ügyfél hitelesítő adatain belül
Adjon meg egy új osztályt, amely az alkalmazás hitelkártyaadatait jelöli. Az alábbi példa az osztály
CreditCardInfo
nevét adja.Adjon hozzá megfelelő tulajdonságokat az osztályhoz, hogy egy alkalmazás beállíthassa az egyéni jogkivonathoz szükséges információkat. Ebben a példában az osztály három tulajdonsággal rendelkezik:
CardNumber
,CardIssuer
ésExpirationDate
.public class CreditCardInfo { string cardNumber; string cardIssuer; DateTime expirationDate; public CreditCardInfo(string cardNumber, string cardIssuer, DateTime expirationDate) { this.cardNumber = cardNumber; this.cardIssuer = cardIssuer; this.expirationDate = expirationDate; } public string CardNumber { get { return this.cardNumber; } } public string CardIssuer { get { return this.cardIssuer; } } public DateTime ExpirationDate { get { return this.expirationDate; } } }
Public Class CreditCardInfo Private _cardNumber As String Private _cardIssuer As String Private _expirationDate As DateTime Public Sub New(ByVal cardNumber As String, ByVal cardIssuer As String, _ ByVal expirationDate As DateTime) Me._cardNumber = cardNumber Me._cardIssuer = cardIssuer Me._expirationDate = expirationDate End Sub Public ReadOnly Property CardNumber() As String Get Return Me._cardNumber End Get End Property Public ReadOnly Property CardIssuer() As String Get Return Me._cardIssuer End Get End Property Public ReadOnly Property ExpirationDate() As DateTime Get Return Me._expirationDate End Get End Property End Class
Ezután létre kell hozni egy osztályt, amely az egyéni biztonsági jogkivonatot jelöli. Ezt az osztályt a biztonsági jogkivonat-szolgáltató, a hitelesítő és a szerializáló osztály használja a biztonsági jogkivonattal kapcsolatos információk WCF biztonsági infrastruktúrába való továbbításához.
Egyéni biztonsági jogkivonat-osztály létrehozása
Definiáljon egy új osztályt, amely az SecurityToken osztályból származik. Ez a példa létrehoz egy osztályt
CreditCardToken
.Felülbírálja a tulajdonságot Id . Ez a tulajdonság a biztonsági jogkivonat helyi azonosítójának lekérésére szolgál, amely a SOAP-üzenet más elemeiből a biztonsági jogkivonat XML-reprezentációjára mutat. Ebben a példában a jogkivonat-azonosítók átadhatók konstruktorparaméterként, vagy egy új véletlenszerű azonosító jön létre minden alkalommal, amikor létrejön egy biztonsági jogkivonat-példány.
Implementálja a tulajdonságot SecurityKeys . Ez a tulajdonság a biztonsági jogkivonat-példány által képviselt biztonsági kulcsok gyűjteményét adja vissza. Ezeket a kulcsokat a WCF használhatja a SOAP-üzenet egyes részeinek aláírására vagy titkosítására. Ebben a példában a hitelkártya biztonsági jogkivonata nem tartalmazhat biztonsági kulcsokat; ezért a megvalósítás mindig üres gyűjteményt ad vissza.
Felülbírálja a tulajdonságokat és ValidTo a ValidFrom tulajdonságokat. Ezeket a tulajdonságokat a WCF használja a biztonsági jogkivonat-példány érvényességének meghatározásához. Ebben a példában a hitelkártya biztonsági jogkivonata csak lejárati dátummal rendelkezik, így a
ValidFrom
tulajdonság a DateTime példány létrehozásának dátumát és időpontját jelöli.class CreditCardToken : SecurityToken { CreditCardInfo cardInfo; DateTime effectiveTime = DateTime.UtcNow; string id; ReadOnlyCollection<SecurityKey> securityKeys; public CreditCardToken(CreditCardInfo cardInfo) : this(cardInfo, Guid.NewGuid().ToString()) { } public CreditCardToken(CreditCardInfo cardInfo, string id) { if (cardInfo == null) { throw new ArgumentNullException("cardInfo"); } if (id == null) { throw new ArgumentNullException("id"); } this.cardInfo = cardInfo; this.id = id; // The credit card token is not capable of any cryptography. this.securityKeys = new ReadOnlyCollection<SecurityKey>(new List<SecurityKey>()); } public CreditCardInfo CardInfo { get { return this.cardInfo; } } public override ReadOnlyCollection<SecurityKey> SecurityKeys { get { return this.securityKeys; } } public override DateTime ValidFrom { get { return this.effectiveTime; } } public override DateTime ValidTo { get { return this.cardInfo.ExpirationDate; } } public override string Id { get { return this.id; } } }
Friend Class CreditCardToken Inherits SecurityToken Private _cardInfo As CreditCardInfo Private _effectiveTime As DateTime = DateTime.UtcNow Private _id As String Private _securityKeys As ReadOnlyCollection(Of SecurityKey) Public Sub New(ByVal cardInfo As CreditCardInfo) Me.New(cardInfo, Guid.NewGuid().ToString()) End Sub Public Sub New(ByVal cardInfo As CreditCardInfo, _ ByVal id As String) If cardInfo Is Nothing Then Throw New ArgumentNullException("cardInfo") End If If id Is Nothing Then Throw New ArgumentNullException("id") End If Me._cardInfo = cardInfo Me._id = id ' The credit card token is not capable of any cryptography. Me._securityKeys = New ReadOnlyCollection(Of SecurityKey)(New List(Of SecurityKey)()) End Sub Public ReadOnly Property CardInfo() As CreditCardInfo Get Return Me._cardInfo End Get End Property Public Overrides ReadOnly Property SecurityKeys() As ReadOnlyCollection(Of SecurityKey) Get Return Me._securityKeys End Get End Property Public Overrides ReadOnly Property ValidFrom() As DateTime Get Return Me._effectiveTime End Get End Property Public Overrides ReadOnly Property ValidTo() As DateTime Get Return Me._cardInfo.ExpirationDate End Get End Property Public Overrides ReadOnly Property Id() As String Get Return Me._id End Get End Property End Class
Új biztonsági jogkivonat-típus létrehozásakor az osztály implementálására SecurityTokenParameters van szükség. Az implementáció a biztonsági kötéselem konfigurációjában az új jogkivonattípust jelöli. A biztonsági jogkivonat paraméterosztálya sablonként szolgál, amely az üzenet feldolgozásakor használt tényleges biztonsági jogkivonat-példánynak felel meg. A sablon további tulajdonságokat biztosít, amelyekkel az alkalmazás megadhat olyan feltételeket, amelyeknek a biztonsági jogkivonatnak meg kell egyeznie ahhoz, hogy használni vagy hitelesíteni lehessen. Az alábbi példa nem ad hozzá további tulajdonságokat, így csak a biztonsági jogkivonat típusa lesz megfeleltetve, amikor a WCF-infrastruktúra egy biztonsági jogkivonat-példányt keres, amelyet használni vagy ellenőrizni szeretne.
Egyéni biztonsági jogkivonat paraméterosztályának létrehozása
Definiáljon egy új osztályt, amely az SecurityTokenParameters osztályból származik.
Implementálja a metódust CloneCore . Másolja ki az osztályban definiált összes belső mezőt, ha van ilyen. Ez a példa nem határoz meg további mezőket.
Az írásvédett SupportsClientAuthentication tulajdonság implementálása. Ez a tulajdonság akkor ad vissza
true
, ha az osztály által képviselt biztonsági jogkivonat-típus használatával hitelesíthető egy ügyfél egy szolgáltatásban. Ebben a példában a hitelkártya biztonsági jogkivonatával hitelesítheti az ügyfelet egy szolgáltatásban.Az írásvédett SupportsServerAuthentication tulajdonság implementálása. Ez a tulajdonság akkor ad vissza
true
, ha az osztály által képviselt biztonsági jogkivonat-típus használható egy szolgáltatás ügyfél általi hitelesítésére. Ebben a példában a hitelkártya biztonsági jogkivonata nem használható szolgáltatás ügyfél általi hitelesítésére.Az írásvédett SupportsClientWindowsIdentity tulajdonság implementálása. Ez a tulajdonság akkor ad
true
vissza, ha az osztály által képviselt biztonsági jogkivonattípus windowsos fiókhoz rendelhető. Ha igen, a hitelesítési eredményt egy WindowsIdentity osztálypéldány jelöli. Ebben a példában a jogkivonat nem képezhető le Windows-fiókra.Implementálja a metódust CreateKeyIdentifierClause(SecurityToken, SecurityTokenReferenceStyle) . Ezt a metódust a WCF biztonsági keretrendszere hívja meg, ha a biztonsági jogkivonat paraméterosztálya által képviselt biztonsági jogkivonat-példányra kell hivatkoznia. A rendszer a tényleges biztonsági jogkivonat-példányt és SecurityTokenReferenceStyle a kért hivatkozás típusát is argumentumként továbbítja ennek a metódusnak. Ebben a példában csak a belső hivatkozásokat támogatja a hitelkártya biztonsági jogkivonata. Az SecurityToken osztály funkcióval rendelkezik a belső hivatkozások létrehozásához, ezért a megvalósításhoz nincs szükség további kódra.
Implementálja a metódust InitializeSecurityTokenRequirement(SecurityTokenRequirement) . Ezt a metódust a WCF hívja meg a biztonsági jogkivonat-paraméterek osztálypéldányának osztálypéldányává való konvertálásához SecurityTokenRequirement . Az eredményt a biztonsági jogkivonat-szolgáltatók használják a megfelelő biztonsági jogkivonat-példány létrehozásához.
public class CreditCardTokenParameters : SecurityTokenParameters { public CreditCardTokenParameters() { } protected CreditCardTokenParameters(CreditCardTokenParameters other) : base(other) { } protected override SecurityTokenParameters CloneCore() { return new CreditCardTokenParameters(this); } protected override void InitializeSecurityTokenRequirement(SecurityTokenRequirement requirement) { requirement.TokenType = Constants.CreditCardTokenType; return; } // A credit card token has no cryptography, no windows identity, and supports only client authentication. protected override bool HasAsymmetricKey { get { return false; } } protected override bool SupportsClientAuthentication { get { return true; } } protected override bool SupportsClientWindowsIdentity { get { return false; } } protected override bool SupportsServerAuthentication { get { return false; } } protected override SecurityKeyIdentifierClause CreateKeyIdentifierClause(SecurityToken token, SecurityTokenReferenceStyle referenceStyle) { if (referenceStyle == SecurityTokenReferenceStyle.Internal) { return token.CreateKeyIdentifierClause<LocalIdKeyIdentifierClause>(); } else { throw new NotSupportedException("External references are not supported for credit card tokens"); } } }
Public Class CreditCardTokenParameters Inherits SecurityTokenParameters Public Sub New() End Sub Protected Sub New(ByVal other As CreditCardTokenParameters) MyBase.New(other) End Sub Protected Overrides Function CloneCore() As SecurityTokenParameters Return New CreditCardTokenParameters(Me) End Function Protected Overrides Sub InitializeSecurityTokenRequirement(ByVal requirement As SecurityTokenRequirement) requirement.TokenType = Constants.CreditCardTokenType Return End Sub ' A credit card token has no cryptography, no windows identity, and supports only client authentication. Protected Overrides ReadOnly Property HasAsymmetricKey() As Boolean Get Return False End Get End Property Protected Overrides ReadOnly Property SupportsClientAuthentication() As Boolean Get Return True End Get End Property Protected Overrides ReadOnly Property SupportsClientWindowsIdentity() As Boolean Get Return False End Get End Property Protected Overrides ReadOnly Property SupportsServerAuthentication() As Boolean Get Return False End Get End Property Protected Overrides Function CreateKeyIdentifierClause(ByVal token As SecurityToken, _ ByVal referenceStyle As SecurityTokenReferenceStyle) As SecurityKeyIdentifierClause If referenceStyle = SecurityTokenReferenceStyle.Internal Then Return token.CreateKeyIdentifierClause(Of LocalIdKeyIdentifierClause)() Else Throw New NotSupportedException("External references are not supported for credit card tokens") End If End Function End Class
A biztonsági jogkivonatok SOAP-üzenetekben kerülnek továbbításra, amihez fordítási mechanizmusra van szükség a memóriában lévő biztonsági jogkivonat-ábrázolás és a vezetéken történő ábrázolás között. A WCF biztonsági jogkivonat szerializálóval végzi el ezt a feladatot. Minden egyéni jogkivonathoz egyéni biztonsági jogkivonat szerializálót kell csatolni, amely szerializálhatja és deszerializálhatja az egyéni biztonsági jogkivonatot a SOAP-üzenetből.
Feljegyzés
A származtatott kulcsok alapértelmezés szerint engedélyezve vannak. Ha létrehoz egy egyéni biztonsági jogkivonatot, és elsődleges jogkivonatként használja, a WCF egy kulcsot nyer belőle. Ennek során meghívja az egyéni biztonsági jogkivonat szerializálót, hogy írja meg az SecurityKeyIdentifierClause egyéni biztonsági jogkivonatot, miközben szerializálja a DerivedKeyToken
vezetéket. A fogadó végén, amikor deszerializálja a jogkivonatot a vezetékről, a DerivedKeyToken
szerializáló egy SecurityTokenReference
elemet vár, mint a legfelső szintű gyermek önmagában. Ha az egyéni biztonsági jogkivonat szerializálója nem adott hozzá SecurityTokenReference
elemet a záradéktípus szerializálása során, kivételt eredményez.
Egyéni biztonsági jogkivonat szerializáló létrehozása
Definiáljon egy új osztályt, amely az WSSecurityTokenSerializer osztályból származik.
Bírálja felül a CanReadTokenCore(XmlReader) metódust, amely az XML-adatfolyam olvasására XmlReader támaszkodik. A metódus akkor ad vissza,
true
ha a szerializáló implementáció képes deszerializálni a biztonsági jogkivonatot az aktuális elem alapján. Ebben a példában ez a módszer ellenőrzi, hogy az XML-olvasó aktuális XML-eleme rendelkezik-e a megfelelő elemnévvel és névtérrel. Ha nem, meghívja ennek a metódusnak az alaposztály-implementációját az XML-elem kezeléséhez.Bírálja felül a metódust ReadTokenCore(XmlReader, SecurityTokenResolver) . Ez a metódus beolvassa a biztonsági jogkivonat XML-tartalmát, és összeállítja a megfelelő memóriabeli reprezentációt. Ha nem ismeri fel azt az XML-elemet, amelyen az átadott XML-olvasó áll, meghívja az alaposztály implementációt a rendszer által biztosított jogkivonattípusok feldolgozásához.
Bírálja felül a metódust CanWriteTokenCore(SecurityToken) . Ez a metódus akkor ad vissza,
true
ha a memóriában lévő jogkivonat-ábrázolás (argumentumként átadva) xml-reprezentációvá alakítható. Ha nem konvertálható, meghívja az alaposztály implementálását.Bírálja felül a metódust WriteTokenCore(XmlWriter, SecurityToken) . Ez a módszer xml-reprezentációvá alakítja a memórián belüli biztonsági jogkivonat-reprezentációt. Ha a metódus nem konvertálható, meghívja az alaposztály implementálását.
public class CreditCardSecurityTokenSerializer : WSSecurityTokenSerializer { public CreditCardSecurityTokenSerializer(SecurityTokenVersion version) : base() { } protected override bool CanReadTokenCore(XmlReader reader) { XmlDictionaryReader localReader = XmlDictionaryReader.CreateDictionaryReader(reader); if (reader == null) { throw new ArgumentNullException("reader"); } if (reader.IsStartElement(Constants.CreditCardTokenName, Constants.CreditCardTokenNamespace)) { return true; } return base.CanReadTokenCore(reader); } protected override SecurityToken ReadTokenCore(XmlReader reader, SecurityTokenResolver tokenResolver) { if (reader == null) { throw new ArgumentNullException("reader"); } if (reader.IsStartElement(Constants.CreditCardTokenName, Constants.CreditCardTokenNamespace)) { string id = reader.GetAttribute(Constants.Id, Constants.WsUtilityNamespace); reader.ReadStartElement(); // Read the credit card number. string creditCardNumber = reader.ReadElementString(Constants.CreditCardNumberElementName, Constants.CreditCardTokenNamespace); // Read the expiration date. string expirationTimeString = reader.ReadElementString(Constants.CreditCardExpirationElementName, Constants.CreditCardTokenNamespace); DateTime expirationTime = XmlConvert.ToDateTime(expirationTimeString, XmlDateTimeSerializationMode.Utc); // Read the issuer of the credit card. string creditCardIssuer = reader.ReadElementString(Constants.CreditCardIssuerElementName, Constants.CreditCardTokenNamespace); reader.ReadEndElement(); CreditCardInfo cardInfo = new CreditCardInfo(creditCardNumber, creditCardIssuer, expirationTime); return new CreditCardToken(cardInfo, id); } else { return WSSecurityTokenSerializer.DefaultInstance.ReadToken(reader, tokenResolver); } } protected override bool CanWriteTokenCore(SecurityToken token) { if (token is CreditCardToken) { return true; } else { return base.CanWriteTokenCore(token); } } protected override void WriteTokenCore(XmlWriter writer, SecurityToken token) { if (writer == null) { throw new ArgumentNullException("writer"); } if (token == null) { throw new ArgumentNullException("token"); } CreditCardToken c = token as CreditCardToken; if (c != null) { writer.WriteStartElement(Constants.CreditCardTokenPrefix, Constants.CreditCardTokenName, Constants.CreditCardTokenNamespace); writer.WriteAttributeString(Constants.WsUtilityPrefix, Constants.Id, Constants.WsUtilityNamespace, token.Id); writer.WriteElementString(Constants.CreditCardNumberElementName, Constants.CreditCardTokenNamespace, c.CardInfo.CardNumber); writer.WriteElementString(Constants.CreditCardExpirationElementName, Constants.CreditCardTokenNamespace, XmlConvert.ToString(c.CardInfo.ExpirationDate, XmlDateTimeSerializationMode.Utc)); writer.WriteElementString(Constants.CreditCardIssuerElementName, Constants.CreditCardTokenNamespace, c.CardInfo.CardIssuer); writer.WriteEndElement(); writer.Flush(); } else { base.WriteTokenCore(writer, token); } } }
Public Class CreditCardSecurityTokenSerializer Inherits WSSecurityTokenSerializer Public Sub New(ByVal version As SecurityTokenVersion) MyBase.New() End Sub Protected Overrides Function CanReadTokenCore(ByVal reader As XmlReader) As Boolean Dim localReader = XmlDictionaryReader.CreateDictionaryReader(reader) If reader Is Nothing Then Throw New ArgumentNullException("reader") End If If reader.IsStartElement(Constants.CreditCardTokenName, _ Constants.CreditCardTokenNamespace) Then Return True End If Return MyBase.CanReadTokenCore(reader) End Function Protected Overrides Function ReadTokenCore(ByVal reader As XmlReader, _ ByVal tokenResolver As SecurityTokenResolver) As SecurityToken If reader Is Nothing Then Throw New ArgumentNullException("reader") End If If reader.IsStartElement(Constants.CreditCardTokenName, _ Constants.CreditCardTokenNamespace) Then Dim id = reader.GetAttribute(Constants.Id, _ Constants.WsUtilityNamespace) reader.ReadStartElement() ' Read the credit card number. Dim creditCardNumber = reader.ReadElementString(Constants.CreditCardNumberElementName, _ Constants.CreditCardTokenNamespace) ' Read the expiration date. Dim expirationTimeString = reader.ReadElementString(Constants.CreditCardExpirationElementName, _ Constants.CreditCardTokenNamespace) Dim expirationTime As DateTime = XmlConvert.ToDateTime(expirationTimeString, _ XmlDateTimeSerializationMode.Utc) ' Read the issuer of the credit card. Dim creditCardIssuer = reader.ReadElementString(Constants.CreditCardIssuerElementName, _ Constants.CreditCardTokenNamespace) reader.ReadEndElement() Dim cardInfo As New CreditCardInfo(creditCardNumber, _ creditCardIssuer, _ expirationTime) Return New CreditCardToken(cardInfo, id) Else Return WSSecurityTokenSerializer.DefaultInstance.ReadToken(reader, _ tokenResolver) End If End Function Protected Overrides Function CanWriteTokenCore(ByVal token As SecurityToken) As Boolean If TypeOf token Is CreditCardToken Then Return True Else Return MyBase.CanWriteTokenCore(token) End If End Function Protected Overrides Sub WriteTokenCore(ByVal writer As XmlWriter, _ ByVal token As SecurityToken) If writer Is Nothing Then Throw New ArgumentNullException("writer") End If If token Is Nothing Then Throw New ArgumentNullException("token") End If Dim c = TryCast(token, CreditCardToken) If c IsNot Nothing Then With writer .WriteStartElement(Constants.CreditCardTokenPrefix, _ Constants.CreditCardTokenName, _ Constants.CreditCardTokenNamespace) .WriteAttributeString(Constants.WsUtilityPrefix, _ Constants.Id, _ Constants.WsUtilityNamespace, _ token.Id) .WriteElementString(Constants.CreditCardNumberElementName, _ Constants.CreditCardTokenNamespace, _ c.CardInfo.CardNumber) .WriteElementString(Constants.CreditCardExpirationElementName, _ Constants.CreditCardTokenNamespace, _ XmlConvert.ToString(c.CardInfo.ExpirationDate, _ XmlDateTimeSerializationMode.Utc)) .WriteElementString(Constants.CreditCardIssuerElementName, _ Constants.CreditCardTokenNamespace, _ c.CardInfo.CardIssuer) .WriteEndElement() .Flush() End With Else MyBase.WriteTokenCore(writer, token) End If End Sub End Class
Az előző négy eljárás elvégzése után integrálja az egyéni biztonsági jogkivonatot a biztonsági jogkivonat-szolgáltatóval, a hitelesítővel, a kezelővel, valamint az ügyfél- és szolgáltatás-hitelesítő adatokkal.
Az egyéni biztonsági jogkivonat integrálása biztonsági jogkivonat-szolgáltatóval
A biztonsági jogkivonat-szolgáltató létrehozza, módosítja (ha szükséges), és visszaadja a jogkivonat egy példányát. Ha egyéni szolgáltatót szeretne létrehozni az egyéni biztonsági jogkivonathoz, hozzon létre egy, az SecurityTokenProvider osztálytól öröklő osztályt. Az alábbi példa felülírja a metódust a GetTokenCore példány visszaadásához
CreditCardToken
. Az egyéni biztonsági jogkivonat-szolgáltatókkal kapcsolatos további információkért lásd : Egyéni biztonsági jogkivonat-szolgáltató létrehozása.class CreditCardTokenProvider : SecurityTokenProvider { CreditCardInfo creditCardInfo; public CreditCardTokenProvider(CreditCardInfo creditCardInfo) : base() { if (creditCardInfo == null) { throw new ArgumentNullException("creditCardInfo"); } this.creditCardInfo = creditCardInfo; } protected override SecurityToken GetTokenCore(TimeSpan timeout) { SecurityToken result = new CreditCardToken(this.creditCardInfo); return result; } }
Friend Class CreditCardTokenProvider Inherits SecurityTokenProvider Private creditCardInfo As CreditCardInfo Public Sub New(ByVal creditCardInfo As CreditCardInfo) MyBase.New() If creditCardInfo Is Nothing Then Throw New ArgumentNullException("creditCardInfo") End If Me.creditCardInfo = creditCardInfo End Sub Protected Overrides Function GetTokenCore(ByVal timeout As TimeSpan) As SecurityToken Return TryCast(New CreditCardToken(Me.creditCardInfo), SecurityToken) End Function End Class
Az egyéni biztonsági jogkivonat integrálása biztonsági jogkivonat-hitelesítővel
A biztonsági jogkivonat hitelesítője ellenőrzi a biztonsági jogkivonat tartalmát az üzenetből való kinyerésekor. Ha egyéni hitelesítőt szeretne létrehozni az egyéni biztonsági jogkivonathoz, hozzon létre egy, az SecurityTokenAuthenticator osztálytól öröklő osztályt. Az alábbi példa felülírja a metódust ValidateTokenCore . Az egyéni biztonsági jogkivonat-hitelesítőkkel kapcsolatos további információkért lásd : Egyéni biztonsági jogkivonat-hitelesítő létrehozása.
class CreditCardTokenAuthenticator : SecurityTokenAuthenticator { string creditCardsFile; public CreditCardTokenAuthenticator(string creditCardsFile) { this.creditCardsFile = creditCardsFile; } protected override bool CanValidateTokenCore(SecurityToken token) { return (token is CreditCardToken); } protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateTokenCore(SecurityToken token) { CreditCardToken creditCardToken = token as CreditCardToken; if (creditCardToken.CardInfo.ExpirationDate < DateTime.UtcNow) { throw new SecurityTokenValidationException("The credit card has expired"); } if (!IsCardNumberAndExpirationValid(creditCardToken.CardInfo)) { throw new SecurityTokenValidationException("Unknown or invalid credit card"); } // The credit card token has only 1 claim: the card number. The issuer for the claim is the // credit card issuer. DefaultClaimSet cardIssuerClaimSet = new DefaultClaimSet(new Claim(ClaimTypes.Name, creditCardToken.CardInfo.CardIssuer, Rights.PossessProperty)); DefaultClaimSet cardClaimSet = new DefaultClaimSet(cardIssuerClaimSet, new Claim(Constants.CreditCardNumberClaim, creditCardToken.CardInfo.CardNumber, Rights.PossessProperty)); List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>(1); policies.Add(new CreditCardTokenAuthorizationPolicy(cardClaimSet)); return policies.AsReadOnly(); } // This helper method checks whether a given credit card entry is present in the user database. private bool IsCardNumberAndExpirationValid(CreditCardInfo cardInfo) { try { using (StreamReader myStreamReader = new StreamReader(this.creditCardsFile)) { string line = ""; while ((line = myStreamReader.ReadLine()) != null) { string[] splitEntry = line.Split('#'); if (splitEntry[0] == cardInfo.CardNumber) { string expirationDateString = splitEntry[1].Trim(); DateTime expirationDateOnFile = DateTime.Parse(expirationDateString, System.Globalization.DateTimeFormatInfo.InvariantInfo, System.Globalization.DateTimeStyles.AdjustToUniversal); if (cardInfo.ExpirationDate == expirationDateOnFile) { string issuer = splitEntry[2]; return issuer.Equals(cardInfo.CardIssuer, StringComparison.InvariantCultureIgnoreCase); } else { return false; } } } return false; } } catch (Exception e) { throw new Exception("BookStoreService: Error while retrieving credit card information from User DB " + e.ToString()); } } }
Friend Class CreditCardTokenAuthenticator Inherits SecurityTokenAuthenticator Private creditCardsFile As String Public Sub New(ByVal creditCardsFile As String) Me.creditCardsFile = creditCardsFile End Sub Protected Overrides Function CanValidateTokenCore(ByVal token As SecurityToken) As Boolean Return (TypeOf token Is CreditCardToken) End Function Protected Overrides Function ValidateTokenCore(ByVal token As SecurityToken) As ReadOnlyCollection(Of IAuthorizationPolicy) Dim creditCardToken = TryCast(token, CreditCardToken) If creditCardToken.CardInfo.ExpirationDate < DateTime.UtcNow Then Throw New SecurityTokenValidationException("The credit card has expired") End If If Not IsCardNumberAndExpirationValid(creditCardToken.CardInfo) Then Throw New SecurityTokenValidationException("Unknown or invalid credit card") End If ' The credit card token has only 1 claim: the card number. The issuer for the claim is the ' credit card issuer. Dim cardIssuerClaimSet As New DefaultClaimSet(New Claim(ClaimTypes.Name, _ creditCardToken.CardInfo.CardIssuer, _ Rights.PossessProperty)) Dim cardClaimSet As New DefaultClaimSet(cardIssuerClaimSet, _ New Claim(Constants.CreditCardNumberClaim, _ creditCardToken.CardInfo.CardNumber, _ Rights.PossessProperty)) Dim policies As New List(Of IAuthorizationPolicy)(1) policies.Add(New CreditCardTokenAuthorizationPolicy(cardClaimSet)) Return policies.AsReadOnly() End Function ' This helper method checks whether a given credit card entry is present in the user database. Private Function IsCardNumberAndExpirationValid(ByVal cardInfo As CreditCardInfo) As Boolean Try Using myStreamReader As New StreamReader(Me.creditCardsFile) Dim line = String.Empty line = myStreamReader.ReadLine() Do While line IsNot Nothing Dim splitEntry() = line.Split("#"c) If splitEntry(0) = cardInfo.CardNumber Then Dim expirationDateString = splitEntry(1).Trim() Dim expirationDateOnFile As DateTime = DateTime.Parse(expirationDateString, _ System.Globalization.DateTimeFormatInfo.InvariantInfo, _ System.Globalization.DateTimeStyles.AdjustToUniversal) If cardInfo.ExpirationDate = expirationDateOnFile Then Dim issuer = splitEntry(2) Return issuer.Equals(cardInfo.CardIssuer, _ StringComparison.InvariantCultureIgnoreCase) Else Return False End If End If line = myStreamReader.ReadLine() Loop Return False End Using Catch e As Exception Throw New Exception("BookStoreService: Error while retrieving credit card information from User DB " & e.ToString()) End Try End Function End Class
public class CreditCardTokenAuthorizationPolicy : IAuthorizationPolicy { string id; ClaimSet issuer; IEnumerable<ClaimSet> issuedClaimSets; public CreditCardTokenAuthorizationPolicy(ClaimSet issuedClaims) { if (issuedClaims == null) throw new ArgumentNullException("issuedClaims"); this.issuer = issuedClaims.Issuer; this.issuedClaimSets = new ClaimSet[] { issuedClaims }; this.id = Guid.NewGuid().ToString(); } public ClaimSet Issuer { get { return this.issuer; } } public string Id { get { return this.id; } } public bool Evaluate(EvaluationContext context, ref object state) { foreach (ClaimSet issuance in this.issuedClaimSets) { context.AddClaimSet(this, issuance); } return true; } }
Public Class CreditCardTokenAuthorizationPolicy Implements IAuthorizationPolicy Private _id As String Private _issuer As ClaimSet Private _issuedClaimSets As IEnumerable(Of ClaimSet) Public Sub New(ByVal issuedClaims As ClaimSet) If issuedClaims Is Nothing Then Throw New ArgumentNullException("issuedClaims") End If Me._issuer = issuedClaims.Issuer Me._issuedClaimSets = New ClaimSet() {issuedClaims} Me._id = Guid.NewGuid().ToString() End Sub Public ReadOnly Property Issuer() As ClaimSet Implements IAuthorizationPolicy.Issuer Get Return Me._issuer End Get End Property Public ReadOnly Property Id() As String Implements System.IdentityModel.Policy.IAuthorizationComponent.Id Get Return Me._id End Get End Property Public Function Evaluate(ByVal context As EvaluationContext, _ ByRef state As Object) As Boolean Implements IAuthorizationPolicy.Evaluate For Each issuance In Me._issuedClaimSets context.AddClaimSet(Me, issuance) Next issuance Return True End Function End Class
Az egyéni biztonsági jogkivonat integrálása biztonsági jogkivonat-kezelővel
A biztonsági jogkivonat-kezelő létrehozza a megfelelő jogkivonat-szolgáltatót, biztonsági hitelesítőt és jogkivonat-szerializáló példányokat. Egyéni jogkivonat-kezelő létrehozásához hozzon létre egy, az ClientCredentialsSecurityTokenManager osztálytól öröklő osztályt. Az osztály elsődleges metódusai az a SecurityTokenRequirement használatával hozzák létre a megfelelő szolgáltatói és ügyfél- vagy szolgáltatás-hitelesítő adatokat. További információ az egyéni biztonsági jogkivonat-kezelőkről : Útmutató: Egyéni ügyfél- és szolgáltatás hitelesítő adatok létrehozása.
public class CreditCardClientCredentialsSecurityTokenManager : ClientCredentialsSecurityTokenManager { CreditCardClientCredentials creditCardClientCredentials; public CreditCardClientCredentialsSecurityTokenManager(CreditCardClientCredentials creditCardClientCredentials) : base(creditCardClientCredentials) { this.creditCardClientCredentials = creditCardClientCredentials; } public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement) { if (tokenRequirement.TokenType == Constants.CreditCardTokenType) { // Handle this token for Custom. return new CreditCardTokenProvider(this.creditCardClientCredentials.CreditCardInfo); } else if (tokenRequirement is InitiatorServiceModelSecurityTokenRequirement) { // Return server certificate. if (tokenRequirement.TokenType == SecurityTokenTypes.X509Certificate) { return new X509SecurityTokenProvider(creditCardClientCredentials.ServiceCertificate.DefaultCertificate); } } return base.CreateSecurityTokenProvider(tokenRequirement); } public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version) { return new CreditCardSecurityTokenSerializer(version); } }
Public Class CreditCardClientCredentialsSecurityTokenManager Inherits ClientCredentialsSecurityTokenManager Private creditCardClientCredentials As CreditCardClientCredentials Public Sub New(ByVal creditCardClientCredentials As CreditCardClientCredentials) MyBase.New(creditCardClientCredentials) Me.creditCardClientCredentials = creditCardClientCredentials End Sub Public Overrides Function CreateSecurityTokenProvider(ByVal tokenRequirement As SecurityTokenRequirement) As SecurityTokenProvider If tokenRequirement.TokenType = Constants.CreditCardTokenType Then ' Handle this token for Custom. Return New CreditCardTokenProvider(Me.creditCardClientCredentials.CreditCardInfo) ElseIf TypeOf tokenRequirement Is InitiatorServiceModelSecurityTokenRequirement Then ' Return server certificate. If tokenRequirement.TokenType = SecurityTokenTypes.X509Certificate Then Return New X509SecurityTokenProvider(creditCardClientCredentials.ServiceCertificate.DefaultCertificate) End If End If Return MyBase.CreateSecurityTokenProvider(tokenRequirement) End Function Public Overloads Overrides Function CreateSecurityTokenSerializer(ByVal version As SecurityTokenVersion) As SecurityTokenSerializer Return New CreditCardSecurityTokenSerializer(version) End Function End Class
public class CreditCardServiceCredentialsSecurityTokenManager : ServiceCredentialsSecurityTokenManager { CreditCardServiceCredentials creditCardServiceCredentials; public CreditCardServiceCredentialsSecurityTokenManager(CreditCardServiceCredentials creditCardServiceCredentials) : base(creditCardServiceCredentials) { this.creditCardServiceCredentials = creditCardServiceCredentials; } public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver) { if (tokenRequirement.TokenType == Constants.CreditCardTokenType) { outOfBandTokenResolver = null; return new CreditCardTokenAuthenticator(creditCardServiceCredentials.CreditCardDataFile); } return base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver); } public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version) { return new CreditCardSecurityTokenSerializer(version); } }
Public Class CreditCardServiceCredentialsSecurityTokenManager Inherits ServiceCredentialsSecurityTokenManager Private creditCardServiceCredentials As CreditCardServiceCredentials Public Sub New(ByVal creditCardServiceCredentials As CreditCardServiceCredentials) MyBase.New(creditCardServiceCredentials) Me.creditCardServiceCredentials = creditCardServiceCredentials End Sub Public Overrides Function CreateSecurityTokenAuthenticator(ByVal tokenRequirement As SecurityTokenRequirement, _ <System.Runtime.InteropServices.Out()> ByRef outOfBandTokenResolver As SecurityTokenResolver) As SecurityTokenAuthenticator If tokenRequirement.TokenType = Constants.CreditCardTokenType Then outOfBandTokenResolver = Nothing Return New CreditCardTokenAuthenticator(creditCardServiceCredentials.CreditCardDataFile) End If Return MyBase.CreateSecurityTokenAuthenticator(tokenRequirement, outOfBandTokenResolver) End Function Public Overrides Function CreateSecurityTokenSerializer(ByVal version As SecurityTokenVersion) As SecurityTokenSerializer Return New CreditCardSecurityTokenSerializer(version) End Function End Class
Az egyéni biztonsági jogkivonat integrálása egyéni ügyfél- és szolgáltatás-hitelesítő adatokkal
Az egyéni ügyfél- és szolgáltatáshitelesítési hitelesítő adatokat hozzá kell adni ahhoz, hogy az alkalmazás API-t biztosítson, amely lehetővé teszi a korábban létrehozott egyéni biztonsági jogkivonat-infrastruktúra által az egyéni biztonsági jogkivonat tartalmának megadásához és hitelesítéséhez használt egyéni jogkivonat-információk megadását. Az alábbi minták bemutatják, hogyan lehet ezt megtenni. Az egyéni ügyfél- és szolgáltatás-hitelesítő adatokkal kapcsolatos további információkért lásd : Útmutató: Egyéni ügyfél- és szolgáltatás hitelesítő adatok létrehozása.
public class CreditCardClientCredentials : ClientCredentials { CreditCardInfo creditCardInfo; public CreditCardClientCredentials(CreditCardInfo creditCardInfo) : base() { if (creditCardInfo == null) { throw new ArgumentNullException("creditCardInfo"); } this.creditCardInfo = creditCardInfo; } public CreditCardInfo CreditCardInfo { get { return this.creditCardInfo; } } protected override ClientCredentials CloneCore() { return new CreditCardClientCredentials(this.creditCardInfo); } public override SecurityTokenManager CreateSecurityTokenManager() { return new CreditCardClientCredentialsSecurityTokenManager(this); } }
Public Class CreditCardClientCredentials Inherits ClientCredentials Private _creditCardInfo As CreditCardInfo Public Sub New(ByVal creditCardInfo As CreditCardInfo) MyBase.New() If creditCardInfo Is Nothing Then Throw New ArgumentNullException("creditCardInfo") End If Me._creditCardInfo = creditCardInfo End Sub Public ReadOnly Property CreditCardInfo() As CreditCardInfo Get Return Me._creditCardInfo End Get End Property Protected Overrides Function CloneCore() As ClientCredentials Return New CreditCardClientCredentials(Me._creditCardInfo) End Function Public Overrides Function CreateSecurityTokenManager() As SecurityTokenManager Return New CreditCardClientCredentialsSecurityTokenManager(Me) End Function End Class
public class CreditCardServiceCredentials : ServiceCredentials { string creditCardFile; public CreditCardServiceCredentials(string creditCardFile) : base() { if (creditCardFile == null) { throw new ArgumentNullException("creditCardFile"); } this.creditCardFile = creditCardFile; } public string CreditCardDataFile { get { return this.creditCardFile; } } protected override ServiceCredentials CloneCore() { return new CreditCardServiceCredentials(this.creditCardFile); } public override SecurityTokenManager CreateSecurityTokenManager() { return new CreditCardServiceCredentialsSecurityTokenManager(this); } }
Public Class CreditCardServiceCredentials Inherits ServiceCredentials Private creditCardFile As String Public Sub New(ByVal creditCardFile As String) MyBase.New() If creditCardFile Is Nothing Then Throw New ArgumentNullException("creditCardFile") End If Me.creditCardFile = creditCardFile End Sub Public ReadOnly Property CreditCardDataFile() As String Get Return Me.creditCardFile End Get End Property Protected Overrides Function CloneCore() As ServiceCredentials Return New CreditCardServiceCredentials(Me.creditCardFile) End Function Public Overrides Function CreateSecurityTokenManager() As SecurityTokenManager Return New CreditCardServiceCredentialsSecurityTokenManager(Me) End Function End Class
A korábban létrehozott egyéni biztonsági jogkivonat paramétereinek osztálya azt jelzi a WCF biztonsági keretrendszernek, hogy egy egyéni biztonsági jogkivonatot kell használni a szolgáltatással való kommunikáció során. Az alábbi eljárás bemutatja, hogyan lehet ezt megtenni.
Az egyéni biztonsági jogkivonat integrálása a kötéssel
Az egyéni biztonsági jogkivonat paraméterosztályát meg kell adni az osztályon közzétett tokenparaméter-gyűjtemények egyikében SecurityBindingElement . Az alábbi példa a visszaadott gyűjteményt
SignedEncrypted
használja. A kód hozzáadja az egyéni hitelkártya-jogkivonatot az ügyféltől a szolgáltatásnak küldött minden üzenethez, amelynek tartalma automatikusan alá van írva és titkosítva.public static class BindingHelper { public static Binding CreateCreditCardBinding() { HttpTransportBindingElement httpTransport = new HttpTransportBindingElement(); // The message security binding element is configured to require a credit card // token that is encrypted with the service's certificate. SymmetricSecurityBindingElement messageSecurity = new SymmetricSecurityBindingElement(); messageSecurity.EndpointSupportingTokenParameters.SignedEncrypted.Add(new CreditCardTokenParameters()); X509SecurityTokenParameters x509ProtectionParameters = new X509SecurityTokenParameters(); x509ProtectionParameters.InclusionMode = SecurityTokenInclusionMode.Never; messageSecurity.ProtectionTokenParameters = x509ProtectionParameters; return new CustomBinding(messageSecurity, httpTransport); } }
Public NotInheritable Class BindingHelper Private Sub New() End Sub Public Shared Function CreateCreditCardBinding() As Binding Dim httpTransport As New HttpTransportBindingElement() ' The message security binding element is configured to require a credit card ' token that is encrypted with the service's certificate. Dim messageSecurity As New SymmetricSecurityBindingElement() messageSecurity.EndpointSupportingTokenParameters.SignedEncrypted.Add(New CreditCardTokenParameters()) Dim x509ProtectionParameters As New X509SecurityTokenParameters() x509ProtectionParameters.InclusionMode = SecurityTokenInclusionMode.Never messageSecurity.ProtectionTokenParameters = x509ProtectionParameters Return New CustomBinding(messageSecurity, httpTransport) End Function End Class
Ez a témakör az egyéni jogkivonatok implementálásához és használatához szükséges különböző kódrészleteket mutatja be. Ha teljes példát szeretne látni arra, hogy ezek a kódrészletek hogyan illeszkednek egymáshoz, tekintse meg az Egyéni jogkivonatot.
Lásd még
- SecurityToken
- SecurityTokenParameters
- WSSecurityTokenSerializer
- SecurityTokenProvider
- SecurityTokenAuthenticator
- IAuthorizationPolicy
- SecurityTokenRequirement
- SecurityTokenManager
- ClientCredentials
- ServiceCredentials
- SecurityBindingElement
- Útmutató: Egyéni ügyfél- és szolgáltatás hitelesítő adatok létrehozása
- Útmutató: Egyéni biztonsági jogkivonat-hitelesítő létrehozása
- Útmutató: Egyéni biztonsági jogkivonat-szolgáltató létrehozása