Question

We are trying to extract the number of unread emails from current users inbox in Exchange 2007 SP1.

Since we are using SharePoint 2013, we are using Claims authentication. The problem now is: How to get a valid Network Credential for the currently logged in SharePoint user?

If we hardcode username, password and domain it works like a charm:

var cred = new NetworkCredential(Settings.ExchangeTestUserName,
                                              Settings.ExchangeTestPassword,
                                              Settings.ExchangeTestDomain)

But I am not sure how to get this network credential from the SPUser. This was my approach:

IClaimsIdentity identity = (ClaimsIdentity)Thread.CurrentPrincipal.Identity;
string upn = identity.Claims.Where(c => c.ClaimType == ClaimTypes.Upn).First().Value;

if (String.IsNullOrEmpty(upn))
{
    throw new Exception("No UPN claim found");
}

WindowsIdentity windowsIdentity = null;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
     windowsIdentity = S4UClient.UpnLogon(upn);
});



using (WindowsImpersonationContext ctxt = windowsIdentity.Impersonate())
{
     var cred = CredentialCache.DefaultNetworkCredentials
}

the idea being to extract the UPN claim for the current user, an then (elevated) use Claims 2 Windows token service to get a Windows Identity. By impersonating then Windows Identity, we can then use DefaultNetworkCredentials.

But even if DefaultNetworkCredentials.ToString() yiels the correct login name for current user, a request to the ExchangeService fails with

401 unauthorized

Note that it is working for the same user when creating the NetworkCredential with login, password and domain.

How can we successfully do a requestion from a claims enabled environment to Exchange.asmx?

Was it helpful?

Solution

  • Just confirming, are you using Kerberos? Source: http://msdn.microsoft.com/en-us/library/hh231678.aspx

    Any service that relies on the Claims to Windows token service (C2WTS) must use Kerberos constrained delegation to allow C2WTS to use Kerberos protocol transition to translate claims into Windows credentials.

  • Did you set up the SPNs correctly? They should be like this:

    SharePoint Portal Application Pool account
    HTTP/webapplication
    HTTP/webapplicationFQDN
    HTTP/webapplicationFQDN:port
    
    C2WTS account
    HTTP/c2wts
    
  • Then set constrained delegation of the respective services both NetBIOS and FQDN: enter image description here

  • Then you need to have the c2wts service account and the web application pool account in the allowed callers list (defaults to WSS_WPG group) located C:\Program Files\Windows Identity Foundation\v3.5\c2wtshost.exe.config on each Sharepoint server

  • Then you need to do the following for the web server (all WFEs).

a) Add the service account to the local Administrators Groups.

b) In local security policy (secpol.msc) under user rights assignment give the service account the following permissions:

  1. i. Act as part of the operating system
  2. ii. Impersonate a client after authentication
  3. iii. Log on as a service

c) 1.Open the command-prompt window.

  1. Type: sc config c2wts depend= CryptSvc

OTHER TIPS

I've also been trying to run this to ground with similar results. My code is very similar to what you have above so maybe I am missing something as well, but what I have found out, is that the Claims to Windows Token Service (C2WTS) creates a windows token that is valid ONLY for that SharePoint box when using web services.

You might want to verify that the SPN and constrained delegation is setup correctly for the C2WTS service account.

EDIT:

More information on how to configure C2WTS with Kerberos Authentication: http://support.microsoft.com/kb/2722087

Basically, if you configure the C2WTS for kerberos auth, then it will generate valid kerberos tickets for the windows token. And then if you set your exchange web service to also allow kerberos authenticate, then the creds should be able to pass from your sharepoint box to the webservice. But the C2WTS only supports constrained delegation which means you have to specify in AD which services it is allowed to delegate credentials to.

You are doing it wrong. Always use one single account to query data from other systems. Give one account permission to all mail addresses, then check if the user you are going to query has any permissions or inbox on the exchange server. Maybe create a web services to be hosted on exchange server then use that to be accessed by only 1 account.

If its on premises which i assume it is, then use wcf certificate authentication for authentication to the webservices i just told you to create.

yes it sounds crazy but this is how a system architect would tackle this problem. Thank You.

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top