ServiceAuthorizationManager.cs 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel
  5. {
  6. using System.Collections.Generic;
  7. using System.ServiceModel.Channels;
  8. using System.ServiceModel.Description;
  9. using System.Collections.ObjectModel;
  10. using System.Diagnostics;
  11. using System.IdentityModel.Policy;
  12. using System.ServiceModel.Diagnostics;
  13. using System.ServiceModel.Security;
  14. public class ServiceAuthorizationManager
  15. {
  16. // This is the API called by framework to perform CheckAccess.
  17. // The API is responsible for ...
  18. // 1) Evaluate all policies (Forward\Backward)
  19. // 2) Optionally wire up the resulting AuthorizationContext
  20. // to ServiceSecurityContext.
  21. // 3) An availability of message content to make an authoritive decision.
  22. // 4) Return the authoritive decision true/false (allow/deny).
  23. public virtual bool CheckAccess(OperationContext operationContext, ref Message message)
  24. {
  25. return CheckAccess(operationContext);
  26. }
  27. public virtual bool CheckAccess(OperationContext operationContext)
  28. {
  29. if (operationContext == null)
  30. {
  31. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("operationContext");
  32. }
  33. // default to forward-chaining implementation
  34. // 1) Get policies that will participate in chain process.
  35. // We provide a safe default policies set below.
  36. ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies = GetAuthorizationPolicies(operationContext);
  37. // 2) Do forward chaining and wire the new ServiceSecurityContext
  38. operationContext.IncomingMessageProperties.Security.ServiceSecurityContext =
  39. new ServiceSecurityContext(authorizationPolicies ?? EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance);
  40. // 3) Call the CheckAccessCore
  41. return CheckAccessCore(operationContext);
  42. }
  43. // Define the set of policies taking part in chaining. We will provide
  44. // the safe default set (primary token + all supporting tokens except token with
  45. // with SecurityTokenAttachmentMode.Signed + transport token). Implementor
  46. // can override and provide different selection of policies set.
  47. protected virtual ReadOnlyCollection<IAuthorizationPolicy> GetAuthorizationPolicies(OperationContext operationContext)
  48. {
  49. SecurityMessageProperty security = operationContext.IncomingMessageProperties.Security;
  50. if (security == null)
  51. {
  52. return EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance;
  53. }
  54. ReadOnlyCollection<IAuthorizationPolicy> externalPolicies = security.ExternalAuthorizationPolicies;
  55. if (security.ServiceSecurityContext == null)
  56. {
  57. return externalPolicies ?? EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance;
  58. }
  59. ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies = security.ServiceSecurityContext.AuthorizationPolicies;
  60. if (externalPolicies == null || externalPolicies.Count <= 0)
  61. {
  62. return authorizationPolicies;
  63. }
  64. // Combine
  65. List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>(authorizationPolicies);
  66. policies.AddRange(externalPolicies);
  67. return policies.AsReadOnly();
  68. }
  69. // Implementor overrides this API to make authoritive decision.
  70. // The AuthorizationContext in opContext is generally the result from forward chain.
  71. protected virtual bool CheckAccessCore(OperationContext operationContext)
  72. {
  73. return true;
  74. }
  75. }
  76. }