Метод CustomAuthorizationPolicy.Evaluate() никогда не запускается в wcf webhttpbinding

Я создаю wcf-службу, как вы можете видеть:

[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Role = "Admin")]
[WebInvoke(Method = "GET", UriTemplate = "/Data/{data}")]

string GetData(string data);

Поэтому я создаю настраиваемое разрешение, как вы можете видеть:

public class AuthorizationPolicy : IAuthorizationPolicy
{
    string id = Guid.NewGuid().ToString();

    public string Id
    {
        get { return this.id; }
    }

    public System.IdentityModel.Claims.ClaimSet Issuer
    {
        get { return System.IdentityModel.Claims.ClaimSet.System; }
    }

    // this method gets called after the authentication stage
    public bool Evaluate(EvaluationContext evaluationContext, ref object state)
    {
        // get the authenticated client identity
        IIdentity client = HttpContext.Current.User.Identity;

        // set the custom principal
        evaluationContext.Properties["Principal"] = new CustomPrincipal(client);

        return true;
    }
}

public class CustomPrincipal : IPrincipal
{
    private IIdentity _identity;
    public IIdentity Identity
    {
        get
        {
            return _identity;
        }
    }

    public CustomPrincipal(IIdentity identity)
    {
        _identity = identity;
    }

    public bool IsInRole(string role)
    {
        //my code 
        return true;

       // return Roles.IsUserInRole(role);
    }
}

И аутентификация:

  public class RestAuthorizationManager: ServiceAuthorizationManager
    {
        protected override bool CheckAccessCore(OperationContext operationContext)
        {
            //Extract the Authorization header, and parse out the credentials converting the Base64 string:  
            var authHeader = WebOperationContext.Current.IncomingRequest.Headers["Authorization"];
            if ((authHeader != null) && (authHeader != string.Empty))
            {
                var svcCredentials = System.Text.ASCIIEncoding.ASCII
                    .GetString(Convert.FromBase64String(authHeader.Substring(6)))
                    .Split(':');
                var user = new
                {
                    Name = svcCredentials[0],
                    Password = svcCredentials[1]
                };
                if ((user.Name == "1" && user.Password == "1"))
                {
                    //here i get the role of my user from the database
                    // return Admin role 
                    //User is authrized and originating call will proceed  
                    return true;
                }
                else
                {
                    //not authorized  
                    return false;
                }
            }
            else
            {
                //No authorization header was provided, so challenge the client to provide before proceeding:  
                WebOperationContext.Current.OutgoingResponse.Headers.Add("WWW-Authenticate: Basic realm=\"MyWCFService\"");
                //Throw an exception with the associated HTTP status code equivalent to HTTP status 401  
                throw new WebFaultException(HttpStatusCode.Unauthorized);
            }
        }
    }

Итак, я создаю и https-хостинг в своем IIS, и я загружаю эту услугу, мой класс проверки подлинности работает, но моя авторизация не работает. Почему? Я определяю свою аутентификацию в своей веб-конфигурации, как вы можете видеть. Но я не знаете, как я могу определить свою авторизацию в моей веб-конфигурации.

<?xml version="1.0"?>
<configuration>

<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2"/>
</system.web>
<system.serviceModel>
<client />

<bindings>
  <webHttpBinding>
    <binding>
      <security mode="Transport" />
    </binding>
  </webHttpBinding>
</bindings>

<behaviors>
  <serviceBehaviors>
    <behavior name="ServiceBehavior">

      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
      <serviceAuthorization
        serviceAuthorizationManagerType  
    ="wcfrestauth.RestAuthorizationManager, wcfrestauth"/>
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="webHttpServiceBehavior">
      <!-- Important this is the behavior that makes a normal WCF service to REST based service-->
      <webHttp/>
    </behavior>
  </endpointBehaviors>
</behaviors>
<services>
  <service name="wcfrestauth.Service1" behaviorConfiguration="ServiceBehavior">
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost/WCFRestAuthentication/api/" />
      </baseAddresses>
    </host>
    <endpoint binding="webHttpBinding" contract="wcfrestauth.IService1" behaviorConfiguration="webHttpServiceBehavior" />
  </service>
</services>

<protocolMapping>
  <add binding="webHttpBinding" scheme="https"/>

</protocolMapping>

<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>

</configuration>

Я имею в виду, когда я вызываю свое обслуживание в клиенте. Служба не проверяет функцию авторизации. я должен определить мой собственный класс полномочий в webconfig, но я не знаю, как это сделать?

public bool IsInRole(string role)
{
    //my code 
    return true;

    // return Roles.IsUserInRole(role);
}

Ответ 2

Вы можете указать свою пользовательскую AuthorizationPolicy в тегах <serviceAuthorization>, например:

<serviceAuthorization serviceAuthorizationManagerType=
        "wcfrestauth.RestAuthorizationManager, wcfrestauth">
  <authorizationPolicies>         
    <add policyType="wcfrestauth.AuthorizationPolicy, wcfrestauth"  
  </authorizationPolicies> 
</serviceAuthorization>

В документах WCF есть хороший пример для реализации Custom Authorization Policy для службы WCF.

Будьте осторожны, если переопределить метод CheckAccess абстрактного базового класса AuthorizationManager. Метод базового класса внутренне вызывает метод GetAuthorizationPolicies для извлечения коллекции всех объектов IAuthorizationPolicy (см. Также в этой статье в блоге).

Если вы переопределите CheckAcces и не вызываете метод родительского класса, не будет вызван какой-либо метод Evaluate объектов IAuthorizationPolicy.