[E2013/Exchange-Online] [EWSMA] [C#] [Win7/Win Server 2007/2010] OAuth authentication for Exchange 2013 and Exchange Online
I'm trying to use OAuth with EWS MA to authenticate against Exchange Server 2013 or Exchange Online. EWS Provides an assembly (Microsoft.Exchange.WebServices.Auth.Validation) which does token validation as follows:
string token = "..."; // where do I get this? new AppIdentityToken().Validate(token);
What I'm wondering is where I obtain this token from. It isn't mentioned in the documentation for the assembly. Can I obtain it using WIF, or do I need to write custom code to get it? Do I need to have an Azure, Office, or Sharepoint app registered to get the token or can I register a client ID and secret somewhere else (assuming I need one at all).
Thanks in advance,
- Edited by Matthew Visser Thursday, February 21, 2013 3:30 PM
Every Partner you want to use for authentication (either to generate the Token on or use the Exchange Token against) needs to configured see http://technet.microsoft.com/en-us/library/jj655399.aspx which details how to do this for SharePoint 2013.
The validation library is when you want to validate the Token you obtained in Exchange in your own WebService, eg when you have a MailApp that is going to make a request to your own webservice and you need to validate the user. So you grab the Token in your Mail Apps send it to your WebService then use the Microsoft.Exchange.WebServices.Auth.Validation library in your webservice to validate it.
You can generate a Token using EWS but you must first have a Mail Apps setup and enabled because you need to use the Mail Apps Id in the GetClientAccessToken request eg
KeyValuePair<String, Microsoft.Exchange.WebServices.Data.ClientAccessTokenType> kvType = new KeyValuePair<string, Microsoft.Exchange.WebServices.Data.ClientAccessTokenType>("d5429927-5822-4126-8159-07b06d84ae6a", Microsoft.Exchange.WebServices.Data.ClientAccessTokenType.CallerIdentity); List<KeyValuePair<String, Microsoft.Exchange.WebServices.Data.ClientAccessTokenType>> tknreq = new List<KeyValuePair<string, Microsoft.Exchange.WebServices.Data.ClientAccessTokenType>>(); tknreq.Add(kvType); ServiceResponseCollection<GetClientAccessTokenResponse> TokenResponse = service.GetClientAccessToken(tknreq);Glen
Thanks for the response, Glen.
Does the partner application that we create need to be a sharepoint or mail application, or could it be any web application? Does it allower access to any user or require more configuration?
I have realized that my original question didn't make it clear what I was looking for. I'm trying to use a traditional OAuth 2 experience to gain access to resources through EWS against Exchange Online or Exchange 2013. Is this type of workflow possible as well?
No your partner application can be anything the implement STS auth, and you configure that app with the New-PartnerApplication cmdlet http://technet.microsoft.com/en-us/library/jj215772(v=exchg.150).aspx . If your using it this way you making a claim on a Security context of a Mailbox. (But I've only used it with Sharepoint and lync 2013 tokens).
The current version of Exchange Online is Exchange 2010 so wont support tokens the preview version is 2013 and should support tokens but I'm not sure about 3rd party STS partners.
I am looking for a code sample on how to authenticate with my Office365 oauth token against the Exchange 2013 online service (EWS). There does not seem to be any code sample around for this (it is quite new i guess..); can you give my some pointers for this? I figure i should use the "Microsoft.Exchange.WebServices.Auth.Validation" ddl with the SharePoint app's tokenhelper.cs; but some sample would be great.
Basically i want to display simple mailbox information in a SharePoint App (new messages, etc.) for the currently logged in user.
You only need the Auth.Validation library if your validating a token (eg you have your own application/service that has implemented STS Authentication and your using this to check if this is a valid token for the user where the token was generated on a Exchange server).
I can't help with the sharepoint side on getting the correct token (try the sharepoint forum). Once you have the token it pretty easy to use eg here's a sample of reusing and Token generated from and Office Apps
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013); service.TraceEnabled = true; KeyValuePair<String, Microsoft.Exchange.WebServices.Data.ClientAccessTokenType> kvType = new KeyValuePair<string, Microsoft.Exchange.WebServices.Data.ClientAccessTokenType>("d5429927-5822-4126-8159-07b06d84ae6a", Microsoft.Exchange.WebServices.Data.ClientAccessTokenType.ExtensionCallback); List<KeyValuePair<String, Microsoft.Exchange.WebServices.Data.ClientAccessTokenType>> tknreq = new List<KeyValuePair<string, Microsoft.Exchange.WebServices.Data.ClientAccessTokenType>>(); tknreq.Add(kvType); ServiceResponseCollection<GetClientAccessTokenResponse> TokenResponse = service.GetClientAccessToken(tknreq); OAuthCredentials oaCred = new OAuthCredentials(TokenResponse.TokenValue); service.Credentials = oaCred;
(Its just the standard Bearer header etc)
Both of your samples for calling GetClientAccessToken resulting in
"The token for this extension could not be retrieved." on my Office365 account where calling getUserIdentityTokenAsync from an Outlook mail application returns a valid token.
Could you give me please a hint how to retrieve the token from EWS using managed api ?
Where in the docs are the parameters described for GetClientAccessToken ?
Thx and regards
- Edited by Torsten KuhnMicrosoft employee Friday, April 19, 2013 6:09 AM
Ok I found the answer here http://msdn.microsoft.com/en-us/library/exchange/jj900496(v=exchg.150).aspx
var kvType = new KeyValuePair<string, Microsoft.Exchange.WebServices.Data.ClientAccessTokenType>("7730559e-ed42-4024-aad3-4b0bf5912430", ClientAccessTokenType.CallerIdentity);
where the GUID is my Application Id (from the app manifest).
But this means that only deployed mail apps could call this API or is there a Special GUID for non registered applications ? I want to use GetClientAccessToken from an Azure Website.
Hello, have you been succeeded with your development? I am experiencing similar problems. I want to authenticate SharePoint Current user to EWS for sending appointments on behalf of this user. If I am trying to set OAuth Credentials and then Autodiscover Serivce URL - the Exception saying, that OAuth call needs Service URL is thrown. When I am trying to Autodiscover Service URL before getting OAuth Credentials - another one saying, that Autodiscover needs Credentials is thrown.. So sad, so confusing.
If you had resolved your problem, it could help me too.
Thanks in advance - Grzegorz.
EWS and Autodiscover are seperate applications on the server and AFAIK oauth isn't supported in AutoDiscover.
If you using ExchangeOnline you don't really need to use Autodiscover as there is now a unified URL https://outlook.office365.com/ews/exchange.asmx for EWS requests through the loadbalender see http://blogs.msdn.com/b/mstehle/archive/2013/04/17/changes-in-managing-affinity-for-ews-subscriptions.aspx
By the Autodiscover i meant
But if i don't need it, a good news, thank you. Another problem is with trying to get ClientAccessToken, when calling:
it says, that the service needs Credentials:
Credentials are required to make a service request. at Microsoft.Exchange.WebServices.Data.ExchangeServiceBase.PrepareHttpWebRequestForUrl(Uri url, Boolean acceptGzipEncoding, Boolean allowAutoRedirect) at Microsoft.Exchange.WebServices.Data.ExchangeService.PrepareHttpWebRequest(String methodName) at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.BuildEwsHttpWebRequest() at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.ValidateAndEmitRequest(IEwsHttpWebRequest& request) at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.Execute() at Microsoft.Exchange.WebServices.Data.ExchangeService.InternalCreateItems(IEnumerable`1 items, FolderId parentFolderId, Nullable`1 messageDisposition, Nullable`1 sendInvitationsMode, ServiceErrorHandling errorHandling) at Microsoft.Exchange.WebServices.Data.Item.InternalCreate(FolderId parentFolderId, Nullable`1 messageDisposition, Nullable`1 sendInvitationsMode) at Microsoft.Exchange.WebServices.Data.Appointment.Save(SendInvitationsMode sendInvitationsMode) at Solution.Models.Helpers.ExchangeHelper.SendInvitations(String author, Event ev)
Do you have any ideas with that?
Greets from far Poland,
- Edited by Grz_ Tuesday, April 30, 2013 7:42 AM
All this does is makes a call to the Autodiscover service, it doesn't make any request to EWS and hence will fail if you don't use credentials.
>> But if i don't need it, a good news, thank you. Another problem is with trying to get ClientAccessToken, when calling:
Why are trying to use GetClientAccessToken ?? this is used to generate a Token that you can use with in either Exchange, SharePoint or Link based on the credentials your using, hence you would always need credentials to call it.
If you have Token from SharePoint already you don't need to call this just use the Token you already have via the OAuthCredentials Class.
I would suggest that you enable tracing http://msdn.microsoft.com/en-us/library/exchange/dd633676%28v=exchg.80%29.aspx. That will allow you to see if the token is actually being sent (eg you should see the Bearer header with the Token in the Traces). That error sounds like the Token isn't being sent or your trying to access a Mailbox that the user associated with the token doesn't have access to.
I am trying to achieve the same thing ... have you managed to find a solution in the meantime? Or maybe an alternative / official answer on this topic? The documentation on how to do this seems very scarce...
MCTS, MCPD SharePoint 2010. My blog - http://radutut.wordpress.com/