【问题标题】:WCF authentication and authorization doesn't workWCF 身份验证和授权不起作用
【发布时间】:2017-05-20 14:46:21
【问题描述】:

我创建了一个带有自定义身份验证和授权的简单 wcf

<system.serviceModel>
    <client />
    <bindings>
      <basicHttpBinding>
        <binding name="secureHttpBinding">
          <security mode="TransportWithMessageCredential">
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <services>
      <service name="WcfService1.Service1" behaviorConfiguration="customBehaviour">
        <endpoint address=""
                  binding="basicHttpBinding"
                  bindingConfiguration="secureHttpBinding"
                  contract="WcfService1.IService1"/>

        <endpoint address="mex"
                  binding="mexHttpsBinding"
                  contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
        <behavior name="customBehaviour">

          <serviceMetadata httpGetEnabled="true"/>

          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="Custom"
               customUserNamePasswordValidatorType="WcfService1.UserAuthentication,WcfService1"/>
          </serviceCredentials>

          <serviceAuthorization principalPermissionMode="Custom">
            <authorizationPolicies>
              <add policyType="WcfService1.AuthorizationPolicy, WcfService1" />
            </authorizationPolicies>
          </serviceAuthorization>


        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

有了这个实现:

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

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

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

        public bool Evaluate(EvaluationContext context, ref object state)
        {
            object obj;
            if (!context.Properties.TryGetValue("Identities", out obj))
                return true;

            IList<IIdentity> identities = obj as IList<IIdentity>;
            if (obj == null || identities.Count <= 0)
                return true;

            context.Properties["Principal"] = new CustomPrincipal(identities[0]);
            return true;
        }
    }
    class CustomPrincipal : IPrincipal
    {
        IIdentity identity;
        public CustomPrincipal(IIdentity identity)
        {
            this.identity = identity;
        }

        public IIdentity Identity
        {
            get { return this.identity; }
        }

        public bool IsInRole(string role)
        {

            return true;
        }
    }

还有

public class UserAuthentication : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            try
            {
                if (userName == "test" && password == "test123")
                {
                    Console.WriteLine("Authentic User");
                }
            }
            catch (Exception ex)
            {
                throw new FaultException("Unknown Username or Incorrect Password");
            }
        }
    }

我在本地 iis 中以 ssl 上传我的服务,并在我的客户端中调用我的服务,如下所示:

 static void Main(string[] args)
        {
            ServiceReference1.Service1Client serviceProxy = new ServiceReference1.Service1Client();
            serviceProxy.ClientCredentials.UserName.UserName = "test";
            serviceProxy.ClientCredentials.UserName.Password = "test123";

            PatientData objData = new PatientData();
            objData.Name = "test";
            objData.Gender = "Male";
            objData.Email = "v@g.com";
            objData.Age = 20;
            string message = serviceProxy.GetData(5);
            //Console.WriteLine(serviceProxy.UpdatePatientData(objData));


            Console.WriteLine(message);
            Console.ReadLine();
        }

有了这个配置:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_IService1">
                <security mode="TransportWithMessageCredential" />
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="https://union-pc58.union.com/Service1.svc"
            binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1"
            contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" />
    </client>
</system.serviceModel>

但是你可以看到我的用户名是test,密码是test123,但是当我在客户端更改我的密码时,一切正常并且数据再次返回?!!!为什么?

【问题讨论】:

    标签: c# web-services rest wcf


    【解决方案1】:

    如果用户名和密码在您的验证方法中不匹配,可能会引发异常:

    public override void Validate(string userName, string password)
    {
        try
        {
            if (userName == "test" && password == "test123")
            {
                Console.WriteLine("Authentic User");
            } else {
                throw new Exception();
            }
        }
        catch (Exception ex)
        {
            throw new FaultException("Unknown Username or Incorrect Password");
        }
    }
    

    或更简化:

    public override void Validate(string userName, string password)
    {   
        if (userName != "test" && password != "test123")
        {
            throw new FaultException("Unknown Username or Incorrect Password");     
        }
    }
    

    检查空值也很好:

    if (null == userName || null == password)
       {
           throw new ArgumentNullException();
       }
    

    【讨论】:

      猜你喜欢
      • 2013-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-15
      • 1970-01-01
      • 1970-01-01
      • 2012-04-29
      相关资源
      最近更新 更多