Exemplo n.º 1
0
        /// <summary>
        /// Virtual method for ProcessRequestSecurityToken
        /// Should be overridden by STS implementations that derive from this base class
        /// </summary>
        public virtual Message ProcessRequestSecurityToken(Message message)
        {
            // Check for appropriate action header
            EnsureRequestSecurityTokenAction(message);

            // Extract the MessageID from the request message
            UniqueId requestMessageID = message.Headers.MessageId;

            if (requestMessageID == null)
            {
                throw new InvalidOperationException("The request message does not have a message ID.");
            }

            // Get the RST from the message
            RequestSecurityToken rst = RequestSecurityToken.CreateFrom(message.GetReaderAtBodyContents());

            // Set up the claims we are going to issue
            Collection <SamlAttribute> samlAttributes = GetIssuedClaims(rst);

            // get the key size, default to 192
            int keySize = (rst.KeySize != 0) ? rst.KeySize : 192;

            // Create proof token
            // Get requester entropy, if any
            byte[]        senderEntropy = null;
            SecurityToken entropyToken  = rst.RequestorEntropy;

            if (entropyToken != null)
            {
                senderEntropy = ((BinarySecretSecurityToken)entropyToken).GetKeyBytes();
            }

            byte[] key        = null;
            byte[] stsEntropy = null;

            // If sender provided entropy, then use combined entropy
            if (senderEntropy != null)
            {
                // Create an array to store the entropy bytes
                stsEntropy = new byte[keySize / 8];
                // Create some random bytes
                RNGCryptoServiceProvider random = new RNGCryptoServiceProvider();
                random.GetNonZeroBytes(stsEntropy);
                // Compute the combined key
                key = RequestSecurityTokenResponse.ComputeCombinedKey(senderEntropy, stsEntropy, keySize);
            }
            else // Issuer entropy only...
            {
                // Create an array to store the entropy bytes
                key = new byte[keySize / 8];
                // Create some random bytes
                RNGCryptoServiceProvider random = new RNGCryptoServiceProvider();
                random.GetNonZeroBytes(key);
            }

            // Create a BinarySecretSecurityToken to be the proof token, based on the key material
            // in key. The key is the combined key in the combined entropy case, or the issuer entropy
            // otherwise
            BinarySecretSecurityToken proofToken = new BinarySecretSecurityToken(key);

            // Create the saml condition
            SamlConditions samlConditions = new SamlConditions(DateTime.UtcNow - TimeSpan.FromMinutes(5), DateTime.UtcNow + TimeSpan.FromHours(10));

            AddAudienceRestrictionCondition(samlConditions);

            // Create a SAML token, valid for around 10 hours
            SamlSecurityToken samlToken = SamlTokenCreator.CreateSamlToken(this.stsName,
                                                                           proofToken,
                                                                           this.IssuerToken,
                                                                           this.ProofKeyEncryptionToken,
                                                                           samlConditions,
                                                                           samlAttributes);

            // Set up RSTR
            RequestSecurityTokenBase rstr = GetRequestSecurityTokenResponse(rst, keySize, proofToken, samlToken, senderEntropy, stsEntropy);

            // Create a message from the RSTR
            Message rstrMessage = Message.CreateMessage(message.Version, Constants.Trust.Actions.IssueReply, rstr);

            // Set RelatesTo of response message to MessageID of request message
            rstrMessage.Headers.RelatesTo = requestMessageID;

            // Return the create message
            return(rstrMessage);
        }