/// <summary> /// Overrides the SetUpClaims from the SecurityTokenService Base Class /// Checks if the caller can purchase the book specified in the RST and if so /// issues a purchase authorized claim /// </summary> protected override Collection<SamlAttribute> GetIssuedClaims(RequestSecurityToken requestSecurityToken) { EndpointAddress rstAppliesTo = requestSecurityToken.AppliesTo; if (rstAppliesTo == null) { throw new InvalidOperationException("No AppliesTo EndpointAddress in RequestSecurityToken"); } string bookName = rstAppliesTo.Headers.FindHeader(Constants.BookNameHeaderName, Constants.BookNameHeaderNamespace).GetValue<string>(); if (string.IsNullOrEmpty(bookName)) throw new FaultException("The book name was not specified in the RequestSecurityToken"); EnsurePurchaseLimitSufficient(bookName); Collection<SamlAttribute> samlAttributes = new Collection<SamlAttribute>(); foreach (ClaimSet claimSet in ServiceSecurityContext.Current.AuthorizationContext.ClaimSets) { // Copy Name claims from the incoming credentials into the set of claims we're going to issue IEnumerable<Claim> nameClaims = claimSet.FindClaims(ClaimTypes.Name, Rights.PossessProperty); if (nameClaims != null) { foreach (Claim nameClaim in nameClaims) { samlAttributes.Add(new SamlAttribute(nameClaim)); } } } // add a purchase authorized claim samlAttributes.Add(new SamlAttribute(new Claim(Constants.PurchaseAuthorizedClaim, bookName, Rights.PossessProperty))); return samlAttributes; }
/// <summary> /// Overrides the GetIssuedClaims from the SecurityTokenService Base Class /// to return a valid user claim and purchase limit claim with the appropriate purchase limit /// for the user /// </summary> protected override Collection<SamlAttribute> GetIssuedClaims(RequestSecurityToken requestSecurityToken) { string caller = ServiceSecurityContext.Current.PrimaryIdentity.Name; double purchaseLimit = GetPurchaseLimit(); // Create Name and PurchaseLimit claims Collection<SamlAttribute> samlAttributes = new Collection<SamlAttribute>(); samlAttributes.Add(new SamlAttribute(Claim.CreateNameClaim(caller))); samlAttributes.Add(new SamlAttribute(new Claim ( Constants.PurchaseLimitClaim, purchaseLimit.ToString(), Rights.PossessProperty))); return samlAttributes; }
/// <summary> /// abstract method for setting up claims in the SAML Token issued by the STS /// Should be overridden by STS implementations that derive from this base class /// to set up appropriate claims /// </summary> protected abstract Collection<SamlAttribute> GetIssuedClaims(RequestSecurityToken requestSecurityToken);
/// <summary> /// abstract method for setting up claims in the SAML Token issued by the STS /// Should be overridden by STS implementations that derive from this base class /// to set up appropriate claims /// </summary> protected abstract Collection <SamlAttribute> GetIssuedClaims(RequestSecurityToken requestSecurityToken);
/// <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); }