调用 Sitefinity WCF Web 服务时出现错误 401

Posted

技术标签:

【中文标题】调用 Sitefinity WCF Web 服务时出现错误 401【英文标题】:Error 401 When calling the Sitefinity WCF Web Services 【发布时间】:2015-11-11 04:51:26 【问题描述】:

我已经开始使用 Sitefinity 8.1 进行开发,我需要访问 Sitefinity 的 WCF Web 服务(例如 ~\Sitefinity\Services\Ecommerce\Catalog\ProductService.svc)

我尝试像访问任何其他 Web 服务一样访问它们,但我收到 401 错误。在网络和 Sitefinity 论坛上搜索后,我发现了一些东西。

    我需要在使用服务前进行身份验证 [1&2]

    基于声明的身份验证是默认身份验证

    用于认证的 url 是 /Sitefinity/Services/Security/Users.svc/authenticate [1 & 2]

    我还发现了 Ivan Dimitrov 提供的一个 sn-p,他在其中编写了身份验证代码 [3]

    Client Api 验证并允许对 Web 服务的请求是毫无价值的

    它需要一个 STS 来进行身份验证,它集成在我的 Sitefinity 安装中 [2] “您可能想知道这个 STS 在哪里。默认情况下,该逻辑集成在您的 Sitefinity 应用程序中,可以在 ~/Sitefinity/SWT 下找到。 ” [2]

    阅读此信息后,我修改了 Ivan Dimitrov [3] 提供的代码,并将调用编码为 ~\Sitefinity\Services\Ecommerce\Catalog\ProductService.svc。我得到了 401 错误。

'远程服务器返回错误:(401)未经授权'是错误凭据的结果,但是我使用客户端 Api 测试了相同的凭据,通过 SecurityManager 类,我得到了“UserLoggingReason.Succes”,所以凭据是正确的。

奇怪的事实是我没有任何 ~/Sitefinity/SWT 文件夹。这可能是我问题的根源吗?

我正在使用 ASP.NET MVC,并且正在执行来自 Web Api 控制器的请求。 这是改编后的代码:

public static bool AuthenticateRequest(string membershipProvider, string userName, string password, bool rememberMe, ApiController controller)


    var jsonData = String.Format(credentialsFormat, membershipProvider, userName, password, rememberMe.ToString().ToLower());
    var credentials = Encoding.UTF8.GetBytes(jsonData);
    string result = InvokeWebMethod(usersServiceUrl, authenticateMethod, "POST", credentials, controller);
    switch (result)
    
        case "0":
            return true;
        default:
            return false;
    



public static string InvokeWebMethod(string serviceUrl, string methodName, string httpMethod, byte[] data, ApiController controller)


    var request = (HttpWebRequest)WebRequest.Create(String.Concat(sitefinityHost, serviceUrl, methodName));
    request.Method = httpMethod;
    request.ContentType = "application/json";
    request.CookieContainer = new CookieContainer();

    if (cookies != null)
    
        foreach (Cookie cookie in cookies)
            if (!cookie.Expired)
                request.CookieContainer.Add(cookie);
    

    if (data != null)
    
        request.ContentLength = data.Length;
        using (var writer = request.GetRequestStream())
        
            writer.Write(data, 0, data.Length);
        
    


    using (var response = (HttpWebResponse)request.GetResponse()) //The error is here
    
        cookies = response.Cookies;
        using (var reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
        
              var cookie = new HttpCookie("customCookie", "cookieVal")
            
                Expires = DateTime.Now.AddDays(1),
                Domain = controller.Request.RequestUri.Host,
                Path = "/"
            ;
            HttpContext.Current.Response.SetCookie(cookie);

            return reader.ReadToEnd();
        
    

(我也将sitefinityHost更改为我的机器)

我的 6 个前提都是正确的还是发生了一些变化?

401 的原因可能是什么?

非常感谢,

参考文献(最相关的):

[1] 如何验证 (http://www.sitefinity.com/blogs/svetlayankova/posts/svetla-yankovas-blog/2011/11/01/getting_started_with_restful_services_in_sitefinity)

[2] 如何验证 (http://www.sitefinity.com/blogs/svetla-yankovas-blog/2013/01/02/working-with-restful-services-part-2-claims-authentication-and-designing-service-calls)

[3] 验证码 (http://www.sitefinity.com/developer-network/forums/general-discussions-/windows-authentication#1655610)

【问题讨论】:

【参考方案1】:

timw255 为 Sitefinity 编写了一个 REST 客户端。可在此处获得:https://github.com/timw255/timw255.Sitefinity.RestClient

下面的方法记录用户正在使用 RestSharp(非常有帮助的库)

 private void SignIn()
    
        RestRequest request = new RestRequest("Sitefinity/Authenticate", Method.GET);

        IRestResponse response = _restClient.Execute(request);

        switch (response.StatusCode)
        
            case HttpStatusCode.OK:
                request = new RestRequest("Sitefinity/Authenticate/SWT?realm=realm&redirect_uri=redirectUri&deflate=true", Method.POST);

                request.AddUrlSegment("realm", _baseUrl);
                request.AddUrlSegment("redirectUri", "/Sitefinity");

                request.AddParameter("wrap_name", _username, ParameterType.GetOrPost);
                request.AddParameter("wrap_password", _password, ParameterType.GetOrPost);
                request.AddParameter("sf_persistent", "true", ParameterType.GetOrPost);

                response = _restClient.Execute(request);

                switch (response.StatusCode)
                
                    case HttpStatusCode.OK:
                        if (response.ResponseUri.AbsolutePath == "/Sitefinity/SignOut/selflogout")
                        
                            SelfLogout();
                        
                        break;
                    case HttpStatusCode.Unauthorized:
                        throw new SitefinityException("Invalid username or password");
                    default:
                        break;
                
                break;
            case HttpStatusCode.Redirect:
                throw new NotImplementedException("External STS not supported");
            default:
                break;
        
    

文件: https://github.com/timw255/timw255.Sitefinity.RestClient/blob/master/timw255.Sitefinity.RestClient/SitefinityRestClient.cs

SWT 文件夹不是一个实际的文件系统文件夹,它是一个路由。

【讨论】:

以上是关于调用 Sitefinity WCF Web 服务时出现错误 401的主要内容,如果未能解决你的问题,请参考以下文章

从 wcf 服务调用第三方 Web 服务

在 Web 服务 WCF 中调用 Web 服务

调用 WCF Web 服务时出现错误的 Json 响应

Sitefinity调试时初始页面加载缓慢

WCF Web 服务调用的性能

无法从本地机器调用 WCF 服务