AuthorizationBehavior.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.Dispatcher
  5. {
  6. using System.Collections.ObjectModel;
  7. using System.Diagnostics;
  8. using System.Globalization;
  9. using System.IdentityModel.Policy;
  10. using System.Runtime;
  11. using System.Runtime.CompilerServices;
  12. using System.ServiceModel;
  13. using System.ServiceModel.Diagnostics;
  14. using System.ServiceModel.Diagnostics.Application;
  15. using System.ServiceModel.Security;
  16. sealed class AuthorizationBehavior
  17. {
  18. static ServiceAuthorizationManager DefaultServiceAuthorizationManager = new ServiceAuthorizationManager();
  19. ReadOnlyCollection<IAuthorizationPolicy> externalAuthorizationPolicies;
  20. ServiceAuthorizationManager serviceAuthorizationManager;
  21. AuditLogLocation auditLogLocation;
  22. bool suppressAuditFailure;
  23. AuditLevel serviceAuthorizationAuditLevel;
  24. AuthorizationBehavior() { }
  25. public void Authorize(ref MessageRpc rpc)
  26. {
  27. if (TD.DispatchMessageBeforeAuthorizationIsEnabled())
  28. {
  29. TD.DispatchMessageBeforeAuthorization(rpc.EventTraceActivity);
  30. }
  31. SecurityMessageProperty security = SecurityMessageProperty.GetOrCreate(rpc.Request);
  32. security.ExternalAuthorizationPolicies = this.externalAuthorizationPolicies;
  33. ServiceAuthorizationManager serviceAuthorizationManager = this.serviceAuthorizationManager ?? DefaultServiceAuthorizationManager;
  34. try
  35. {
  36. if (!serviceAuthorizationManager.CheckAccess(rpc.OperationContext, ref rpc.Request))
  37. {
  38. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateAccessDeniedFaultException());
  39. }
  40. }
  41. catch (Exception ex)
  42. {
  43. if (Fx.IsFatal(ex))
  44. {
  45. throw;
  46. }
  47. if (PerformanceCounters.PerformanceCountersEnabled)
  48. {
  49. PerformanceCounters.AuthorizationFailed(rpc.Operation.Name);
  50. }
  51. if (AuditLevel.Failure == (this.serviceAuthorizationAuditLevel & AuditLevel.Failure))
  52. {
  53. try
  54. {
  55. string primaryIdentity;
  56. string authContextId = null;
  57. AuthorizationContext authContext = security.ServiceSecurityContext.AuthorizationContext;
  58. if (authContext != null)
  59. {
  60. primaryIdentity = SecurityUtils.GetIdentityNamesFromContext(authContext);
  61. authContextId = authContext.Id;
  62. }
  63. else
  64. {
  65. primaryIdentity = SecurityUtils.AnonymousIdentity.Name;
  66. authContextId = "<null>";
  67. }
  68. SecurityAuditHelper.WriteServiceAuthorizationFailureEvent(this.auditLogLocation,
  69. this.suppressAuditFailure, rpc.Request, rpc.Request.Headers.To, rpc.Request.Headers.Action,
  70. primaryIdentity, authContextId,
  71. serviceAuthorizationManager == DefaultServiceAuthorizationManager ? "<default>" : serviceAuthorizationManager.GetType().Name,
  72. ex);
  73. }
  74. #pragma warning suppress 56500
  75. catch (Exception auditException)
  76. {
  77. if (Fx.IsFatal(auditException))
  78. throw;
  79. DiagnosticUtility.TraceHandledException(auditException, TraceEventType.Error);
  80. }
  81. }
  82. throw;
  83. }
  84. if (AuditLevel.Success == (this.serviceAuthorizationAuditLevel & AuditLevel.Success))
  85. {
  86. string primaryIdentity;
  87. string authContextId;
  88. AuthorizationContext authContext = security.ServiceSecurityContext.AuthorizationContext;
  89. if (authContext != null)
  90. {
  91. primaryIdentity = SecurityUtils.GetIdentityNamesFromContext(authContext);
  92. authContextId = authContext.Id;
  93. }
  94. else
  95. {
  96. primaryIdentity = SecurityUtils.AnonymousIdentity.Name;
  97. authContextId = "<null>";
  98. }
  99. SecurityAuditHelper.WriteServiceAuthorizationSuccessEvent(this.auditLogLocation,
  100. this.suppressAuditFailure, rpc.Request, rpc.Request.Headers.To, rpc.Request.Headers.Action,
  101. primaryIdentity, authContextId,
  102. serviceAuthorizationManager == DefaultServiceAuthorizationManager ? "<default>" : serviceAuthorizationManager.GetType().Name);
  103. }
  104. }
  105. [MethodImpl(MethodImplOptions.NoInlining)]
  106. static AuthorizationBehavior CreateAuthorizationBehavior(DispatchRuntime dispatch)
  107. {
  108. AuthorizationBehavior behavior = new AuthorizationBehavior();
  109. behavior.externalAuthorizationPolicies = dispatch.ExternalAuthorizationPolicies;
  110. behavior.serviceAuthorizationManager = dispatch.ServiceAuthorizationManager;
  111. behavior.auditLogLocation = dispatch.SecurityAuditLogLocation;
  112. behavior.suppressAuditFailure = dispatch.SuppressAuditFailure;
  113. behavior.serviceAuthorizationAuditLevel = dispatch.ServiceAuthorizationAuditLevel;
  114. return behavior;
  115. }
  116. public static AuthorizationBehavior TryCreate(DispatchRuntime dispatch)
  117. {
  118. if (dispatch == null)
  119. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("dispatch"));
  120. if (!dispatch.RequiresAuthorization)
  121. return null;
  122. return CreateAuthorizationBehavior(dispatch);
  123. }
  124. internal static Exception CreateAccessDeniedFaultException()
  125. {
  126. // always use default version?
  127. SecurityVersion wss = SecurityVersion.Default;
  128. FaultCode faultCode = FaultCode.CreateSenderFaultCode(wss.FailedAuthenticationFaultCode.Value, wss.HeaderNamespace.Value);
  129. FaultReason faultReason = new FaultReason(SR.GetString(SR.AccessDenied), CultureInfo.CurrentCulture);
  130. return new FaultException(faultReason, faultCode);
  131. }
  132. }
  133. }