locked
Windows Store app with enterpriseAuthentication and Impersonation RRS feed

  • Question

  • Short Version: Why when I impersonate a web-request made by Windows Store app, I get WindowsIdentity object with correct user name, but its IsAuthenticated property returns False? Making same request from a browser (including Metro IE10) gives IsAuthenticated==true.

    Long Version:
    I'm prototyping a line-of-business solution, which consists of WCF-service and WinJS application. WCF-service is based on the webHttpBinding (i.e. simple GET/POST requests).

    Certain actions need to be processed on behalf of a user making request, therefore service is configured to impersonate its callers. Here is sample configuration:

        <system.serviceModel>
          <bindings>
            <webHttpBinding>
              <binding name="CustomizedWebBinding">
                <security mode="TransportCredentialOnly">
                  <transport clientCredentialType="Windows" />
                </security>
              </binding>
            </webHttpBinding>
          </bindings>
            <behaviors>
              <endpointBehaviors>
                <behavior name="Web">
                  <webHttp/>
                </behavior>
              </endpointBehaviors>
                <serviceBehaviors>
                    <behavior name="">
                        <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                        <serviceDebug includeExceptionDetailInFaults="false" />
                    </behavior>
                </serviceBehaviors>
            </behaviors>
            <services>
                <service name="WcfService">
                    <endpoint address="" binding="webHttpBinding" bindingConfiguration="CustomizedWebBinding" contract="IWcfService" behaviorConfiguration="Web">
                        <identity>
                            <dns value="localhost" />
                        </identity>
                    </endpoint>
                    <host>
                        <baseAddresses>
                            <add baseAddress="http://localhost:8787/" />
                        </baseAddresses>
                    </host>
                </service>
            </services>
        </system.serviceModel>

    ... and code:

        public class WcfService : IWcfService
        {
            [OperationBehavior(Impersonation=ImpersonationOption.Required)]
            public UserInfo GetUserInfo()
            {
                UserInfo ui = new UserInfo();
                WindowsIdentity identity = ServiceSecurityContext.Current.WindowsIdentity;
    
                ui.UserName = identity.Name;
                ui.IsAuthenticated = identity.IsAuthenticated;
                ui.ImpersonationLevel = identity.ImpersonationLevel.ToString();
                ui.IsAnonymous = identity.IsAnonymous;
                ui.IsGuest = identity.IsGuest;
                ui.IsSystem = identity.IsSystem;
                ui.AuthenticationType = identity.AuthenticationType;
    
                return ui;
            }
        }

    So, this operation simply collects information about the caller and sends it back in a json string.

    Moving to the client. To enable automatic authentication I checked "Enterprise Authentication", "Internet (Client)" and "Private Networks" in the Windows Store app's manifest file.

    From within Windows Store app, I send request using WinJS.xhr function:

            var options = {
                url: "http://localhost:8787/getuserinfo"
            };
    
            WinJS.xhr(options).then(function (xhrResponse) {
                var userInfoBlock = document.getElementById("userInfoBlock");
                var data = JSON.parse(xhrResponse.response);
    
                userInfoBlock.innerHTML += "<ul>"
    
                for (var p in data) {
                    if (data.hasOwnProperty(p)) {
                        userInfoBlock.innerHTML += "<li>" + p + ": " + data[p] + "</li>";
                    }
                }
    
                userInfoBlock.innerHTML += "</ul>";
            });

    Now, when I execute Windows Store app and it sends request, the response I get is:


        AuthenticationType: "NTLM"
        ImpersonationLevel: "Impersonation"
        IsAnonymous: false
        IsAuthenticated: false
        IsGuest: false
        IsSystem: false
        UserName: "TESTBOX\dev"

    If I send request using browser's address bar, I get same response, with the only difference that "IsAuthenticated: true".

    I also noticed that if I disable "Enterprise Authentication", it causes Credentials Picker to popup and after providing correct credentials I'm getting "IsAuthenticated: true".

    Am I missing something or expecting too much from the enterpriseAuthentication capability?


    • Edited by AndreyR1231 Sunday, December 2, 2012 3:47 PM
    Sunday, December 2, 2012 12:44 PM

Answers

  • Thanks for your followup AndrevR1231,

    Yeah, hosting on localhost for windows store app is prohibited for production deployment. Also it works for development time, the behavior might be different. And my previous test is also using a remote webservice hosted on a remote IIS server.


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Song Tian Friday, December 7, 2012 8:44 AM
    Thursday, December 6, 2012 2:16 AM
    Moderator

All replies

  • Hi AndreyR1231,

    As for windows store app, if the client machine is windows domain joined and the following capabilities are enabled, the windows store app should be able to supply the default windows credentials to server for authenticaton.

    "Enterprise authentication", "privateNetworkClientServer"

    To verify that the windows auth does happened correctlyl, you can open the IIS log file of the IIS web site which hosts your WCF service and find the request records of your windows store app client. The IIS log should have recorded all the details such as status code, request url, client authenticated user name (if authenticated)... And for a browser or windows store app client which use xhr to access the windows authentication protected service, the expected records are:

    One initial request with 401 response code (since no authentication credential supplied)
    Followed by several authenticated requests which has 200 status code and authenticated username associated

    #IIS logging for Windows Integrated authentication
    http://support.microsoft.com/kb/969060

    In addition, since your WCF service is a REST service (use WebHttpBinding), you can also turn on AspNetCompatiblity mode and use HttpContext.Current.User.Identity (which also contains properties IsAuthenticated, AuthenticationType...) to verify if a valid windows authentication identity is attached to the request context.


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, December 4, 2012 4:00 AM
    Moderator
  • Hi Steven,

    Thank you for your reply.

    I haven't mentioned (sorry about that), but WCF service is hosted in Windows Service. Anyway, I decided to check how things would change if I were using an IIS-based hosting. The main difference was in that my Windows Store app asked for credentials all the time (while IE did not). As I described in my first post, I can achieve same behavior by simply not using enterpriseAuthentication capability at all. So this is not what I wanted. (I tried various IIS and service settings - nothing helped.)

    What actually helped is putting WCF Service and Windows Store app on different machines - no popups and successful authentication with impersonation. I know localhost is prohibited in Windows Store apps, but thought it can be used in development environment without any restrictions. Turns out that's not exactly so.

    Wednesday, December 5, 2012 9:17 PM
  • Thanks for your followup AndrevR1231,

    Yeah, hosting on localhost for windows store app is prohibited for production deployment. Also it works for development time, the behavior might be different. And my previous test is also using a remote webservice hosted on a remote IIS server.


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Song Tian Friday, December 7, 2012 8:44 AM
    Thursday, December 6, 2012 2:16 AM
    Moderator