+1-888-365-2779
Try Now
More in this section

Forums / Developing with Sitefinity / [SF 5.0] Consuming WCF REST services from an external .NET app

[SF 5.0] Consuming WCF REST services from an external .NET app

7 posts, 0 answered
  1. Yann
    Yann avatar
    19 posts
    Registered:
    24 Jun 2010
    15 Mar 2012
    Link to this post
    Hi,

    I am trying to consume the WCF rest services exposed by Sitefinity 5.0.

    I understand that in order to access the services, I need to to first get authenticated by calling  users.svc?AuthenticateUser and that will return the cookie I need to call other services such as getting News items.
    Is that part right or has it changed in SF 5 ?

    I have referenced the Telerik.Sitefinity.dll assembly and tried to call the service :
    var usersService = new WebChannelFactory<IUsers>("UserServiceEndpoint");
    var usersChannel = usersService.CreateChannel();
    var auth = usersChannel.AuthenticateUser(new Telerik.Sitefinity.Security.Credentials() { UserName = "admin", Password = "[PASSWORD HERE]", Persistent = true });
      The config file contains:
    <system.serviceModel>
       <extensions>
         <behaviorExtensions>
           <add name="PersistantCookieBehavior" type="Tests.PersistantCookieBehaviorExtensionElement, Tests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
         </behaviorExtensions>
       </extensions>
       <behaviors>
         <endpointBehaviors>
           <behavior name="CookieBehaviorConfig">
             <PersistantCookieBehavior />
           </behavior>
         </endpointBehaviors>
       </behaviors>
     
       <bindings>
         <webHttpBinding>
           <binding name="PagesServiceBinding" maxReceivedMessageSize="1024000000" />
         </webHttpBinding>
       </bindings>
     
       <client>
         <endpoint name="UserServiceEndpoint"
                   address="http://MySFSite/sitefinity/services/security/Users.svc/"
                   binding="webHttpBinding"
                   behaviorConfiguration="CookieBehaviorConfig"
                   contract="Telerik.Sitefinity.Security.Web.Services.IUsers" />
       </client>
     </system.serviceModel>
    However, when the service is called I get the exception:
    The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'WRAP realm="http://MySFSite/", issuer="http://MySFSite/Sitefinity/Authenticate/SWT"'

    I don't understand why AuthenticateUser method doesn't allow Anonymous Access if that is what needs to be used to get the authentication cookie.

    Thank you to help me figure this out.
  2. Tim
    Tim avatar
    258 posts
    Registered:
    22 Jun 2011
    15 Mar 2012
    Link to this post
    Yann,

    From past experience, I found that I always had you use this JSON when authenticating to Sitefinity:

    {"MembershipProvider":"","Password":"yourpassword","Persistent":true,"UserName":"youruser"}
  3. Yann
    Yann avatar
    19 posts
    Registered:
    24 Jun 2010
    16 Mar 2012
    Link to this post
    Hi Tim,

    I thought it would be handling XML as well.
    Anyway, I modified my binding behavior to use JSON instead of XML.

    The request being sent seems correct:
    {"MembershipProvider":null,"Password":"MyPassword","Persistent":true,"UserName":"MyUsername"}

    I still receive a 401 

    The error message is:
    The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'WRAP realm="http://sf_fiig/", issuer="http://sf_fiig/Sitefinity/Authenticate/SWT"

    It seems to me that the user/authenticate resource is not accessible to Anonymous and that defeats the reason I am calling this resource...

    And I am not sure I can authenticate my .NET app against claimed-based security when using WebHttpBinding...


  4. Tim
    Tim avatar
    258 posts
    Registered:
    22 Jun 2011
    16 Mar 2012
    Link to this post
    Yann,

    Can you double check that your IIS setup matches the recommended configuration? Depending on what kind of authentication you want to use, you have to configure it a little differently.
  5. Yann
    Yann avatar
    19 posts
    Registered:
    24 Jun 2010
    19 Mar 2012
    Link to this post
    I have double checked the IIS settings and they match the recommendations.

    FYI, I can only access the services from the browser ( ie .../Users.svc/authenticate ) if I am logged in. 

    The 401 seems to come from the ProtectedRoute  route. 
    Unless the svc is located in the Public service folder, it will fail.
    I also noticed that there is a bug and the route doesn't ignore the casing for the public service path
    ( ie Sitefinity/Public/Services/ECommerce/Order/CartOrder.svc/ will work but not  Sitefinity/public/Services/ECommerce/Order/CartOrder.svc ).

    I am still looking for an acceptable solution as moving users.svc to the public folder will make all the operations accessible.

  6. Yann
    Yann avatar
    19 posts
    Registered:
    24 Jun 2010
    19 Mar 2012
    Link to this post
    I copied the users.svc file to the Public folder to access the authenticate operation.
    However, even if i copy the received cookie to call another service such as News.svc, I keep receiving a 401 error.
    I can't think of a way to access the web services using claims based authentication ( which is the default authentication method in SF 5).

    I switched to Forms based authentication and i can access the services normally. ( every service is available but most need a cookie that is retrieved through a call to users/authenticate).

    Can you say it so if it is not possible to access the services through an external app with Claims Based Authentication ?
    If this can be done, please provide a working example. 
  7. Yann
    Yann avatar
    19 posts
    Registered:
    24 Jun 2010
    27 Mar 2012
    Link to this post
    More news on this.

    I managed to access the REST services using claims based authentication (sort of)

    In order to do this, I created a POST HttpRequest where I provide the username and password, basically replicating the request to Sitefinity/Authenticate/SWT happening in the browser on the login page.

    When doing that i receive the wrap_access_token and I can pass that one to the service call.
    It happens to work when sent through the 
    Authentication header as long as the following string is added wrap access_token=  before the actual token.
    Notice that there is no underscore between wrap and access and I think this is a bug.

    I added the authentication header on my wcf call using a message inspector. 
    I am not an expert on security and maybe there is a more elegant way to do all this using Microsoft Identity Model. If someone has any thoughts on how to do it, I am all ears.

    Now, it still doesn't work great. Not sure to understand the reason, but Sitefinity SecurityManager won't authenticate the user if this one has not been explicitely logged out before. 
    Instead of returning Success, it is considered already Logged In.
    This behavior is frequently seen on the browser where we receive a message saying that the user is already logged in on another computer and asking if we want to continue.
    Well, first, the message is misleading because it happens all the time even from the same computer.
    Supposing this behavior makes sense on the browser ( I am yet to be convinced), how can we get past this when calling the services from an external app ?

    I'd rather not have my application sending a new web request to tell SItefinity to logout the user so i can access my services. That would be a waste of resource. 

    Unfortunately, this is what i end up doing :( . When a call to a web service returns a 403 (yes, when the user is already logged in, then we get a 403. I find it confusing because I can't tell if that's because the user is already logged in or because the user doesn't have the proper permissions), then i send a web request to 
    Sitefinity/SignOut/selflogout and retry.

    I would like to see a blog from you guys at Telerik that explains the use of Claims based authentication in Sitefinity in more details.
    In the meantime, can I get a reply to the parts in bold ?

    Thanks.

    Yann


    
    

7 posts, 0 answered