基于WCF自定义操作的身份验证

本文关键字:身份验证 操作 自定义 WCF 基于 | 更新日期: 2023-09-27 18:09:44

我正在尝试为WCF服务的内部/外部用户实现基于令牌的身份验证,基于他们从服务调用的方法。我已经尝试拦截传入的soap信封,并在全局中使用令牌提取信封中的操作调用。当调用完成时,它不会传递到服务中所请求的操作。是否有一种方法可以捕获传入的请求并在它到达所请求的调用之前进行一些身份验证?这是我当前的代码。

全球。asax

  protected void Application_AuthorizeRequest(object sender, EventArgs e)
    {
        bool authorized = false;
        bool soapRequestReceived = false;
        try
        {
            XmlDocument soapDocument = new XmlDocument();
            Stream receiveStream = HttpContext.Current.Request.InputStream;
            receiveStream.Position = 0;
            if (receiveStream.Length > 0)
            {
                soapRequestReceived = true;
                using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8))
                {
                    // Load into XML document
                    soapDocument.Load(readStream);
                    logger.Info("output of XML document received is " + readStream);
                }
                authorized = XMLSoapParser.ParseMethodNameAndToken(soapDocument);
                if (!authorized)
                {
                    throw new Exception("User not authorized!");
                }
            }
            return;
        }
        catch (Exception EX_NAME)
        {
            if (soapRequestReceived && !authorized)
            {
                throw new Exception("User not authorized!");
            }
            // eat it;
        }
    }
下面是XML解析器 的代码
    public static class XMLSoapParser
{
    public static bool ParseMethodNameAndToken(XmlDocument doc)
    {
        try
        {
            XmlElement rootElement = doc.DocumentElement;
            XmlNodeList nodes = rootElement.ChildNodes;
            string methodName = "";
            string token = "";
            for (int i = 0; i < nodes.Count; i++)
            {
                if (nodes.Item(i).Name.ToLower().Contains("body"))
                {
                    XmlNodeList bodyList = nodes.Item(i).ChildNodes;
                    for (int j = 0; j < bodyList.Count; j++)
                    {
                        if (bodyList.Item(j).Name.ToLower().Contains("tem:"))
                        {
                            methodName = bodyList.Item(j).Name.Substring(4);
                            Logger.Info("Method Name received! : " + methodName );
                            XmlNodeList methodNodeList = bodyList.Item(j).ChildNodes;
                            for (int k = 0; k < methodNodeList.Count; k++)
                            {
                                if (methodNodeList.Item(j).Name.ToLower().Contains("token"))
                                {
                                    token = methodNodeList.Item(j).InnerText;
                                    Logger.Info("Token received ! : " + token);
                                }
                            }
                        }
                    }
                }
            }
            var client = new AuthAdminClient("BasicHttpBinding_IAuthAdmin");
            var authorized = client.IsAuthorized(token, "Partners", methodName);
            return authorized;
        }
        catch (Exception exception)
        {
            Logger.Warn(
                string.Format(
                    "Execption encountered at XML Soap Parser with parameter {0} /r/n Exeception caught : {1} /r/n {2}",
                    doc.ToString(), exception.Message, exception.StackTrace));
            return false;
        }
    }
}

基于WCF自定义操作的身份验证

即使您的解决方案可以工作,我也不建议自己解析SOAP信封。

通常,您将从ClaimsAuthorizationManager派生并覆盖CheckAccess。第一个参数类型为AuthorizationContext,它具有Action属性,您可以从中获得所调用的方法。

CheckAccess返回false将阻止调用被分派到该方法。

编辑:要将其连接起来,您需要创建一个ServiceHost派生类并覆盖ApplyConfiguration方法。在此方法中,您将创建配置标识模型,如下所示:
var credentials = this.Description.Behaviors.Find<ServiceCredentials>();
var identityConfiguration = new IdentityConfiguration();
// configure IdentityConfiguration properties here
credentials.IdentityConfiguration = identityConfiguration;
credentials.UseIdentityConfiguration = true;
identityConfiguration.ClaimsAuthorizationManager = new MyClaimsAuthorizationManager();

这不是完整的代码,但应该给你足够的方向来找到一些完整的例子。在这里查看如何激活servicehost。