4

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?

2
  • what version of exchange are you running?
    – Mike
    Sep 22, 2014 at 14:42
  • 2
    Exchange 2007 it says in quest Sep 22, 2014 at 14:45

3 Answers 3

6
  • 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
4
  • Today we are using "normal" claims, no Kerberos. But I'm more and more getting the picture that you need to use Kerberos to be able to do this kind of "double hop" authentication? Sep 22, 2014 at 18:21
  • 2
    Yes. Kerberos is a token that you can pass as many hops down multiple and different systems. Windows Auth and FBA is a challenge system, so you get a token after successful login for each challenge. You need Kerberos for this operation.
    – Mike
    Sep 22, 2014 at 19:10
  • See my edit. I've linked a reference that says Kerberos contrained delegation with protocol transition is required for c2wts
    – Mike
    Sep 22, 2014 at 19:16
  • Thanks for the details! I'll try to get a good grip on this tomorrow (it's been a while since I configured Kerberos, but I remember it to more than difficult!) Sep 22, 2014 at 19:27
2

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.

4
  • It is a bit sad that it is so hard to get these microsoft products together (if only the client had Exchange in the cloud!). Can you tell me a bit more about your last sentence, I'm not able to fully follow it Sep 22, 2014 at 13:55
  • 1
    Updated answer with more information. Sep 22, 2014 at 14:11
  • Today we are using "normal" claims, no Kerberos. But I'm more and more getting the picture that you need to use Kerberos to be able to do this kind of "double hop" authentication? Sep 22, 2014 at 18:22
  • Well, i don't think you need to change your sharepoint authentication model, I think you just need to change what type of tokens the c2wts can create. I could be wrong but I don't think it is dependent on the settings in the SharePoint web app. Sep 22, 2014 at 18:46
-1

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.

4
  • 2
    Where this would be an easy way to do this, I don't agree with this method, at least an end-result solution
    – Mike
    Sep 22, 2014 at 17:51
  • 2
    That is my fallback method but, as Mike said, to me that is a more dirty solution since it is not fully dependent on the current users permissions Sep 22, 2014 at 18:20
  • I disagree, why we use secure store service in SharePoint to access third party data ? why we do not give each user permission to access sql database but just 1 or 2 for read and write ? just because an api is available to you doesn't mean you should give permission to everyone to access it, your webservice should only allow specific users and not be accessible by everyone. what permissions are you talking about when it comes to access user mail box. Your approach is against system architecture rules, i am not surprised why people think sharepoint developers are bad when it comes to architect Sep 23, 2014 at 6:23
  • Well in this particular use case, each user already do have access to their emails. But sure, if you have a system where the users do not have access your approach is probably preferable Sep 23, 2014 at 11:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.