【问题标题】:Transfer WCF custom authentication session to service将 WCF 自定义身份验证会话传输到服务
【发布时间】:2011-06-03 15:05:34
【问题描述】:

我有使用 UserNamePasswordValidator 进行自定义授权的 WCF 网络服务

public class CustomUserNameValidator : UserNamePasswordValidator
    {
    public override void Validate(string userName, string password)
        {
        try
            {
            MySession session = new MySession(userName, password);
            }
        catch (UnauthorizedAccessException e)
            {
            throw new System.IdentityModel.Tokens.SecurityTokenException("Incorrect username or password");
            }
        }
    }

身份验证工作正常,但我不知道如何将在 CustomUserNameValidator 中创建的会话传输到服务。

如果您想知道的话,MySession 来自第三方 API。

【问题讨论】:

    标签: wcf authentication


    【解决方案1】:

    我假设您的第三方库实际上不是为 WCF 构建的,您需要实现 WCF 授权/身份验证位?

    你有没有研究过这样的事情:

    http://www.leastprivilege.com/CustomPrincipalsAndWCF.aspx

    你可以设置 Thread.CurrentPrincipal 吗?

    【讨论】:

    • 是的,第三方不是为 WCF 构建的。目前正在研究基于自定义 IAuthorizationPolicy 的解决方案。有一件事是肯定的 - UserNamePasswordValidator 是创建我的会话的坏地方。仍在寻找好的解决方案。
    • “MySession”代表什么?我以为是身份信息。
    • MySession 是来自第三方 API 的一个类,它使用用户名和密码进行初始化,以后可用于检索数据。自然,我不想为每次调用我的服务创建两个 MySession 对象。
    • 你能创建一个自定义的 IPrincipal 并将该对象嵌入其中吗?然后您可以稍后通过 (Thread.CurrentPrincipal as MyCustomPrincipal).MySession 检索它 - 您可能希望将其包装到 MySession 上的静态方法中 - MySession.GetCurrent()
    【解决方案2】:

    在对我的网络服务进行了几次迭代之后,我对我的问题得出了一个可以接受的答案。如果有人输入,我会立即接受的答案。

    不要使用 UserNamePasswordValidator。将您的服务配置为使用传输安全性,并将 clientCredentialType 设置为“None”。在 Web 服务方法中,首先要做的是使用从 WebOperationContext.Current 中提取的凭据创建一个会话,例如:

        WebOperationContext operationContext = WebOperationContext.Current;
        string encoded = operationContext.IncomingRequest.Headers[HttpRequestHeader.Authorization];
    
        if (encoded != null)
        {
            var decoded = Convert.FromBase64String(encoded.Substring(encoded.LastIndexOf("Basic ") + 6));
            var headerValue = Encoding.UTF8.GetString(decoded);
    
            string userName = headerValue.Substring(0, headerValue.IndexOf(":"));
            string password = headerValue.Substring(headerValue.IndexOf(":") + 1, headerValue.Length - userName.Length - 1);
    
            if (ValidCredentials(userName, password)
               return new MySession(userName, password);
        }
    
        operationContext.OutgoingResponse.Headers.Add(HttpResponseHeader.WwwAuthenticate,
                String.Format("Basic realm =\"MyRealm\"", Settings.EBCommunity));
        throw new WebFaultException(HttpStatusCode.Unauthorized);
    

    这样,Web 服务可以轻松自托管或托管在 IIS 上,并且避免了UserNamePasswordValidator http protocol issue

    【讨论】:

    • 我相信静态变量不会帮助你。它们将是应用程序范围的,并且在整个应用程序池的长度内都存在。此外,我相信 HttpContext 仅适用于 ASP.NET 兼容模式......也许你想要,也许你不想要。消息检查器将帮助您拦截输入(包括 un/pw),但不会像您现在所拥有的那样直接帮助您解决从服务代码访问该信息的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 2011-06-24
    • 1970-01-01
    相关资源
    最近更新 更多