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

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

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

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

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

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

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

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

  6. 它需要一个 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)

【问题讨论】:

    标签: c# .net wcf sitefinity


    【解决方案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 文件夹不是一个实际的文件系统文件夹,它是一个路由。

    【讨论】:

      猜你喜欢
      • 2021-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-03
      • 1970-01-01
      • 2015-12-29
      • 2015-08-24
      • 1970-01-01
      相关资源
      最近更新 更多