How to: Create a Constraint on a Relationship
How to: Create a Constraint on a Relationship
This topic describes how to create a constraint on a relationship that puts restrictions on some of its settings. This topic uses the sample from a previous topic How to: Create an SDM Resource and demonstrates how to add a constraint to a relationship defined in that sample.
Standard Setting Constraints
The relationship setting uses the built-in ListComparison constraint to impose a condition on one of its settings. There are several simple setting constraints provided that you can consider to use before writing your own custom setting constraint. They are contained in the System.Constraints.sdmdocument file.
The standard setting constraints each have the following settings:
- ActualValue: The value that is specified by the user.
- DesiredValue: The value that the constraint requires.
- Operator: The operator used to perform the comparison.
Constraint | Operators | Description |
---|---|---|
SimpleComparison | =, <, <=, >, >=, !=, Contains, Between. The default is =. | Compares one setting value to another setting value. The operators will also operate on the following built-in setting definitions: Any, String, Int, UnsignedInt, Long, UnsignedLong, Float, Decimal, Double, Boolean, and TimeSpan. |
EnumComparison | OneOf, NoneOf. The default is OneOf | Compares whether a value exists (OneOf) or doesn't exist (NoneOf) in a list of values. |
ListComparison | ContainsAll, ContainsOne, ContainsNone. The default is ContainsAll. | Compares whether a list of values is contained entirely by the desired list of values (ContainsAll), or has at least one value in the desired list (ContainsOne), or does not have any values in the desired list (ContainsNone). |
Add a constraint to check that a setting related to the certificate is valid.
Add a constraint to the certificates resource sample. This constraint will be added to the containment relation between a Web application (the containing parent) and a certificate (the contained member).
<ContainmentDefinition Name="WebApplicationContainsCertificate" ParentDefinition="WebApp:WebApplication" MemberDefinition="X509Certificate">
This is the context in which the constraint is defined, and therefore applies to certificate members which are contained in Web applications.
<!-- A certificate that is used by a web application must satisfy EnhancedKeyUsage = ServerAuthentication --> <ObjectConstraint Name="CheckCertificates" PrimaryRole="Member" PrimaryObjectDefinition="X509Certificate"> <!-- Constraint details --> <Constraint Name="RequireServerAuthenticationUsage" Definition="Constraints:ListComparison"> <SettingValue Path="Operator">ContainsAll</SettingValue> <SettingValueList Path="DesiredValue" Definition="EnhancedKeyUsageType"> <Value>ServerAuthentication</Value> </SettingValueList> <Input Name="ActualValue" Path="Member.EnhancedKeyUsage"/> </Constraint> </ObjectConstraint>
Because this is a constraint on an object setting, the element <ObjectConstraint> is used to describe it. To see the structure of an object constraint, it is useful to look at the topic ObjectConstraint (ConstraintDefinition) Element which in turn describes an element of ObjectConstraint Complex Type. The object constraint has a Name attribute that gives the constraint a meaningful name. In this case, it is called "CheckCertificates". The PrimaryRole attribute is the name of the role in the relationship that this constraint targets. Here it has a value "Member" which references the contained object in the containment relationship. The name of the object definition associated with the primary role is mentioned in the PrimaryObjectDefinition attribute. The name here is "X509Certificate", which is a value of the simple type QualifiedName.
The constraint details appear in a <Constraint> element. For more information on the <Constraint> element see Constraint (ObjectConstraint) Element. It has a name attribute whose value is a meaningful name for the constraint at the certificate (member) level. Here, the value is "RequireServerAuthenticationUsage". The Definition attribute of the constraint tells us that the type of constraint is a "Constraints:ListComparison", which is a predefined constraint in the "Constraints" namespace. The list comparison constraint in this case uses a "ContainsAll" operator, which checks to see if the actual value pointed to by the <Input> element is among the desired values contained in the list that is described by the <SettingValueList> element. The value of Path attribute, of the <Input> element points to the "EnhancedKeyUsage" setting as the source of the actual value used for the comparison. The Definition attribute of the <SettingValueList> element describes the type of contents expected to be in the list. Here, the value of the Definition attribute of the <SettingValueList> element is an enumeration called "EnhancedKeyUsageType" described previously in the topic How to: Create an SDM Resource. In this case, the list of <Value> elements that follows contains a singleton entry from the possible entries in the enumeration, namely, "ServerAuthentication". The constraint thus checks to see if the "EnhancedKeyUsage" setting of the "X509Certificate" member mentioned in the object constraint has the value "ServerAuthentication". In simple words, the constraint checks to make sure that a certificate contained in a Web application can only be used for server authentication.
Create an error message for a failed constraint.
The following example shows how to create a more meaningful error message when a constraint fails. Without a custom error message, you will see a generic error message. ITo return an error message specific to the failure, you need to add a <Description> element with the attribute ErrorDescription. When this constraint fails, this very specific error message will be returned to the user.
<!-- Error Description for this constraint --> <Description> <Entry Name="ErrorDescription" Manager="CertManager" Substitute="Parent.InstanceName Member.EnhancedKeyUsage" ResourceId="RequireServerAuthenticationUsage"> The web application '{0}' contains a certificate with the EnhancedKeyUsage value '{1}', but the constraint dictates that the EnhancedKeyUsage value must be 'ServerAuthentication'. Please change the value. </Entry> </Description>
To substitute parameters into the message, the Substitute attribute is used, with substitution parameters separated by a space. The sdm compiler uses the standard String.Format method to insert the parameters. Make sure the insertion indices are zero-based. Note that the SDM compiler will not attempt to resolve the parameters at compile time. They will only be resolved when the constraint fails, so ensure that each constraint failure message is tested.
The .sdm file that results from adding the above constraint and error definition to the sample in the How to: Create an SDM Resource topic is given below in its entirety.
[XML]
<?xml version="1.0" encoding="UTF-8"?> <SystemDefinitionModel Name="Microsoft.Samples.Certificates" Version="1.0.0.0" DocumentLanguage="en" xmlns="https://schemas.microsoft.com/SystemDefinitionModel/2005/1"> <Information> <FriendlyName>Sample certificate model</FriendlyName> <CompanyName>Microsoft Corporation</CompanyName> <Copyright> Copyright (c) Microsoft Corporation. All rights reserved. This is provided AS IS with no warranties, and confers no rights. </Copyright> <Description Manager="CertManager" ResourceId="DocumentDescription"> SDM model for certificate resources </Description> </Information> <Import Alias="WindowsHost" Name="Microsoft.WindowsHost" /> <Import Alias="WindowsApp" Name="Microsoft.WindowsApplication" /> <Import Alias="IIS" Name="Microsoft.InternetInformationServices" /> <Import Alias="WebHost" Name="Microsoft.WebHost" /> <Import Alias="WebApp" Name="Microsoft.WebApplication" /> <Import Alias="FileSystem" Name="Microsoft.FileSystem" /> <Import Alias="Constraints" Name="System.Constraints" /> <Import Alias="Flow" Name="System.Flow"/> <!-- Setting definitions --> <SettingDefinitions Manager="CertManager" ClrNamespace="Microsoft.Sdm.Samples.Certificates"> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns="http://Microsoft.Samples.Certificates" targetNamespace="http://Microsoft.Samples.Certificates"> <xs:simpleType name="HexString"> <xs:annotation> <xs:documentation> Defines a type for representing a hex encoded number. </xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> <xs:pattern value="[0-9A-Fa-f]+" /> </xs:restriction> </xs:simpleType> <xs:simpleType name="KeyUsageType"> <xs:annotation> <xs:documentation> Defines an enumeration for key usage. </xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> <xs:enumeration value="DigitalSignature" /> <xs:enumeration value="NonRepudiation" /> <xs:enumeration value="KeyEncryption" /> <xs:enumeration value="DataEncryption" /> <xs:enumeration value="KeyAgreement" /> <xs:enumeration value="CertificateValidation" /> <xs:enumeration value="CRLValidation" /> </xs:restriction> </xs:simpleType> <xs:simpleType name="EnhancedKeyUsageType"> <xs:annotation> <xs:documentation> Defines an enumeration for enhanced key usage. </xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> <xs:enumeration value="ClientAuthentication" /> <xs:enumeration value="ServerAuthentication" /> <xs:enumeration value="EmailProtection" /> <xs:enumeration value="CodeSigning" /> <xs:enumeration value="TimeStampSigning" /> <xs:enumeration value="IPSec" /> <xs:enumeration value="Other" /> </xs:restriction> </xs:simpleType> <xs:complexType name="PropertyValuePairType"> <xs:sequence> <xs:element name="Property" type="xs:string" /> <xs:element name="Value" type="xs:string" /> </xs:sequence> </xs:complexType> </xs:schema> </SettingDefinitions> <ResourceDefinition Name="CertificateStore" Layer="ApplicationHost" Abstract="true"> <SettingDeclaration Name="Name" Definition="String" /> </ResourceDefinition> <ResourceDefinition Name="X509Certificate" Layer="Application" Abstract="true"> <!-- X509 V3 settings --> <SettingDeclaration Name="Version" Definition="String" /> <SettingDeclaration Name="SerialNumber" Definition="HexString" /> <SettingDeclaration Name="AlgorithmId" Definition="String" /> <SettingDeclaration Name="AlgorithmParameters" Definition="String" List="true" /> <SettingDeclaration Name="IssuerName" Definition="String" /> <SettingDeclaration Name="ValidFrom" Definition="DateTime" /> <SettingDeclaration Name="ValidTo" Definition="DateTime" /> <SettingDeclaration Name="SubjectName" Definition="String" /> <SettingDeclaration Name="PublicKey" Definition="HexString" /> <SettingDeclaration Name="PublicKeyAlgorithm" Definition="String" /> <SettingDeclaration Name="PublicKeyParameters" Definition="String" List="true" /> <SettingDeclaration Name="Signature" Definition="String" /> <SettingDeclaration Name="IssuerId" Definition="String" /> <SettingDeclaration Name="SubjectId" Definition="HexString" /> <SettingDeclaration Name="Extensions" Definition="PropertyValuePairType" List="true" /> <!-- Key and Policy extensions --> <SettingDeclaration Name="AuthorityKeyId" Definition="HexString" /> <SettingDeclaration Name="SubjectKeyId" Definition="HexString" /> <SettingDeclaration Name="KeyUsage" Definition="KeyUsageType" List="true" /> <SettingDeclaration Name="PrivateKeyUsagePeriod" Definition="String" /> <SettingDeclaration Name="CertificatePolicies" Definition="String" List="true" /> <SettingDeclaration Name="PolicyMappings" Definition="String" List="true" /> <!-- Certificate Subject and Issuer Extensions --> <SettingDeclaration Name="SubjectAlternativeName" Definition="String" List="true" /> <SettingDeclaration Name="IssuerAlternativeName" Definition="String" List="true" /> <SettingDeclaration Name="SubjectDirectoryAttributes" Definition="String" List="true" /> <!-- Certification Path Constraints --> <SettingDeclaration Name="BasicConstraints" Definition="String" List="true" /> <SettingDeclaration Name="NameConstraints" Definition="String" List="true" /> <SettingDeclaration Name="PolicyConstraints" Definition="String" List="true" /> <!-- Other extensions --> <SettingDeclaration Name="EnhancedKeyUsage" Definition="EnhancedKeyUsageType" List="true" /> <SettingDeclaration Name="Thumbprint" Definition="HexString" /> <SettingDeclaration Name="ThumbprintAlgorithm" Definition="String" /> </ResourceDefinition> <!-- Certificate Store containment relationships --> <ContainmentDefinition Name="WindowsHostContainsCertificateStore" ParentDefinition="WindowsHost:WindowsHost" MemberDefinition="CertificateStore"> <Description Manager="CertManager" ResourceId="WindowsHostContainsCertificateStore"> A WindowsHost system can contain certificate store resources. </Description> </ContainmentDefinition> <ContainmentDefinition Name="WebServerContainsCertificateStore" ParentDefinition="WebHost:WebServer" MemberDefinition="CertificateStore"> <Description Manager="CertManager" ResourceId="WebServerContainsCertificateStore"> A WebServer can contain a certificate store. </Description> </ContainmentDefinition> <!-- Certificate containment relationships --> <ContainmentDefinition Name="WindowsApplicationContainsCertificate" ParentDefinition="WindowsApp:WindowsApplication" MemberDefinition="X509Certificate"> <Description Manager="CertManager" ResourceId="WindowsApplicationContainsCertificate"> A WindowsApplication system can contain certificate resources. </Description> </ContainmentDefinition> <ContainmentDefinition Name="WebApplicationContainsCertificate" ParentDefinition="WebApp:WebApplication" MemberDefinition="X509Certificate"> <Description Manager="CertManager" ResourceId="WebApplicationContainsCertificate"> A WebApplication system can contain certificate resources. </Description> <!-- Constraint: A certificate that is used by a web application must have EnhancedKeyUsage = ServerAuthentication --> <ObjectConstraint Name="CheckCertificates" PrimaryRole="Member" PrimaryObjectDefinition="X509Certificate"> <Constraint Name="RequireServerAuthenticationUsage" Definition="Constraints:ListComparison"> <!-- Error Description for this constraint --> <Description> <Entry Name="ErrorDescription" Manager="CertManager" Substitute="Parent.InstanceName Member.EnhancedKeyUsage" ResourceId="RequireServerAuthenticationUsage"> The web application '{0}' contains a certificate with the EnhancedKeyUsage value '{1}', but the constraint dictates that the EnhancedKeyUsage value must be 'ServerAuthentication'. Please change the value. </Entry> </Description> <!-- Constraint details --> <SettingValue Path="Operator"> ContainsAll </SettingValue> <SettingValueList Path="DesiredValue" Definition="EnhancedKeyUsageType"> <Value>ServerAuthentication</Value> </SettingValueList> <Input Name="ActualValue" Path="Member.EnhancedKeyUsage" /> </Constraint> </ObjectConstraint> </ContainmentDefinition> <!-- CertificateStore hosts a Certificate, although this isn't used by the design surface. --> <HostingDefinition Name="CertificateStoreHostsCertificate" HostDefinition="CertificateStore" GuestDefinition="X509Certificate"> <Description Manager="CertManager" ResourceId="CertificateStoreHostsCertificate"> A certificate store can host certificates. </Description> </HostingDefinition> <Manager Name="CertManager" AssemblyName="Microsoft.Sdm.Samples.Certs" SourcePath="Microsoft.Sdm.Samples.Certs.dll" /> </SystemDefinitionModel>
See Also
How to: Create an SDM Resource
ObjectConstraint (ConstraintDefinition) Element
ObjectConstraint Complex Type
Constraint (ObjectConstraint) Element
Send comments about this topic to Microsoft
Build date: 10/2/2007