Метод 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>

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

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

    // return Roles.IsUserInRole(role);
}

2 ответа

Вам может понадобиться установить serviceCredentials в вашем web config файл:

<serviceCredentials type="YourString">
     <YourTagsHere>
     </YourTagsHere>
</serviceCredentials>

Вот ссылка на дополнительную информацию о serviceCredentials: https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/servicecredentials

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

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

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

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

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

Другие вопросы по тегам