gpt4 book ai didi

c# - 如何在 ServiceAuthorizationManager 中设置身份/用户名?

转载 作者:太空狗 更新时间:2023-10-30 01:09:16 27 4
gpt4 key购买 nike

我在服务器端(托管在 IIS 中)和 Android 客户端上有一个 WCF 4.0 REST 服务。 Android 客户端在自定义 HTTP header 中发送加密的安全 token ,以对用户进行身份验证。我已经实现了一个自定义 ServiceAuthorizationManager,它从 header 中提取安全 token 。 token 包含我可以从 token 中读取的用户名:

public class MyAuthorizationManager : ServiceAuthorizationManager
{
protected override bool CheckAccessCore(OperationContext operationContext)
{
var requestMessage = operationContext.RequestContext.RequestMessage;
var requestProperty = (HttpRequestMessageProperty)requestMessage
.Properties[HttpRequestMessageProperty.Name];
var token = requestProperty.Headers["X-MyCustomHeader"];
if (!string.IsNullOrEmpty(token))
{
var userName = GetUserNameFromToken(token);
if (!string.IsNullOrEmpty(userName))
{
// How to save userName now so that I can
// retrieve it in the service operations?
return true;
}
}
return false;
}
}

现在,我的问题是在各种服务操作(主要是访问用户配置文件数据)中我还需要经过身份验证的用户的名称,我正计划以这种方式检索它:

public void MyServiceOperation()
{
string userName = OperationContext.Current
.ServiceSecurityContext.PrimaryIdentity.Name;

// check profile store for that userName and do something depending on
// profile settings
}

如何在 CheckAccessCore 中设置此用户名?

像这样一个非常天真的试验......

operationContext.ServiceSecurityContext.PrimaryIdentity.Name = userName;

...不起作用,因为 PrimaryIdentity.Name 是只读的。我假设需要更复杂的代码。

最佳答案

经过一些研究,我没有找到在 ServiceAuthorizationManager.CheckAccessCore 中设置身份的方法。当用户身份已设置(可能为“匿名”(IsAuthenticatedfalse))且无法再更改时,此方法似乎在处理管道中被调用得太迟. ServiceAuthorizationManager 用于授权,而不是身份验证,因此它不是实现自定义身份验证的错误位置。

我终于找到了三种可能的方法来解决我的问题:

  1. 如@TheCodeKing 的回答中链接的文章中所述,使用 WCF REST 初学者工具包提供了编写自定义 RequestInterceptor 的选项,它足够早地挂接到管道中,允许访问传入请求并允许根据自定义 HTTP header 等设置用户身份。不幸的是,WCF REST Starter Kit 很旧(基于 WCF 3.5)并且开发显然已被放弃。它的一些特性已经被合并到 WCF 4.0 中,但有些还没有,RequestInterceptor 就是其中之一。尽管如此,我现在已经使用了这个解决方案并将初学者工具包中的 Microsoft.ServiceModel.Web 程序集混合到我的 WCF 4.0 解决方案中。经过一些简单的测试,它似乎到目前为止有效。

  2. 如果身份不是真正必需的,而只是用户名,那么将用户名写入新请求 header 的简单“技巧”/“hack”就可以了(也在 CheckAccessCore 中) ):

    // ...
    var userName = GetUserNameFromToken(token);
    if (!string.IsNullOrEmpty(userName))
    {
    requestProperty.Headers["X-UserName"] = userName;
    return true;
    }
    // ...

    然后在服务方法中:

    public void MyServiceOperation()
    {
    string userName = WebOperationContext.Current.IncomingRequest
    .Headers["X-UserName"];
    // ...
    }
  3. 另一个更底层的选项是编写一个自定义 HttpModule,它拦截传入的请求并设置身份。这看起来像的一个例子是 here来自 Microsoft Pattern & Practices 团队(参见文章中间的“HTTP 模块代码”示例)。

关于c# - 如何在 ServiceAuthorizationManager 中设置身份/用户名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7299922/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com