将 WCF 自定义身份验证会话传递到服务

5
我有一个使用UserNamePasswordValidator进行自定义授权的WCF Web服务。
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。

2个回答

2

是的,第三方并不适用于WCF。目前正在寻找基于自定义IAuthorizationPolicy的解决方案。有一件事是确定的 - UserNamePasswordValidator不适合创建我的会话。仍在寻找一个好的解决方案。 - Juozas Kontvainis
"MySession" 代表什么?我认为它是身份信息。 - Steve
MySession是第三方API中的一个类,它通过用户名和密码进行初始化,然后可以用于检索数据。自然地,我不想为每个对我的服务的调用创建两个MySession对象。 - Juozas Kontvainis
你能创建一个自定义的IPrincipal对象并将其嵌入其中吗?然后,您可以通过(Thread.CurrentPrincipal as MyCustomPrincipal).MySession检索它 - 您可能希望将其封装在MySession的静态方法中 - MySession.GetCurrent()。 - Steve

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协议问题


我认为静态变量对你没有帮助。它们将是应用程序范围内的,并且将在整个应用程序池的生命周期内存在。此外,HttpContext我认为仅在ASP.NET兼容模式下可用...也许你想要,也许你不想要。消息检查器将帮助您拦截输入(包括用户名/密码),但不会直接帮助解决从服务代码获取该信息的问题,就像现在所拥有的一样。 - Steve

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接