none
Provide static claim to read content stored in SharePoint Online from a public ASP.NET page

    Question

  • I am migrating a SharePoint 2007 solution to SharePoint Online (O365), and need to replicate a feature whereby some information provided in SharePoint is displayed on a public web page.  The information is a SharePoint Calendar.  Each time the public page is hit (20 times a week maybe) the public page uses a stored credential to read the date/time and title of the events only.  It is a quick way to check the calendar without being logged in and without showing more private details like location or body of the item. 

    I had created an ASPX page in SharePoint that renders the view I'd like, then in the public ASP.NET page used HttpWebRequest to read the page, supplying a Credential using a stored username/password.

    Again, for clarity, the user is not logged is, but sees a page with some basic facts from a SharePoint Online Calendar on an anonymous, non-SharePoint enabled, ASP.NET hosted page.  So I don't think this is actually an "app", nor can I use the SharePoint Client SDK. 

    The code to do this was simple but returns a 403 using the new SharePoint.  I am under the impression that this is due to SharePoint Online's reliance on Claims Based Authentication. 

            WebRequest myRq = HttpWebRequest.Create(url);

            myRq.Credentials = new NetworkCredential(myAcct, myPWD, myDomain);
            WebResponse myRsp = myRq.GetResponse();

    I need to know if there is a way to create and pass an appropriate claim using stored username password. 

    (Yes, I know that the password needs to be stored securely, I've simplified the code above for clarity.)

    -Frank Long

    Sunday, December 22, 2013 1:23 AM

Answers

  • And so after a bunch of research I've found at least one way to do this. 

    The solution does leverage the app for SharePoint model, but not a mainstream scenario.  The twist is that the code (which lives on a separate non-SharePoint host) needs to request an App-Only authentication token.   So rather than creating some dummy user and providing the username/password, we create an app with minimal permission, and request a token for that app using its ClientID/ClientSecret.

    I leveraged code from this sample: http://code.msdn.microsoft.com/office/SharePoint-2013-Make-app-28141ce6/

    The TokenHelper.cs class in that sample (included in several samples) has a method GetAppOnlyAccessToken which does the trick.  The three values are predictable and static for a given scenario, so they can be set in configuration. With the AccessToken returned you can use CSOM code to access the contents of that web.

    So by giving this app read only access to the calendar, the web page gets only the permissions it needs, and it can provide this limited view on the calendar (datetime/title/location) plus it has enough information to cobble together a direct link to the event.  Thus a person needing more info can drill down and if they are not logged in they'll be prompted to do so, and they don't have to find the event again after signing in.

    The web.config ends up having the ClientId and ClientSecret in appSettings for the app identity, and the project needs a few binary references added to the bin if your host doesn't have these in the GAC.  That in turn seems to require the App be set to Full trust, which GoDaddy allows.  So all is well. 

    Hope this helps you searcher, and happy coding!

    -Frank Long

    • Marked as answer by TrailBear1 Thursday, March 13, 2014 6:43 AM
    Thursday, March 13, 2014 6:43 AM

All replies

  • Looks like the 403 was a result of not setting the User Agent String.  So now the call redirects to the interactive login page.  

    This article: http://msdn.microsoft.com/en-us/library/hh147177(v=office.14).aspx  refers to a configuration on SharePoint online where the cookie is set to httponly.  

    So is all the information in my SharePoint online site locked up there and not programmatically accessible? 

    Monday, December 23, 2013 2:12 AM
  • SharePoint Online does not allow for deploying ASP.NET artifacts such as HTTP Handlers and building apps is the only approach to deploy custom solutions to Office 365. With this I guess you will need to revise the architecture of your solution based on the App model.

    w: http://blog.mastykarz.nl | t: @waldekm | c: http://mavention.codeplex.com | c: http://mavention.nl

    Friday, December 27, 2013 7:42 AM
  • Thanks for taking the time to review my post and offer your suggestion. 

    The ASP.NET code is deployed on another host, outside of the SharePoint environment entirely.  The goal is to have this page use cached credentials of some sort to access the Calendar and display basic details only. 

    So my most recent approach is to use a provider hosted app to read the list and write a plain XML file.  This page becomes a "Publish" step for the data, done by the person updating the calendar. 

    Then a different page on that same host, and here's the kicker - which is served up anonymously - can read the XML file and render something pretty.

    If I get that working I'm considering putting this publish code in a remote event handler for the list, but one step at a time. 

    Since the anonymous page really only gets ten or twenty hits a week I'd really rather have that anonymous page read the data in real time.  But I'm not seeing any mechanism to get authorized that doesn't involve a web page with two boxes and a button, meant for a human to interact with. 

    Thanks again for taking the time.

    -Frank Long

    Friday, December 27, 2013 9:46 AM
  • Respectfully, this doesn't address the question.  If in fact the app model is the solution, then an answer would have the form "using the app model, here's how you get a credential that the app can use without a user being present". 

    Sunday, December 29, 2013 1:03 PM
  • And so after a bunch of research I've found at least one way to do this. 

    The solution does leverage the app for SharePoint model, but not a mainstream scenario.  The twist is that the code (which lives on a separate non-SharePoint host) needs to request an App-Only authentication token.   So rather than creating some dummy user and providing the username/password, we create an app with minimal permission, and request a token for that app using its ClientID/ClientSecret.

    I leveraged code from this sample: http://code.msdn.microsoft.com/office/SharePoint-2013-Make-app-28141ce6/

    The TokenHelper.cs class in that sample (included in several samples) has a method GetAppOnlyAccessToken which does the trick.  The three values are predictable and static for a given scenario, so they can be set in configuration. With the AccessToken returned you can use CSOM code to access the contents of that web.

    So by giving this app read only access to the calendar, the web page gets only the permissions it needs, and it can provide this limited view on the calendar (datetime/title/location) plus it has enough information to cobble together a direct link to the event.  Thus a person needing more info can drill down and if they are not logged in they'll be prompted to do so, and they don't have to find the event again after signing in.

    The web.config ends up having the ClientId and ClientSecret in appSettings for the app identity, and the project needs a few binary references added to the bin if your host doesn't have these in the GAC.  That in turn seems to require the App be set to Full trust, which GoDaddy allows.  So all is well. 

    Hope this helps you searcher, and happy coding!

    -Frank Long

    • Marked as answer by TrailBear1 Thursday, March 13, 2014 6:43 AM
    Thursday, March 13, 2014 6:43 AM