none
userPrincipalName element generated in client config RRS feed

  • Question

  • If I generate a client config file using svcutil the <endpoint> element contains an <identity> element, which in turns contains a <userPrincipalName> element that contains a 'value' attribute set to the user who started the service (service was started as a Console app for testing). However, these elements are not specified in the services config file. e.g. for a basic example:

    Server definition:
    <endpoint
       
    address="net.tcp://localhost:8000/Anite/TestService"
       
    binding="netTcpBinding"
       
    contract="Anite.ITestService"/>

    Clients generated config:
    <endpoint
       
    address="net.tcp://localhost:8000/Anite/TestService"
       
    binding="netTcpBinding" bindingConfiguration="NetTcpBinding_ITestService"
       
    contract="ITestService" name="NetTcpBinding_ITestService">
        <
    identity>
            <
    userPrincipalName value="user@myaddress.com"
    />
        </
    identity
    >
    </
    endpoint>

    The problem is that only "user@myaddress.com" can call the service when using this client config unless the <identity> element is removed.

    Does anyone know why this is being added, and is there any way to prevent it being added, or get it to be set to a value that doesn't specify a single user when the code is generated by svcutil?

    Cheers
    Ant

    Tuesday, May 16, 2006 3:50 PM

Answers


  • By default, when a service is configured to use Windows credentials, an <identity> and <userPrincipalName> element is generated in the WSDL document produced the by Service Model Metadata Utility Tool (Svcutil.exe). If the service is running under the LocalSystem. LocalService, or NetworkService account, a Service Principal Name (SPN) will be generated in the form of host/<hostname> because those accounts have access to the computer's SPN data. If the service is running under a different account, WCF generates a Principal Name (UPN) in the form of <username>@<domainName>. This occurs because Kerberos authentication requires a UPN or SPN to be supplied to the client to authenticate the service.

    This behavior does not occur if you set the Identity of the service endpoint in either code or configuration. You can also use the SetSpn.exe (http://www.microsoft.com/windows2000/techinfo/reskit/tools/existing/setspn-o.asp) tool register an additional SPN with a service's account in a domain. The SPN can then be used as the Identity of the service.
    Tuesday, May 16, 2006 4:39 PM

All replies


  • By default, when a service is configured to use Windows credentials, an <identity> and <userPrincipalName> element is generated in the WSDL document produced the by Service Model Metadata Utility Tool (Svcutil.exe). If the service is running under the LocalSystem. LocalService, or NetworkService account, a Service Principal Name (SPN) will be generated in the form of host/<hostname> because those accounts have access to the computer's SPN data. If the service is running under a different account, WCF generates a Principal Name (UPN) in the form of <username>@<domainName>. This occurs because Kerberos authentication requires a UPN or SPN to be supplied to the client to authenticate the service.

    This behavior does not occur if you set the Identity of the service endpoint in either code or configuration. You can also use the SetSpn.exe (http://www.microsoft.com/windows2000/techinfo/reskit/tools/existing/setspn-o.asp) tool register an additional SPN with a service's account in a domain. The SPN can then be used as the Identity of the service.
    Tuesday, May 16, 2006 4:39 PM
  • Thanks for your reply. I'm not sure if I fully understand it as I'm still not getting it to work properly. This is what I've done and perhaps you could point out where I've gone wrong:

    1. In the services config I added a <servicePrincipalName> element, e.g. from previous example:
       
    <endpoint
           
    address="net.tcp://localhost:8000/Anite/TestService"
            binding="netTcpBinding"
            contract="Anite.ITestService">
            <identity>
                <
    servicePrincipalName value=""/>
           
    </identity>

    2. At this point I wasn't sure what to set the value attribute to. I used setspn.exe to try to register a new SPN, without success! I tried:

        (a) setspn -A myspn myserver (for myspn I just used the name of my service)
    and
        (b) setspn -A myspn/clientPCname mydomain\myusername (as I would be running the service for the moment)

    Both of these resulted in a "Failed to assign SPN on account..." error. As a test, though, I listed the SPNs for the host I was testing the client on and used one of these as the value in the server config. After I regenerated the client config this worked on the client PC whatever username I was logged on as. Of course it didn't work from another PC that didn't have the same SPN registered.

    What I'm not sure about is:

    1. Should I be registering the same SPN with all the client machines with I want to use, as I could only add one <servicePrincipalName value=""/> to the server config?
    2. Was I running setspn incorrectly or is this a priviledge issue (I've got local admin on the machine I was trying the register the SPN on)?

    Something I'd noticed earlier was that if I removed the <identity> element from the client config (when it wasn't set in the server config) this worked fine if the client and server where on the same PC, but not if they were on different PCs. However, if in the client config I use the IP address of the server machine instead of it's network name (in the address attribute of the endpoint element) and remove the identity element, I can call the server from any PC with any logon! What's going on here? Does this mean authentication is being bypassed?

    Cheers
    Ant

    Thursday, May 18, 2006 3:20 PM
  • SetSpn to add a new spn must be run by someone with Domain Admin privilages.  The SPN is registered at the domain level because the KDC (Key Distribution Center) must be able to authenticate it. 

    By default you will have a Host/machine SPN which will work if the service is running as NetworkService or System (which is why this should work if it's hosted in IIS).  However, since you're running a self-hosted service running as a different account, this won't work.

    So, the kerberos client needs to know who it's talking to in order for it to get an appropriate ticket from the KDC.  Since you don't have a valid SPN for your service, you need to ask the KDC for a ticket to authenticate against a UPN (User Principal Name) instead. 

    Please see these for further info:

    http://msdn2.microsoft.com/en-US/library/ms178119.aspx

    http://www.microsoft.com/technet/prodtechnol/windows2000serv/maintain/security/kerberos.mspx

     

    Locally the client will use NTLM to authenticate so no identity is necessary.

    Remotely it will try to use kerberos using the UPN or SPN.  If that fails, then it will use NTLM.  If there is no identity then it will just fail.

    So in a nutshell for your scenario....

    You can ask your domain admin to create an SPN that identifies your service running as a specific account and use that... or a much easier solution would be to use a UserPrincipalName instead.

    As far as the ip address scenario is concerned, it's probably using NTLM and not Kerberos.

    Hope that helps!

    Thanks!

    Scott

     

     

    Friday, May 19, 2006 11:29 PM
  • If you set WCF Service Address with IP,you do not need to set userPrincipalName  in client.

    I do not know why,and I will do more research on it.

    any suggestions or tips on it will be appreciated.

     

    Thanks.

    I got a error of Windows Athentication,

    http://www.frankxulei.com/?p=495

    The kerberos client received a KRB_AP_ERR_MODIFIED error from the server esbservice.  The target name used was host/gmc0101.ci.org. This indicates that the password used to encrypt the kerberos service ticket is different than that on the target server. Commonly, this is due to identically named  machine accounts in the target realm (CI.ORG), and the client realm.   Please contact your system administrator.

    I fixed it with adding userPrincipalName


    Frank Xu Lei--谦卑若愚,好学若饥
    专注于.NET平台下分布式应用系统开发和企业应用系统集成
    Focus on Distributed Applications Development and EAI based on .NET
     

    老徐的网站】:http://www.frankxulei.com/

    老徐的博客】:http://www.cnblogs.com/frank_xl/

    微软WCF中文技术论坛
    微软WCF英文技术论坛

    Monday, August 16, 2010 7:53 AM