Office 365 OAuth Authorization flow for Nextcloud

So, I read this one Office 365, Azure AD SSO? and this one Enable SSO with OAuth 2 (for Azure AD and Google Apps) and I also think that OAuth authentication via Office 365 / Azure AD could come in very handy. In easy words: I want users to be able to create an account and log-in to Nextcloud with their Office 365 account.

Since I’ve implemented the Authorization flow (https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-code) in a node js application a while ago, I’d like to take a shot at creating an app for that.

The flow can be described like this:

  1. There is a button on the login page to log-in via Office 365 (I’ll try to make it pretty, Jan :slight_smile: )
  2. When clicked, the user gets redirected to example.org/nextcloud/login/office365
  3. The code behind this route redirects to the auth-endpoint of Office 365, specifying a callback URL
  4. If the user is already logged-in to Office 365, they are redirected to the callback URL immediately, if not, they see the Office 365 login and are redirected afterwards
  5. On the callback URL we need to do the following:
    5.1 Decode the user information in form of a json-web-token (easy)
    5.2 Make sure the user information we got is complete (easy)
    5.3 Verify the user information jwt was signed with an official Azure AD X509 Certificate – we’ll also implement certificate rollover, because we want to cache the certificate, but it can change every x months. (difficult & difficult)
    5.4 Find out if the user’s domain is in the list of allowed log-in domains (easy)
    5.5 Find out if the user (by email) is already in the Nextcloud database. (medium)
    5.6 If already there:
    5.6.1 Log-in without asking for password (difficult – for me at least)
    5.6.2 Fetch an API token from the correct endpoint with our login-token (easy)
    5.6.3 Fetch display name and profile picture from Azure AD, in case they have changed, with API token. (easy)
    5.7 If no user like this exists:
    5.7.1 Create a new user (difficult – for me again)
    5.7.2 Continue with 5.6.1

We’ll need a configuration interface for following information:

  • clientID specified in Azure AD
  • clientSecret specified in Azure AD
  • Display callback URL to be set in Azure AD
  • resource to request in AzureAD (this will default to https://outlook.office.com/)
  • tenant in Azure AD

From my previous experience with Nextcloud app development I work on the following points:


My questions follow on the spot:

  • How can I “override” login and safely log-in a user when the callback was hit with a valid response?
  • Who can help me figure out this cryptography fun, we need to deal with, getting the signing certificate from an XML-file to some readable format (pem?) for the jwt library (see https://login.microsoftonline.com/designit.com/FederationMetadata/2007-06/FederationMetadata.xml)
  • Who can point me to right places, so that I don’t need to read all of the code of the SAML app before I can start?

Any help is appreciated :slight_smile: :slight_smile:

Cheers,
Thomas

I got a notification since you mentioned me :slight_smile:

I think what you’re suggesting above is only part of the story. The point of relying on Azure AD (or Google Apps, or any other directory) is that it should completely replace the account system of Nextcloud. That is: we should not use the AAD account to sign in into an existing account in the Nextcloud database. Instead, users should be able to carry their identity, and the Nextcloud user repository would be the AAD directory.

So, I’d say your points 5.5, 5.6 and 5.7 aren’t really necessary: once the user has authenticated via AAD and all points up to 5.4 are valid, then he or she should have a valid session inside Nextcloud.

The next step would be implementing a system that calls the Azure AD APIs every time you need to get, say, a list of users, etc.

This is essentially the same thing that happens when using LDAP with Nextcloud, for example: it’s not only used for authentication, but also as a directory.

Idea: the entire Nextcloud auth backend could be rewritten to always rely on OpenID for authentication. So, all local users would be exposed via OpenID only, and authentication mechanisms would become pluggable :slight_smile: But that’s not an insignificant amount of work.

PS: Regarding 5.3: there are libraries to do that: check https://jwt.io and search for PHP.

Thanks for taking the time reading my post and responding! :slight_smile:

Instead, users should be able to carry their identity, and the Nextcloud user repository would be the AAD directory.

I don’t even know if that’s possible, because you will need to have a user-folder in Nextcloud.
Currently, I don’t see the advantage of making a complicated backend implementation over creating a local user who cannot regularly use log-in, only through OAuth, but has all the benefits of a local user. You could still sync attributes from AzureAD every once in a while.

But maybe we’re not talking about the same things? :smiley:

PS: Regarding 5.3: there are libraries to do that: check https://jwt.io and search for PHP.

Thanks for the hint, I’ve used the firebase php implementation before, but there might be better choices.

– Thomas

I hear what you’re saying. Essentially, you’d use an external provider just to replace the password. It can work and it’s definitely easier to implement than my suggestion :slight_smile:

What I was thinking was to leverage the AAD directory as the only directory. Sessions would be granted by AAD directly, using JWT tokens. The folder in NC would be created the first time a session for the user is started. There are two advantages that I see here:

  1. Every user in the AAD would be already a user in Nextcloud. No need to create a separate account, so you can share files with all users in the directory.
  2. Once an account is removed from the AAD directory (in a business environment, think termination), the user would lose access to the NC account immediately. Also, it might enable scenarios such as impersonation.
1 Like

Sorry for the delay!

Once an account is removed from the AAD directory (in a business environment, think termination), the user would lose access to the NC account immediately. Also, it might enable scenarios such as impersonation.

This would also be the case with my “Frontend” proposal. If you don’t have an account on Office 365, you can’t log-in, the local account should not be able to log-in without the grant by the OAuth identity provider.

Every user in the AAD would be already a user in Nextcloud. No need to create a separate account, so you can share files with all users in the directory.

I have to admit that this is a huge advantage of implementing a “Backend”, like you suggest. Didn’t think about it before. You might want to share files with users that have never logged-in to Nextcloud before.


Most probably, I won’t have time to look into this until next year, but I’ll definetly keep you updated here and we’ll see then what the best solution will be. Also, it’s probably easier if I hit certain questions along the way to ask them once they appear and not all upfront.

Thomas

I think, this might well be what we’re looking for in this thread, wouldn’t it? Office 365, Azure AD SSO?

I’m not actively looking into this anymore, so feel free to use the instructions in the link above.