2017-08-19 2 views
11

créer un service WCF que vous pouvez voir:CustomAuthorizationPolicy.Evaluate() ne se déclenche jamais dans WCF WebHttpBinding

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

string GetData(string data); 

Je crée une coutume autorise que vous pouvez voir:

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); 
    } 
} 

Et authentification:

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); 
      } 
     } 
    } 

Donc je crée et héberge https dans mon IIS et je télécharge le service, mon authenticati sur la classe fonctionne mais mon autorisation ne .why? Je définis mon authentification dans ma configuration web comme vous pouvez le voir.Mais je ne sais pas comment puis-je définir mon autorisation dans ma configuration web.

<?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> 

Je veux dire quand je l'appelle mon service dans le client .le le service ne vérifie pas la function.i authorize devrait définir d'autoriser ma classe personnalisée dans la webconfig mais je ne sais pas comment?

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

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

J'ai vraiment besoin de votre aide –

Répondre

0

Vous pouvez spécifier votre AuthorizationPolicy personnalisé dans les <serviceAuthorization> balises, par exemple:

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

Dans les documents WCF, il existe un bon exemple d'implémentation d'un Custom Authorization Policy pour un service WCF.

Faites attention, cependant, en remplaçant la méthode CheckAccess de la classe de base AuthorizationManager abstraite. La méthode de la classe de base appelle la méthode GetAuthorizationPolicies en interne pour récupérer une collection de tous les objets IAuthorizationPolicy présents (voir également this blog article).

Si vous substituez CheckAcces et n'appelez pas la méthode de la classe parente, aucune méthode Evaluate des objets IAuthorizationPolicy ne sera appelée.