다음을 통해 공유


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).
  1. 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.

  2. 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.

  3. 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