2

I have an unattended, scheduled batch process -- written in C# -- that needs to access data in a list in SharePoint Online. It will make an HTTP call to the REST API from a completely external environment.

What's the best way to manage authentication/access?

I can (and have for testing) just hard-coded a username and password, using the SharePointOnlineCredentials class. This works fine, but it's clearly not ideal, as you have the credentials for a user sitting in code or configuration. Call this "the nuclear option."

What I'd like is to be able to generate an access token for that specific list or an access token for an "API user" which I could pass with the request.

I could make a user specifically to be used by this process, but that seems like overkill, since they'd be a full Office 365 user, and I'd be paying for a full user to do this one thing.

Besides authenticating as a full-blown user, what other options exist for this access?

1

Access is licensename/password.. whatever what method, they need to be used at one point.

If you are worried about a "nuclear option" I would worry more about Users (who have the password stored in the Browser) loosing their device.

A System account runs on a server (with another licensename/password) so at least has two levels of authentication.

Most tight option is to pay for that license, give the account minimal access to SharePoint to only drop-off data.
Then run a workflow which processes data.

You could built all sorts of tokens and handshakes

But as I said, your Human Users should be you first prioirty

Admininstrators are an even worse liability.. they are as Human as other Humans but their accounts give access to loads more.

And You ofcourse force everyone to change their password every 3 weeks

1

Use a service account, a dedicated user account for automation purposes. If the account does not need a mailbox or other O365 features, this account does not need an O365 license. Put the creds in the app config or web config of the calling application. Make sure the creds do not end up in source control.

As an alternative you could use app-only policy in conjunction with an app, but now you've traded the username/password for a client ID/secret, so it doesn't really solve the problem of leaving the keys to the kingdom used in your code.

1

For thos who wants to go with the app-only policy way.

You can register your app as Provider hosted Add-in with App-only policy. Only necessary scope of permissions for the app (it can be for example only one list) can be set. In this case you don't have to pay separate license for some "service account".

The app needs to know two information:

  • Client Id (some guid)
  • Client Secret (some base64 string)

Almost all SharePoint provider hosted examples operates with web application but it can be also some exe application.

  1. Create Add-in project as this example says
  2. Copy SharePointContext.cs and TokenHelper.cs to your app project
  3. Create helper method for getting ClientContext without username and password

    public static ClientContext GetClientContextForApp(string siteUrl)
    {
        Uri url = new Uri(siteUrl);
        string realm = TokenHelper.GetRealmFromTargetUrl(url);
        string accessToken = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, url.Authority, realm).AccessToken;
    
        return TokenHelper.GetClientContextWithAccessToken(url.ToString(), accessToken);
    }
    
  4. Open AppManifest.xml and on Permissions tab. Enable App-only and set required scope of permissions. Then open this file in code view and save somewhere the AppPermissionRequests element.

    <AppPermissionRequests AllowAppOnlyPolicy="true">
        <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web/list" Right="Write" />
    </AppPermissionRequests>
    
  5. Open App registration page https://tenant.sharepoint.com/_layouts/15/appregnew.aspx

  6. Generate some Client Id and Client Secret and save it somewhere, you will need it! Also fill Title, App domain and Redirect URI which are not interesting in this case.
  7. Open Grant Permissions page https://tenant.sharepoint.com/_layouts/15/appinv.aspx
  8. Find the app by Client Id and to field Permission Request XML paste AppPermissionRequests element from AppManifest.xml
  9. Click Create and it will ask you to which list you want the app has access.
  10. Last step is to save Client Id and Client Secret to appconfig. The TokenHelper.cs will automatically pick this information for you from appSettings.

After all these steps you don't need the add-in project anymore and is save to delete it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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