Aug 24 2016 02:48 PM
I'm trying to follow the instructions on https://github.com/OfficeDev/PnP/tree/master/Samples/Core.CloudServices in order to set up a web service than can talk to an Office 365 tenant.
I'm trying to follow the instructions there, but I am using Visual Studio 2015 and the instructions seem to be only partially updated for 2015. Either that or I don't have a Visual Studio component set up correctly. Specifically, I get to the step where it says to click on the "Convert to App for SharePoint Project" sub-menu item of the "Convert" menu item in the context menu on the web role project. However, I don't have a "Convert" menu item.
Is this something that changed in VS2015 or am I missing a VS2015 component? If it's changed in VS2015, what's the new way to do this? @VesaJuvonen, you made the last updates to the Readme 17 days ago. Can you please tell me what I am doing wrong?
Thanks!
Aug 25 2016 06:39 AM
This is an old sample created back in the days when Azure Web Apps and Web Jobs were not yet well developed and broadly used. Nowadays I would recommend using Azure Web Apps instead of a web role and Azure Web Jobs instead of worker roles...when you do there's no additional plumbing you need to do to make it work with Azure.
Aug 26 2016 06:52 AM
Like Bert mentioned, we do recommend using WebJobs or WebAPIs / web services to talk to Office 365 nowadays. You do not need to go through this level of setup due these enhanced capabilities in Azure. If you are just trying to have a web service, whcih talks to Azure, you can simply implement it for example as a WebAPI, whcih then uses app-only permissions to gain access to SharePoint.
Happy to provided additional details, if you specificy the needed scenario.
Aug 31 2016 03:18 PM
Sep 01 2016 05:35 AM
You can for example follow the guidance from PnP Partner Pack (starter kit for partners) at https://github.com/OfficeDev/PnP-Partner-Pack/blob/master/Documentation/Manual-Setup-Guide.md for enabling app-only with Azure. You'll need to do few steps, but the PnP Partner Pack documentation is great step-by-step process on doing required steps.
Sep 01 2016 01:41 PM
Vesa,
Thank you. I followed the Partner Pack instructions at https://github.com/OfficeDev/PnP-Partner-Pack/blob/master/Documentation/Manual-Setup-Guide.md. There were a few things I ran into:
Hope that helps other people.
Now I still have to write the code that gets the token and uses it to talks to the O365 APIs that I am interested in.
@VesaJuvonen wrote:You can for example follow the guidance from PnP Partner Pack (starter kit for partners) at https://github.com/OfficeDev/PnP-Partner-Pack/blob/master/Documentation/Manual-Setup-Guide.md for enabling app-only with Azure. You'll need to do few steps, but the PnP Partner Pack documentation is great step-by-step process on doing required steps.
Sep 02 2016 07:24 AM
Hi Michael,
If your main interest is understanding how to authenticate using "app-only" with Azure AD then I would recommend checking this web cast: https://channel9.msdn.com/blogs/OfficeDevPnP/PnP-Web-Cast-Introduction-to-Authentication-Manager-in-....
The PnP core library has classes that make it easy to do what you want.
Sep 02 2016 09:04 PM
Bert,
Thank you! That video helped a lot. After watching that, I figured out that once I added the SharePointPnPCoreOnline nuget package to my web service, I could use AuthenticationManager.GetAzureADAppOnlyAuthenticatedContext(...) to get a ClientContext.
A question about that method. I uploaded the certificate to the web service by adding it to the SSL section of its configuration web page in Azure (in the new portal). To reference that certificate, since I don't know what the file path is, I can reference it from the certificate store, right? So my call looks like GetAzureADAppOnlyAuthenticatedContext(
urlToTeamSite, ClientID,
"mytenant.onmicrosoft.com", StoreName.My, StoreLocation.LocalMachine, PfxThumb);. Is the Certificate store name and location the correct enum values?
Also, is the siteURL, the URL of a specific team site, or the site collection's root site? In other words, is it https://tenant.sharepoint.com/sites/sitecollectionrootsite, or can it be https://tenant.sharepoint.com/sites/sitecollectionrootsite/subsiteX/subsiteY?
Thanks,
Michael
Sep 02 2016 09:27 PM
I've got another question about using App-only authentication with Azure AD. Using GetAzureADAppOnlyAuthenticatedContext() is great for getting a ClientContext, but a ClientContext only helps me with using SharePoint CSOM. In the particular web service I am writing, it recieves the messageID of an email that is in Exchange Online. I want to get the subject and attachment from that email message (and then store it in SharePoint). I believe I can get the email details and content using the Graph REST API, but I need to send a bearer token in the Authorization header in the HTTP request when I do that. Can the AuthenticationManager help me with that? If not, what's the right way to get that? Is lines 43-48 of https://github.com/richdizz/MyO365BackgroundProcess/blob/master/MyO365BackgroundProcess/Program.cs a good example to follow?
Thanks,
Michael
Sep 04 2016 11:16 PM
Hi Michael,
You create a clientcontext for the site you need, if that's a sub site you want to work against then you should create the clientcontext using the sub site url.
Regarding the certificate: it's up your implementation to handle this, storing it in the local machine certificate store is definitely a valid option.
Sep 04 2016 11:21 PM
Hi Michael,
Once you've a clientcontext object you can always grab the bearer token using the ExecutingWebRequest handler on the ClientContext object
private void Cc_ExecutingWebRequest(object sender, WebRequestEventArgs e) { // Capture the OAuth access token since we want to reuse that one in our REST requests this.accessToken = e.WebRequestExecutor.RequestHeaders.Get("Authorization").Replace("Bearer ", ""); }
Sep 06 2016 11:47 AM
Here's my code to create the ClientContext:
ClientContext cc = AM.GetAzureADAppOnlyAuthenticatedContext( "http://psclistens1.sharepoint.com/sites/something/n2s/MailTest", ClientID, "psclistens1.onmicrosoft.com", StoreName.My, StoreLocation.LocalMachine, PfxThumb);
When it runs, I get the error:
"Could not load type 'Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate' from assembly 'Microsoft.IdentityModel.Clients.ActiveDirectory, Version=3.13.4.878, Culture=neutral, PublicKeyToken=31bf3856ad364e35'."
Any suggestions on troubleshooting this? I know my team site url is correct. The Client ID matches what is registered in AAD. Should the tenant ID be something.onmicrosoft.com or something.sharepoint.com or a GUID? The thumbprint matches what is listed under SSL in the App Service in Azure.
Thanks,
Michael
Sep 06 2016 01:53 PM
Correction to my source code above - the site URL should start with HTTPS.
Realizing that I am running this locally initially, I did try the the other method signature:
ClientContext cc = AM.GetAzureADAppOnlyAuthenticatedContext(spWebUrl, ClientID, O365Tenant, @"C:\Users\mblumenthal\patha\pathb\etc...\Certificate\PSCGroupLLC.pfx", certPassword);
I get the same error.
Sep 07 2016 11:27 AM
Can you try to downgrade the Microsoft.IdentityModel.Clients.ActiveDirectory package to a version 2.x version? Assuming your using the latest version 3.x right now...if not then we'll need to search further.
Sep 08 2016 09:23 AM
That's correct, I have v 3.13.4 of Microsoft.IdentityModel.Clients.ActiveDirectory currently. I will change it over to v2.28.1, since that it the newest of the 2.x choices.
Sep 15 2016 02:57 PM
Downgrading that Nuget package to the highest 2.x patch level, v2.28.1, worked. Now I can get a client context, use it to get the title property of a SPO web, and grab the auth token from the client context. I use that auth token to create a graphClient. However, when try to use the graphClient, I get a Microsoft.Graph.ServiceException. I'm struggling with how to troubleshoot that.
if (this.accessToken != string.Empty) { GraphServiceClient graphClient = new GraphServiceClient( "https://graph.microsoft.com/v1.0", new DelegateAuthenticationProvider( async (requestMessage) => { requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken); })); var currentgraphObject = await graphClient.Organization.Request().GetAsync(); string orgName = currentgraphObject.ToString(); if (orgName != null) { Debug.WriteLine("Got org: " + orgName); } }
In the code above, it fails on the line:
var currentgraphObject = await graphClient.Organization.Request().GetAsync();
I've also tried the following line instead resulting in the same error.
var mailbox = await graphClient.Users["SpecificAccount@psclistens.com"].Request().GetAsync();
Any advice on troubleshooting this would be appreciated.
Thanks,
Michael