【问题标题】:CustomAuthorizationPolicy.Evaluate() method never fires in wcf webhttpbindingCustomAuthorizationPolicy.Evaluate() 方法永远不会在 wcf webhttpbinding 中触发
【发布时间】:2017-09-20 04:09:26
【问题描述】:

如您所见,我创建了一个 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);
            }
        }
    }

所以我在我的 IIS 中创建和 https 托管并上传服务,我的身份验证类正在工作,但我的授权没有。为什么?我在我的 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>

我的意思是当我在客户端调用我的服务时。服务不检查授权功能。我应该在 webconfig 中定义我的自定义授权类,但我不知道如何?

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

    // return Roles.IsUserInRole(role);
}

【问题讨论】:

  • 我真的需要你的帮助

标签: c# wcf authorization restful-architecture


【解决方案1】:

您可能需要在web config 文件中设置serviceCredentials

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

这里是关于serviceCredentials的更多信息的链接:https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/servicecredentials

【讨论】:

  • 谢谢你亲爱的朋友,但我想我不能在我的装订中使用它,对吗?
【解决方案2】:

您可以在 &lt;serviceAuthorization&gt; 标签中指定您的自定义 AuthorizationPolicy,例如:

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

在 WCF 文档中有一个为 WCF 服务实现 Custom Authorization Policy 的好示例。

不过,在重写抽象 AuthorizationManager 基类的 CheckAccess 方法时要小心。基类的方法在内部调用GetAuthorizationPolicies 方法来检索所有存在的IAuthorizationPolicy 对象的集合(另请参见this blog article)。

如果重写 CheckAcces 并且不调用父类的方法,则不会调用 IAuthorizationPolicy 对象的任何 Evaluate 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-15
    • 2015-02-06
    • 1970-01-01
    • 1970-01-01
    • 2021-05-22
    • 2015-04-19
    • 1970-01-01
    相关资源
    最近更新 更多