Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

OVERVIEW

We currently support three OAuth Providers, GitLab, Google, and Office365. After researching our implementation and OpenId Connect, Mattermost already supports most of OpenId Connect. Review the background reading in order to understand OpenId Connect and its relationship to OAuth. As well as the login flow for OAuth.

...

  1. Support OpenId Connect standard for Authentication

  2. Support Discovery Document

  3. Support retrieving user fields currently supported in OAuth2 implementations

    1. Either from IdToken or additional userinfo_endpoint call

    2. Email, First Name, Last Name, Username (from Email), Nickname, AuthData

  4. Ensure OpenId Connect works with existing OAuth providers. (Office365, Google, GitLab)

  5. Migrate Existing OAuth2.0 providers to OpenId Connect

SCOPE

In:

  • OpenId Connect Authentication Provider

  • System Console Setup for OpenId Connect Provider

  • Support of OpenId Connect in Mobile/Desktop/WebApp

Out:

  • Google Support on Mobile

  • Multiple Provider Support

  • Plugin Interactivity

BACKGROUND READING

Document on Google’s OpenId Connect / OAuth2 implementation and the differences between them.
https://developers.google.com/identity/protocols/oauth2/openid-connect
https://openid.net/connect/
OpenId Connect Specification

TERMINOLOGY

OpenID Provider - OAuth 2.0 Authorization Server that is capable of Authenticating the End-User and providing Claims to a Relying Party about the Authentication event and the End-User.

IdToken - [JWT] that contains Claims about the Authentication event. It MAY contain other Claims.

...

At a high-level, the OpenId provider will work in the same manner as the current OAuth2 implementation. Most
Although most of the code required for performing the OAuth authorization already exists. However, it will need to be refactored in order to be used by the OpenId Connect provider. For instance, GetAuthorizationCode() retrieves the Endpoint information from the config file. The OpenId Connect provider will retrieve that information from the Discovery Document.

The steps are provided below with where that code exists for the existing OAuth implementation.

...

  1. Mattermost sends a request to the OpenID Provider (OP). [AuthorizationEndpoint]
    When creating the call to the authorization endpoint, a token gets created and stored, this allows Mattermost to verify it was the provider calling back. [GetAuthorizationCode][app/oauth.go]

  2. The OP authenticates the End-User and obtains authorization.
    The user is presented with a login form from the OP, then an authorization for the requested scopes.

  3. The OP responds with a Token.
    Mattermost validates the token, by retrieving it from the database and comparing Token information.(AuthorizeOAuthUser)[app/oauth.go]

  4. Mattermost send a request to the OpenId Provider. [TokenEndpoint]
    Mattermost exchanges secret for AccessToken/ID Token (AuthorizeOAuthUser)[app/oauth.go]

  5. The OP responds with an ID Token and usually an Access Token.
    The ID Token gets verified and decoded. [New functionality]
    Some providers pass all the user info in the Id Token (Google, Exchange), therefore the login process could end here. Others [GitLab] do not return user information in the Id Token and require an additional call. [New Functionality]

  6. Mattermost requests with the Access Token to the UserInfo Endpoint.
    Similar to existing call to UserApiEndpoint (AuthorizeOAuthUser)[app/oauth.go]

  7. The UserInfo Endpoint returns Claims about the End-User.
    Convert Claims to model.User [New]
    Similar to OAuth Providers [userFromGoogleUser]

...

Discovery Document

The OpenID Connect protocol requires the use of multiple endpoints for authenticating users, and for requesting resources including tokens, user information, and public keys.

...

model.User Property

GoogleUser

IdToken(google)

userInfo (google)

IdToken (github)

userInfo (github)

userInfo (Office365)

Email

Email

email

email

email

email

Username

From Email

from Email

from email

from email

from email

FirstName

GivenName

given_name
name (Split space)(check 3 names?)

given_name
name split space

name split space

name split space

LastName

FamilyName

family_name
name (Split space)(check 3 names?)

family_name
name split space

name - split space

name split space

Nickname

Nicknames[0]

nickname

nickname(?)

nickname

nickname

AuthData

MetadataSource.Id

sub

sub

sub

sub

sub

AuthService

GOOGLE

"iss":"https://accounts.google.com"

"iss":"https://gitlab.com"

picture (url)

locale

iat (time issued)
expires

profile

picture

iat

profile

picture

iat

profile

picture

iat

Licensing

The OpenId Connect provider is planned as a E20 feature. The feature should be protected by license checks.

Permissions

There should not be any permission changes

...

There is the potential of adding two additional api commands for handling OpenId Connect.

Code Block
w.MainRouter.Handle("/openid/{service:[A-Za-z0-9]+}/complete", w.ApiHandler(completeOAuth)).Methods("GET")
w.MainRouter.Handle("/openid/{service:[A-Za-z0-9]+}/login", w.ApiHandler(loginWithOAuth)).Methods("GET")
w.MainRouter.Handle("/openid/{service:[A-Za-z0-9]+}/mobile_login", w.ApiHandler(mobileLoginWithOAuth)).Methods("GET")
w.MainRouter.Handle("/openid/{service:[A-Za-z0-9]+}/signup", w.ApiHandler(signupWithOAuth)).Methods("GET")

Ideally, OpenId could be handled as an additional service and with the existing code. However, that will depend on whether multiple providers are allowed. And how easily the code can be refactored to accommodate both.

CLI

No CLI changes required

...

  • Account Settings

    • Restrict user from setting

      • Username

      • Email

      • Similar to other OAuth providers

  • Logging In

    • WebApp -

      • login_controller.jsx

      • Add OpenIdConnect section

        • Is user restricted to OpenId Connect or OAuth?

        • Currently OAuth limited to one being turned on at a time.

        • I don’t think it is a technical limitation.

    • Mobile

      • loginOptions.js

      • Add OpenIdConnect Option

      • Google OAuth not supported on mobile,

        • Need to understand why

        • Will this affect OpenIdConnect?

      • Update to login flow

Mobile Migration -
w/ old server

  • New OpenId won’t be available as server won’t support.

  • Existing OAuth Connections will continue to work as is.

w/ new server

  • New OpenId will be available if configured and enabled on the server.

  • Existing OAuth Connections will continue to work as is.

    • Same endpoints, change is on server side.

Old app w/ new server

  • New OpenId will not be available

    • If that is users login method, they would not be able to login.

  • Existing OAuth Connections will continue to work as is.

Migration

Once an OAuth System has been migrated to OIDC, we need to understand the impact on existing users. Users will remain logged in as long as their session is valid. Once their session expires, the users will go through the new login process. They will be asked to login in their provider (or not, if already logged into their provider). Whether or not the users are asked to reauthorize usage depends on each Provider.

Each of these was tested as follows -

  • Remove Authorized Application from Provider

  • Login using current OAuth Settings

  • Change Configuration to use OpenId Connect for same provider, same application

  • Login using OpenId Connect Scopes [OpenId, Email, Profile]

Google

Google already uses OpenId Connect as the login mechanism for OAuth. The user does not have to authorize any additional access.

GitLab

GitLab controls the user’s allowed scopes in the GitLab Application. The admin will need to add or verify users have access to [email profile openid] scopes in the Mattermost application on GitLab. Once that is done when the user logs in, the user will be asked to authorize access to the new scopes.

Office365

Office’s User.Read permission allow MM to “Read your profile”. That single permission is enough to allow the profile, email, openid scopes to operate successfully. If the application is deleted and recreated the “View your basic profile” and “View your email address” permissions request access.

Performance

The retrieval of the Discovery Document should only happen once and then be cached.

...

No immediate impact on plugins. However, we need to explore the use of the IdToken to be used between plugins and the server for authentication. Need to understand the plugin use cases better.

However, I do not understand how plugins use OAuth. Currently, they authenticate separately, I believe. But in the future, we want to look at using the IdToken between the server and plugins. There is a way for applications to use incremental authorization to request additional permissions. However, that is beyond the scope of this document.

...

CREDITS

Thanks to