如何使用System.ServiceModel.ServiceAuthenticationManager自定义WCF身份验证?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (35)

我正在处理自定义WCF身份验证和授权,并发现了一些关于UserNamePasswordValidatorServiceAuthorizationManager的文章。

我还发现了使用自定义System.ServiceModel的线索ServiceAuthenticationManager死链接 ),但msdn不会告诉它很多(http://msdn.microsoft.com/en-us/library/system.servicemodel.serviceauthenticationmanager.aspx)。

所以我在这里:任何人都知道更多关于ServiceAuthenticationManager?

一般来说,你将如何设置自定义WCF身份验证?

提问于
用户回答回答于

你是对的,关于这个文件根本没有帮助。

我使用这门课的方式如下。重写Authenticate()方法以:

  1. 从收到的消息中提取认证令牌(例如用户名/密码)
  2. 验证令牌并使用它们来创建IPrincipal对象。这将是调用服务操作期间使用的主体。
  3. 将IPrincipal对象添加到message.Properties集合中,以便稍后可以在WCF处理管道中使用它

因为WCF稍后会更改它,所以不能只设置线程主体。

ServiceAuthenticationManager.Authenticate()方法中的代码如下所示:

public override ReadOnlyCollection<IAuthorizationPolicy> Authenticate(ReadOnlyCollection<IAuthorizationPolicy> authPolicy, Uri listenUri, ref Message message)
{
   int tokenPosition = message.Headers.FindHeader("Token", "http://customnamespace.org");
   string token = message.Headers.GetHeader<string>(tokenPosition);

   IPrincipal user = new CustomPrincipal(token);

   message.Properties["Principal"] = user;

   return authPolicy;
}

然后您添加一个自定义授权策略

  1. 从消息中检索IPrincipal(使用System.ServiceModel.EvaluationContext.Current.IncomingMessageProperties集合)。
  2. 将IPrincipal推入EvaluationContext.Properties集合
  3. 根据IPrincipal.IsInRole()方法进行声明

IAuthorizationPolicy()方法中的代码看起来像

public bool Evaluate(EvaluationContext evaluationContext, ref object state)
{
    IPrincipal user = OperationContext.Current.IncomingMessageProperties["Principal"] as IPrincipal;
    evaluationContext.Properties["Principal"] = user;
    evaluationContext.Properties["Identities"] = new List<IIdentity> { user.Identity };

    IList<Claim> roleClaims = this.GetRoleClaims(user);

    evaluationContext.AddClaimSet(this, new DefaultClaimSet(this.Issuer, roleClaims));

    return true;
}

在服务行为配置中,需要设置principalPermissionMode =“Custom”,以便WCF将IPrincipal设置为实际服务操作调用的执行线程上的主体。

<serviceAuthorization principalPermissionMode="Custom"...

扫码关注云+社区