我已经开始使用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提供的摘要,他在其中对身份验证代码进行了编码[3]
  • Client Api进行身份验证并允许对Web服务的请求是毫无值(value)的
  • 它需要一个STS进行身份验证,并且已集成到我的Sitefinity安装中[2]
    “您可能想知道这个STS在哪里。默认情况下,该逻辑集成在您的Sitefinity应用程序中,可以在〜/Sitefinity/SWT下找到。 ” [2]

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

  • “远程服务器返回错误:(401)未经授权”是由于凭据错误导致的,但是,我通过SecurityManager类使用Client Api测试了相同的凭据,并获得了“UserLoggingReason.Succes”,因此凭据是正确的。

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

    我正在使用ASP.NET MVC,并且正在从Web Api Controller 发出请求。
    这是经过改编的代码:


    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)

    最佳答案

    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文件夹不是实际的文件系统文件夹,而是一条路由。

    关于c# - 调用Sitefinity WCF Web服务时出现错误401,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32069231/

    10-10 09:33