Egyéni jogkivonat
Ez a minta bemutatja, hogyan vehet fel egyéni jogkivonat-implementációt a Windows Communication Foundation (WCF) alkalmazásba. A példa az CreditCardToken
ügyfél hitelkártyáival kapcsolatos információk biztonságos átadására szolgál a szolgáltatásnak. A jogkivonat a WS-Security üzenetfejlécben lesz átadva, és a szimmetrikus biztonsági kötési elem, valamint az üzenettörzs és más üzenetfejlécek használatával van aláírva és titkosítva. Ez akkor hasznos, ha a beépített jogkivonatok nem elegendőek. Ez a minta bemutatja, hogyan biztosíthat egyéni biztonsági jogkivonatot egy szolgáltatásnak a beépített jogkivonatok használata helyett. A szolgáltatás megvalósít egy szerződést, amely egy kérés-válasz kommunikációs mintát határoz meg.
Feljegyzés
A minta telepítési eljárása és összeállítási utasításai a témakör végén találhatók.
Összegzésként ez a minta a következőket mutatja be:
Hogyan adhat át egy ügyfél egyéni biztonsági jogkivonatot egy szolgáltatásnak.
Hogyan használhatja fel és érvényesítheti a szolgáltatás az egyéni biztonsági jogkivonatokat.
Hogyan szerezheti be a WCF szolgáltatáskód a kapott biztonsági jogkivonatokkal kapcsolatos információkat, beleértve az egyéni biztonsági jogkivonatot is.
A kiszolgáló X.509-tanúsítványának használata az üzenettitkosításhoz és aláíráshoz használt szimmetrikus kulcs védelmére.
Ügyfél-hitelesítés egyéni biztonsági jogkivonat használatával
A szolgáltatás egyetlen végpontot tesz elérhetővé, amely programozott módon jön létre a használatával BindingHelper
és EchoServiceHost
az osztályokkal. A végpont egy címből, egy kötésből és egy szerződésből áll. A kötés egyéni kötéssel SymmetricSecurityBindingElement
van konfigurálva az and HttpTransportBindingElement
. Ez a minta egy szolgáltatás X.509-tanúsítványának használatára állítja be a SymmetricSecurityBindingElement
szimmetrikus kulcs átvitel közbeni védelmére, valamint egy egyéni CreditCardToken
WS-Security-üzenet fejlécében aláírt és titkosított biztonsági jogkivonatként való átadására. A viselkedés meghatározza az ügyfél-hitelesítéshez használandó szolgáltatás hitelesítő adatait, valamint az X.509 szolgáltatás tanúsítványával kapcsolatos információkat.
public static class BindingHelper
{
public static Binding CreateCreditCardBinding()
{
var httpTransport = new HttpTransportBindingElement();
// The message security binding element will be configured to require a credit card.
// The token that is encrypted with the service's certificate.
var 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);
}
}
Ha hitelkártya-jogkivonatot szeretne használni az üzenetben, a minta egyéni szolgáltatás hitelesítő adataival biztosítja ezt a funkciót. A szolgáltatás hitelesítő adatai osztály az CreditCardServiceCredentials
osztályban található, és a metódusban hozzáadódik a szolgáltatás gazdagépének EchoServiceHost.InitializeRuntime
viselkedésgyűjteményeihez.
class EchoServiceHost : ServiceHost
{
string creditCardFile;
public EchoServiceHost(parameters Uri[] addresses)
: base(typeof(EchoService), addresses)
{
creditCardFile = ConfigurationManager.AppSettings["creditCardFile"];
if (string.IsNullOrEmpty(creditCardFile))
{
throw new ConfigurationErrorsException("creditCardFile not specified in service config");
}
creditCardFile = String.Format("{0}\\{1}", System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath, creditCardFile);
}
override protected void InitializeRuntime()
{
// Create a credit card service credentials and add it to the behaviors.
CreditCardServiceCredentials serviceCredentials = new CreditCardServiceCredentials(this.creditCardFile);
serviceCredentials.ServiceCertificate.SetCertificate("CN=localhost", StoreLocation.LocalMachine, StoreName.My);
this.Description.Behaviors.Remove((typeof(ServiceCredentials)));
this.Description.Behaviors.Add(serviceCredentials);
// Register a credit card binding for the endpoint.
Binding creditCardBinding = BindingHelper.CreateCreditCardBinding();
this.AddServiceEndpoint(typeof(IEchoService), creditCardBinding, string.Empty);
base.InitializeRuntime();
}
}
Az ügyfélvégpont a szolgáltatásvégponthoz hasonlóan van konfigurálva. Az ügyfél ugyanazt BindingHelper
az osztályt használja kötés létrehozásához. A beállítás többi része az Client
osztályban található. Az ügyfél beállítja a beállítási kódban található CreditCardToken
X.509 szolgáltatástanúsítvány adatait is úgy, hogy hozzáad egy példányt CreditCardClientCredentials
a megfelelő adatokkal az ügyfélvégpont viselkedési gyűjteményéhez. A minta X.509-tanúsítványt használ, amelynek tulajdonosi neve szolgáltatástanúsítványként van beállítva CN=localhost
.
Binding creditCardBinding = BindingHelper.CreateCreditCardBinding();
var serviceAddress = new EndpointAddress("http://localhost/servicemodelsamples/service.svc");
// Create a client with given client endpoint configuration.
channelFactory = new ChannelFactory<IEchoService>(creditCardBinding, serviceAddress);
// Configure the credit card credentials on the channel factory.
var credentials =
new CreditCardClientCredentials(
new CreditCardInfo(creditCardNumber, issuer, expirationTime));
// Configure the service certificate on the credentials.
credentials.ServiceCertificate.SetDefaultCertificate(
"CN=localhost", StoreLocation.LocalMachine, StoreName.My);
// Replace ClientCredentials with CreditCardClientCredentials.
channelFactory.Endpoint.Behaviors.Remove(typeof(ClientCredentials));
channelFactory.Endpoint.Behaviors.Add(credentials);
client = channelFactory.CreateChannel();
Console.WriteLine($"Echo service returned: {client.Echo()}");
((IChannel)client).Close();
channelFactory.Close();
Egyéni biztonsági jogkivonat implementálása
Ha egyéni biztonsági jogkivonatot szeretne engedélyezni a WCF-ben, hozzon létre egy objektumábrázolást az egyéni biztonsági jogkivonatról. A mintának ez a reprezentációja van az CreditCardToken
osztályban. Az objektumábrázolás feladata az összes releváns biztonsági jogkivonat-információ megtartása, valamint a biztonsági jogkivonatban található biztonsági kulcsok listája. Ebben az esetben a hitelkártya biztonsági jogkivonata nem tartalmaz biztonsági kulcsot.
A következő szakasz azt ismerteti, hogy mit kell tenni annak érdekében, hogy az egyéni jogkivonatok átvitele a vezetéken keresztül történik, és amelyeket egy WCF-végpont használjon fel.
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(nameof(cardInfo));
if (id == null)
throw new ArgumentNullException(nameof(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; } }
}
Az egyéni hitelkártya-jogkivonat lekérése az üzenetbe és az üzenetből
A WCF biztonsági jogkivonat-szerializálói felelősek a biztonsági jogkivonatok objektumreprezentációjának létrehozásáért az xml-ből az üzenetben, valamint a biztonsági jogkivonatok XML-formájának létrehozásáért. Más funkciókért is felelősek, például a biztonsági jogkivonatokra mutató kulcsazonosítók olvasásáért és írásáért, de ez a példa csak a biztonsági jogkivonattal kapcsolatos funkciókat használja. Az egyéni jogkivonatok engedélyezéséhez saját biztonsági jogkivonat-szerializálót kell implementálnia. Ez a minta erre a célra használja az CreditCardSecurityTokenSerializer
osztályt.
A szolgáltatásban az egyéni szerializáló beolvassa az egyéni jogkivonat XML-formáját, és létrehozza belőle az egyéni jogkivonat objektumábrázolását.
Az ügyfélen az osztály beírja CreditCardSecurityTokenSerializer
a biztonsági jogkivonat objektumábrázolásában található információkat az XML-íróba.
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(nameof(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(nameof(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();
var 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;
return base.CanWriteTokenCore(token);
}
protected override void WriteTokenCore(XmlWriter writer, SecurityToken token)
{
if (writer == null)
throw new ArgumentNullException(nameof(writer));
if (token == null)
throw new ArgumentNullException(nameof(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);
}
}
}
Jogkivonat-szolgáltatói és jogkivonat-hitelesítő osztályok létrehozása
Az ügyfél- és szolgáltatás hitelesítő adatai felelősek a biztonsági jogkivonat-kezelő példányának biztosításáért. A biztonsági jogkivonat-kezelő példány a jogkivonat-szolgáltatók, a jogkivonat-hitelesítők és a jogkivonat-szerializálók lekérésére szolgál.
A jogkivonat-szolgáltató az ügyfél- vagy szolgáltatás hitelesítő adatai alapján létrehozza a jogkivonat objektumábrázolását. A jogkivonat objektumábrázolása ezután a jogkivonat szerializálójának használatával lesz megírva az üzenetbe (az előző szakaszban tárgyalt).
A jogkivonat-hitelesítő ellenőrzi az üzenetbe érkező jogkivonatokat. A bejövő jogkivonat objektumábrázolását a jogkivonat szerializálója hozza létre. Ezt az objektumábrázolást ezután a rendszer érvényesítés céljából átadja a jogkivonat-hitelesítőnek. A jogkivonat sikeres érvényesítése után a jogkivonat-hitelesítő olyan objektumgyűjteményt IAuthorizationPolicy
ad vissza, amely a jogkivonatban található információkat képviseli. Ezeket az információkat az üzenetfeldolgozás során felhasználjuk az engedélyezési döntések végrehajtására és az alkalmazás jogcímeinek megadására. Ebben a példában a hitelkártya-jogkivonat hitelesítője erre a célra használja CreditCardTokenAuthorizationPolicy
.
A jogkivonat szerializálója a jogkivonat objektumábrázolásának lekérése a vezetékbe és a vezetékből. Erről az előző szakaszban olvashat.
Ebben a példában csak az ügyfélen használunk jogkivonat-szolgáltatót, a jogkivonat-hitelesítőt pedig csak a szolgáltatáson, mivel csak az ügyfél-szolgáltatás irányban szeretnénk továbbítani egy hitelkártya-jogkivonatot.
Az ügyfél funkciói a , CreditCardClientCredentialsSecurityTokenManager
és CreditCardTokenProvider
az CreditCardClientCredentials
osztályokban találhatók.
A szolgáltatásban a funkció a , CreditCardServiceCredentialsSecurityTokenManager
CreditCardTokenAuthenticator
és CreditCardTokenAuthorizationPolicy
az CreditCardServiceCredentials
osztályokban található.
public class CreditCardClientCredentials : ClientCredentials
{
CreditCardInfo creditCardInfo;
public CreditCardClientCredentials(CreditCardInfo creditCardInfo)
: base()
{
if (creditCardInfo == null)
throw new ArgumentNullException(nameof(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 CreditCardClientCredentialsSecurityTokenManager : ClientCredentialsSecurityTokenManager
{
CreditCardClientCredentials creditCardClientCredentials;
public CreditCardClientCredentialsSecurityTokenManager(CreditCardClientCredentials creditCardClientCredentials)
: base (creditCardClientCredentials)
{
this.creditCardClientCredentials = creditCardClientCredentials;
}
public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement)
{
// Handle this token for Custom.
if (tokenRequirement.TokenType == Constants.CreditCardTokenType)
return new CreditCardTokenProvider(this.creditCardClientCredentials.CreditCardInfo);
// Return server cert.
else if (tokenRequirement is InitiatorServiceModelSecurityTokenRequirement)
{
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);
}
}
class CreditCardTokenProvider : SecurityTokenProvider
{
CreditCardInfo creditCardInfo;
public CreditCardTokenProvider(CreditCardInfo creditCardInfo) : base()
{
if (creditCardInfo == null)
throw new ArgumentNullException(nameof(creditCardInfo));
this.creditCardInfo = creditCardInfo;
}
protected override SecurityToken GetTokenCore(TimeSpan timeout)
{
SecurityToken result = new CreditCardToken(this.creditCardInfo);
return result;
}
}
public class CreditCardServiceCredentials : ServiceCredentials
{
string creditCardFile;
public CreditCardServiceCredentials(string creditCardFile)
: base()
{
if (creditCardFile == null)
throw new ArgumentNullException(nameof(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 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);
}
}
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
var cardIssuerClaimSet = new DefaultClaimSet(new Claim(ClaimTypes.Name, creditCardToken.CardInfo.CardIssuer, Rights.PossessProperty));
var cardClaimSet = new DefaultClaimSet(cardIssuerClaimSet, new Claim(Constants.CreditCardNumberClaim, creditCardToken.CardInfo.CardNumber, Rights.PossessProperty));
var policies = new List<IAuthorizationPolicy>(1);
policies.Add(new CreditCardTokenAuthorizationPolicy(cardClaimSet));
return policies.AsReadOnly();
}
/// <summary>
/// Helper method to check if a given credit card entry is present in the User DB
/// </summary>
private bool IsCardNumberAndExpirationValid(CreditCardInfo cardInfo)
{
try
{
using (var 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());
}
}
}
public class CreditCardTokenAuthorizationPolicy : IAuthorizationPolicy
{
string id;
ClaimSet issuer;
IEnumerable<ClaimSet> issuedClaimSets;
public CreditCardTokenAuthorizationPolicy(ClaimSet issuedClaims)
{
if (issuedClaims == null)
throw new ArgumentNullException(nameof(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;
}
}
A hívók adatainak megjelenítése
A hívó adatainak megjelenítéséhez használja az ServiceSecurityContext.Current.AuthorizationContext.ClaimSets
alábbi mintakódot. Ez ServiceSecurityContext.Current.AuthorizationContext.ClaimSets
az aktuális hívóhoz társított engedélyezési jogcímeket tartalmazza. A jogcímeket az osztály adja meg a CreditCardToken
gyűjteményében AuthorizationPolicies
.
bool TryGetStringClaimValue(ClaimSet claimSet, string claimType, out string claimValue)
{
claimValue = null;
IEnumerable<Claim> matchingClaims = claimSet.FindClaims(claimType, Rights.PossessProperty);
if (matchingClaims == null)
return false;
IEnumerator<Claim> enumerator = matchingClaims.GetEnumerator();
enumerator.MoveNext();
claimValue = (enumerator.Current.Resource == null) ? null :
enumerator.Current.Resource.ToString();
return true;
}
string GetCallerCreditCardNumber()
{
foreach (ClaimSet claimSet in
ServiceSecurityContext.Current.AuthorizationContext.ClaimSets)
{
string creditCardNumber = null;
if (TryGetStringClaimValue(claimSet,
Constants.CreditCardNumberClaim, out creditCardNumber))
{
string issuer;
if (!TryGetStringClaimValue(claimSet.Issuer,
ClaimTypes.Name, out issuer))
{
issuer = "Unknown";
}
return $"Credit card '{creditCardNumber}' issued by '{issuer}'";
}
}
return "Credit card is not known";
}
A minta futtatásakor a műveleti kérelmek és a válaszok megjelennek az ügyfélkonzol ablakában. Nyomja le az ENTER billentyűt az ügyfélablakban az ügyfél leállításához.
Batch-fájl beállítása
A mintában szereplő Setup.bat kötegfájl lehetővé teszi a kiszolgáló megfelelő tanúsítványokkal való konfigurálását az IIS által üzemeltetett alkalmazás futtatásához, amely kiszolgálói tanúsítványalapú biztonságot igényel. Ezt a kötegfájlt úgy kell módosítani, hogy a számítógépeken is működjön, vagy nem üzemeltetett esetben működjön.
Az alábbiakban röviden áttekintheti a kötegfájlok különböző szakaszait, hogy azok a megfelelő konfigurációban való futtatásukhoz módosíthatók legyenek.
A kiszolgálótanúsítvány létrehozása:
A batch fájl alábbi sorai
Setup.bat
létrehozzák a használni kívánt kiszolgálói tanúsítványt. A%SERVER_NAME%
változó megadja a kiszolgáló nevét. Módosítsa ezt a változót a saját kiszolgáló nevének megadásához. Ebben a kötegfájlban az alapértelmezett a localhost. Ha módosítja a%SERVER_NAME%
változót, át kell haladnia a Client.cs és Service.cs fájlokat, és a localhost összes példányát le kell cserélnie a Setup.bat szkriptben használt kiszolgálónévre.A tanúsítvány a Saját (Személyes) tárolóban van tárolva az
LocalMachine
áruház helye alatt. A tanúsítvány az IIS által üzemeltetett szolgáltatások LocalMachine áruházában van tárolva. A saját üzemeltetésű szolgáltatások esetében módosítania kell a kötegfájlt úgy, hogy az ügyféltanúsítványt a CurrentUser tárolóhelyén tárolja, a LocalMachine sztringet a CurrentUserre cserélve.echo ************ echo Server cert setup starting echo %SERVER_NAME% echo ************ echo making server cert echo ************ makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=%SERVER_NAME% -sky exchange -pe
A kiszolgálótanúsítvány telepítése az ügyfél megbízható tanúsítványtárolójába:
A Setup.bat kötegfájl alábbi sorai másolja a kiszolgálótanúsítványt az ügyfél megbízható személyek tárolójába. Erre a lépésre azért van szükség, mert a Makecert.exe által létrehozott tanúsítványokat az ügyfélrendszer nem implicit módon megbízhatónak minősíti. Ha már rendelkezik olyan tanúsítvánnyal, amely egy ügyfél megbízható főtanúsítványában gyökerezik – például egy Microsoft által kiadott tanúsítványban –, nem szükséges az ügyféltanúsítvány-tároló kiszolgálótanúsítvánnyal való feltöltésének ez a lépése.
echo ************ echo copying server cert to client's TrustedPeople store echo ************ certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeople
Ahhoz, hogy az IIS által üzemeltetett szolgáltatásból hozzáférjen a tanúsítvány titkos kulcsához, a felhasználói fióknak, amelyen az IIS által üzemeltetett folyamat fut, megfelelő engedélyeket kell biztosítani a titkos kulcshoz. Ezt a Setup.bat szkript utolsó lépései hajtják végre.
echo ************ echo setting privileges on server certificates echo ************ for /F "delims=" %%i in ('"%ProgramFiles%\ServiceModelSampleTools\FindPrivateKey.exe" My LocalMachine -n CN^=%SERVER_NAME% -a') do set PRIVATE_KEY_FILE=%%i set WP_ACCOUNT=NT AUTHORITY\NETWORK SERVICE (ver | findstr /C:"5.1") && set WP_ACCOUNT=%COMPUTERNAME%\ASPNET echo Y|cacls.exe "%PRIVATE_KEY_FILE%" /E /G "%WP_ACCOUNT%":R iisreset
Feljegyzés
A Setup.bat kötegelt fájl úgy lett kialakítva, hogy egy Visual Studio parancssorból fusson. A Visual Studio parancssorában beállított PATH környezeti változó a Setup.bat szkript által igényelt végrehajtható fájlokat tartalmazó könyvtárra mutat.
A minta beállítása és létrehozása
Győződjön meg arról, hogy elvégezte a Windows Communication Foundation-minták egyszeri beállítási eljárását.
A megoldás létrehozásához kövesse a Windows Communication Foundation-minták készítésére vonatkozó utasításokat.
A minta futtatása ugyanazon a számítógépen
- Nyisson meg egy Visual Studio parancssori ablakot rendszergazdai jogosultságokkal, és futtassa a Setup.bat a minta telepítési mappából. Ez telepíti a minta futtatásához szükséges összes tanúsítványt. Győződjön meg arról, hogy az elérési út tartalmazza azt a mappát, amelyben Makecert.exe található.
Feljegyzés
A mintával végzett Cleanup.bat futtatásával távolítsa el a tanúsítványokat. Más biztonsági minták ugyanazokat a tanúsítványokat használják.
Indítsa el a Client.exe az ügyfél\bin könyvtárból. Az ügyféltevékenység megjelenik az ügyfélkonzol-alkalmazásban.
Ha az ügyfél és a szolgáltatás nem tud kommunikálni, olvassa el a WCF-minták hibaelhárítási Tippek című témakört.
A minta futtatása a számítógépen
Hozzon létre egy címtárat a szolgáltatásszámítógépen a szolgáltatás bináris fájljaihoz.
Másolja a szolgáltatásprogram fájljait a szolgáltatásszámítógép szolgáltatáskönyvtárába. Ne felejtse el másolni a CreditCardFile.txt; ellenkező esetben a hitelkártyahitelesítő nem tudja érvényesíteni az ügyféltől küldött hitelkártyaadatokat. Másolja a Setup.bat és Cleanup.bat fájlokat is a szolgáltatásszámítógépre.
Rendelkeznie kell a számítógép teljes tartománynevét tartalmazó tulajdonosnévvel rendelkező kiszolgálótanúsítvánnyal. Létrehozhat egyet a Setup.bat használatával, ha a változót
%SERVER_NAME%
a szolgáltatást futtató számítógép teljes neveként módosítja. Vegye figyelembe, hogy a Setup.bat fájlt rendszergazdai jogosultságokkal megnyitott Fejlesztői parancssorban kell futtatni.Másolja a kiszolgálótanúsítványt az ügyfél CurrentUser-Trusted Kapcsolatok tárolójába. Ezt csak akkor kell megtennie, ha a kiszolgálói tanúsítványt nem megbízható kiállító állítja ki.
A EchoServiceHost.cs fájlban módosítsa a tanúsítvány tulajdonosának nevét úgy, hogy a localhost helyett egy teljes számítógépnevet adjon meg.
Másolja az ügyfélprogram fájljait a \client\bin\ mappából a nyelvspecifikus mappából az ügyfélszámítógépre.
A Client.cs fájlban módosítsa a végpont címértékét, hogy megfeleljen a szolgáltatás új címének.
A Client.cs fájlban módosítsa az X.509 szolgáltatás tanúsítvány tulajdonosának nevét úgy, hogy az megfeleljen a távoli gazdagép teljes számítógépnevének a localhost helyett.
Az ügyfélszámítógépen indítsa el a Client.exe egy parancssori ablakból.
Ha az ügyfél és a szolgáltatás nem tud kommunikálni, olvassa el a WCF-minták hibaelhárítási Tippek című témakört.
A minta utáni tisztítás
- A minta futtatása után futtassa a Cleanup.bat a mintamappában.