>我创建了一个具有自定义身份验证和授权的简单 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
,但是当我在客户端更改密码时,一切正常,数据再次返回?!!!为什么?
如果用户名和密码在您的验证方法中不匹配,可能会引发异常:
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();
}