Error 401 When calling the Sitefinity WCF Web Services
Hello Sitefinity Team,
I've Started Developing with Sitefinity 8.1 and I need to access to Your WCF Web Services (e.g. ~\Sitefinity\Services\Ecommerce\Catalog\ProductService.svc)
I've tryed to access them like any other Web Service, but I get a 401 error. After searching on the web and Sitefinity Forum I Found a couple of things.
1- I need to Authenticate Before I Use the Services [1& 2]
2- The Claim-Based Authentication is the default Authentication
3- The url used to authenticate is /Sitefinity/Services/Security/Users.svc/authenticate [1 & 2]
4- I also found a snippet provided by Ivan Dimitrov where he codes the authentication Code [3]
5 -Client Api it's worthless to authenticate and allow the request to web services
6- Its needed a STS to Authenticate and it is integrated in my Sitefinity Installation [2]
“You may be wondering where this STS is. By default the logic is integrated in your Sitefinity application and can be found under~/Sitefinity/SWT. ” [2]
After I Read this information I adapted the code provided by Ivan Dimitrov [3] and coded the Call to the ~\Sitefinity\Services\Ecommerce\Catalog\ProductService.svc. And I got 401 error.
'The remote server returned an error: (401) Unauthorized' is a result of wrong credentials, However I tested the same credentials with the Client Api, Through SecurityManager class and I get the “UserLoggingReason.Succes”, so the credentials are Correct.
The Strange fact is that I don't have any ~/Sitefinity/SWT folder. May that be the root of my problems?
I'm Using ASP.NET MVC, and I'm doing the request from a Web Api Controller.
And this is the adapted Code:
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())
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();
(I also Changed the sitefinityHost to my machine)
Are all of my 6 premises correct or something have changed?
What could be the cause of 401?
Thank you very much,
References :(The Most relevant)
[1] How to Authenticate
(www.sitefinity.com/.../getting_started_with_restful_services_in_sitefinity)
[2] How to Authenticate
(www.sitefinity.com/.../working-with-restful-services-part-2-claims-authentication-and-designing-service-calls)
[3] Authentication Code
(www.sitefinity.com/.../windows-authentication
Hi Again,
When i put the users.svc in the Sitefinity/Public folder I'm Able to Authenticate and I get the 0, 7 or 9 depending if I Succeed Authenticating, Fail Authentication or the user is already logged in. However this is not a solution because of security problems, but even after get authenticated I could not access to the service.
I Tried the same approach to ProductService.svc but I get This error instead:
" Telerik.Sitefinity was not granted ManageEcommerce in Backend for principals with IDs 00000000-0000-0000-0000-000000000000"
I read that Sitefinity/Services requires Administrator Role and Sitefinity/Public is for General Users. The strange thing here is that Test user is Admin and Backend user and can't access to a service in either
~\Sitefinity\Services\Ecommerce\Catalog\ProductService.svc
or
~\Sitefinity\Public\ProductService.svc
What could be Wrong?
Hi
You are correct in that you need to authenticate if you want to use the services under /sitefinity, including (/sitefinity/services). All routes that are under /sitefinity require backend user authentication. Some of them also require to have permissions over the content that you want to manage - this is why you might get Telerik.Sitefinity was not granted ManageEcommerce even if authenticated.
It depends from where you will authenticate and whether you can persist the cookies that will be sent with the response once you have authenticated and have accessed protected resource:
private
static
HttpStatusCode SignOut(NameValueCollection requestHeaders)
WebRequest wrGETURLSignOut = WebRequest.Create(
"http://localhost/Sitefinity/SignOut"
); // pass the url
as
parameter or
set
it outside
wrGETURLSignOut.Headers.Add(requestHeaders);
var resp = wrGETURLSignOut.GetResponse();
var code = ((System.Net.HttpWebResponse)(resp)).StatusCode;
return
code;
private
static
NameValueCollection SignIn(
string
username,
string
password)
string
sURL;
sURL =
"http://localhost/Sitefinity/Authenticate/SWT"
; // pass the url
as
parameter or
set
it outside
var formData = String.Format(
"wrap_name=0&wrap_password=1"
, username, password);
var bytes = Encoding.UTF8.GetBytes(formData);
WebRequest wrGETURL;
wrGETURL = WebRequest.Create(sURL);
wrGETURL.Method =
"POST"
;
wrGETURL.ContentType =
"application/x-www-form-urlencoded"
;
wrGETURL.ContentLength = bytes.Length;
Stream dataStream = wrGETURL.GetRequestStream();
dataStream.Write(bytes, 0, bytes.Length);
dataStream.Close();
Stream objStream = wrGETURL.GetResponse().GetResponseStream();
StreamReader objReader =
new
StreamReader(objStream);
var token = objReader.ReadToEnd();
var nameValueColl = HttpUtility.ParseQueryString(token);
var bootstrapToken = nameValueColl[
"wrap_access_token"
];
var expiresOn = DateTime.Now + TimeSpan.FromSeconds(
int
.Parse(nameValueColl[
"wrap_access_token_expires_in"
]));
var requestHeaders =
new
NameValueCollection();
requestHeaders[
"Authorization"
] = String.Format(
"WRAP access_token=\"0\""
, bootstrapToken);
return
requestHeaders;
var testUrl =
"http://localhost/sitefinity/pages"
;
var requestHeaders = SignIn(
"admin"
,
"password"
);
WebRequest protectedRequest = CreateRequest(testUrl, requestHeaders);
WebResponse response =
null
;
try
response = protectedRequest.GetResponse();
catch
(WebException ex)
if
(ex.Status == WebExceptionStatus.ProtocolError)
var statusCode = SignOut(requestHeaders);
if
(statusCode == HttpStatusCode.OK)
var newRequestHeaders = SignIn(
"admin"
,
"password"
);
requestHeaders = newRequestHeaders;
WebRequest protectedRequest2 = CreateRequest(testUrl, newRequestHeaders);
response = protectedRequest2.GetResponse();
//process response
...
// call other service /or same again
WebRequest protectedRequest3 = CreateRequest(testUrl, requestHeaders);
var response3 = protectedRequest3.GetResponse();
//process response
...
SignOut(requestHeaders);
public
static
WebRequest CreateRequest(
string
url, NameValueCollection requestHeaders)
WebRequest wrGETURLProtected2 = WebRequest.Create(url);
wrGETURLProtected2.ContentType =
"application/json"
;
wrGETURLProtected2.Headers.Add(requestHeaders);
return
wrGETURLProtected2;