按方法参数改变 WCF 安全角色/声明

发布于 2024-10-25 22:10:40 字数 846 浏览 5 评论 0原文

我有一个实现 IAuthorizationPolicy 的类。我根据登录用户设置了一个自定义主体对象,该用户具有我的所有基本级别角色(我也使用声明完成了此操作)。现在我想根据作为消息参数传入的键值来更改特定主体所具有的角色。

我遇到的问题是无法在授权策略类中读取请求消息,因为我无权将消息写回请求上下文。我可以使用 CheckAccess 方法的重写在 ServiceAuthorizationManager 派生类中复制和读取消息。但是,我必须确保在执行此操作之前已调用 GetAuthorizationPolicies 方法。

我正在寻找有关如何根据消息是否包含特定参数来改变主体角色的建议。基本上,当 Evaluate 方法 id 调用策略时,我想做这样的事情:

string myObjectId = null;

if (!messageCopy.IsEmpty)
{
    System.Xml.XmlDictionaryReader xdr = messageCopy.GetReaderAtBodyContents();
    xdr.ReadToDecendant("objectId");
    if (xdr.Read())
    {
        myObjectId = xdr.ReadContentAsString();
    }
    xdr.Close();
}
messageCopy.Close();

ClaimSet claims = (myObjectId != null) ?
    MapClaims(identity, myObjectId) : MapClaims(identity);

DefaultPrincipal principal = new DefaultPrincipal(identity, claims);

I have a class that implements IAuthorizationPolicy. I set up a custom Principal object based on the logged in user which has all of my base level roles (I have also done this using claims). Now I would like to change the roles that a particular principal has depending on a key value passed in as a message parameter.

The problem I am having is that the request message cannot be read in the authorization policy class because I don't have access to write the message back to the request context. I can copy and read the message in a ServiceAuthorizationManager derived class using an override of the CheckAccess method. However, I have to ensure that the GetAuthorizationPolicies method has already been called prior to doing that.

I am looking for suggestions on how I can vary the roles on a principal, based on whether or not the message contains a particular parameter. Basically, when the Evaluate method id called on the policy I want to do something like this:

string myObjectId = null;

if (!messageCopy.IsEmpty)
{
    System.Xml.XmlDictionaryReader xdr = messageCopy.GetReaderAtBodyContents();
    xdr.ReadToDecendant("objectId");
    if (xdr.Read())
    {
        myObjectId = xdr.ReadContentAsString();
    }
    xdr.Close();
}
messageCopy.Close();

ClaimSet claims = (myObjectId != null) ?
    MapClaims(identity, myObjectId) : MapClaims(identity);

DefaultPrincipal principal = new DefaultPrincipal(identity, claims);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤蝉 2024-11-01 22:10:40

经过一整天的尝试失败后,我放弃了读取消息正文的尝试,并使用了一种更简单的方法,添加 SOAP 消息头。调用服务时,我现在执行以下操作:

using (new OperationContextScope((IContextChannel)myService)) {
    OperationContext.Current.OutgoingMessageHeaders.Add(
        MessageHeader.CreateHeader("objectId", "http://tempuri.org/", "object value"));
    myService.BeginMyOperation(parm, callback, state);
}

然后在我的服务授权策略的 Evaluate 方法中执行以下操作:

int index = OperationContext.Current.IncomingMessageHeaders.FindHeader(
    "objectId", "http://tempuri.org/");

string myObjectId = (index < 0) ? null : 
    OperationContext.Current.IncomingMessageHeaders.GetHeader<string>(index);

ClaimSet claims = (myObjectId != null) ?
    MapClaims(identity, myObjectId) : MapClaims(identity);

DefaultPrincipal principal = new DefaultPrincipal(identity, claims);

After an entire day of attempted failures, I gave up on trying to read the message body and used an easier method, adding a SOAP message header. When calling the service I now perform the following:

using (new OperationContextScope((IContextChannel)myService)) {
    OperationContext.Current.OutgoingMessageHeaders.Add(
        MessageHeader.CreateHeader("objectId", "http://tempuri.org/", "object value"));
    myService.BeginMyOperation(parm, callback, state);
}

Then in my service authorization policy's Evaluate method I do this:

int index = OperationContext.Current.IncomingMessageHeaders.FindHeader(
    "objectId", "http://tempuri.org/");

string myObjectId = (index < 0) ? null : 
    OperationContext.Current.IncomingMessageHeaders.GetHeader<string>(index);

ClaimSet claims = (myObjectId != null) ?
    MapClaims(identity, myObjectId) : MapClaims(identity);

DefaultPrincipal principal = new DefaultPrincipal(identity, claims);
尝蛊 2024-11-01 22:10:40

我在开发 WebAPI 安全性时遇到了同样的情况,我选择了下一个方法:

  • 接收参数的方法创建 AuthorizationContext,它将参数作为资源声明传递,
  • 然后我的自定义 ClaimsAuthorizationManager 可以从 AuthorizationContext.Resource 获取参数并从授权中使用它。

I run into the same situation while developing WebAPI security and I choosen the next approach:

  • Method that recieves argument creates AuthorizationContext where it passes the argument as Resource claim
  • My custom ClaimsAuthorizationManager then can get argument from AuthorizationContext.Resource and use it from authorization.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文