Single Sign On with OpenID Connect
The problem with passwords
Having to memorize a lot of passwords is not a good idea. I know there are password managers, but their spread is still frighteningly low. Also, logging into multiple systems with a password manager takes some time.
So we want to offer our customers a comfortable single sign-on experience. Log in to the Vertec apps should be linked to another system that is already in use. In the environment of our typical customers, we do not have to look far for the “other system” – we operate in a Microsoft-oriented environment, with Office applications and their cloud features as “Microsoft 365”.
If it were just a matter of avoiding different passwords, we would have had a solution ready for a couple of years with the Vertec LDAP Integration. LDAP does just that, however, it takes care of the verification of login and password. True Single sign-on, i.e. without repeatedly entering the username and password, is not directly possible. In addition to the good old login with username and password, there are now a whole lot of other ways to authenticate a user. From 2FA and biometric methods to Windows integration and hardware tokens, the range of possibilities is growing. Vendor like Microsoft is already implementing many newer methods, and it’s not worth implementing them all yourself.
Delegate instead of implement
The better solution is to completely delegate user authentication right away. And that brings us to the real issue of integrating with an identity provider, a specialized provider for user authentication. When it comes to authentication delegation, there are two established standards: SAML and OpenID Connect.
- SAML is a bit more common in the enterprise environment because it is older.
- Openid connect is newer and easier to implement. That’s why we chose OpenID Connect.
OpenID Connect is an application of the Oauth2 standards for authentication. This means that the essential mechanisms correspond to the OAuth2 authorization framework. Essentially, OpenID Connect is about obtaining an ID token instead of an Access token as in OAuth2. The ID token is a cryptographically secured piece of data that confirms the identity of a user.
The SSO aspect is accessed via a browser shared with other apps, which saves the login session with the Identity Provider via cookies. As long as the browser knows the login session, no interaction such as password entry is necessary and the login is automatic. The Identity Server from Microsoft is called Azure AD (so to speak the cloud version of Active Directory) and supports OpenID Connect.
Implementation in Vertec
With our integration, we are focusing on Microsoft as a vendor for the moment. Broadly speaking, the OpenID Connect integration in Vertec looks like this:
- In Vertec, the unique ID of a specific Azure AD user is stored on a user. The Azure AD user is then the same as this Vertec user in Vertec.
- When a Vertec app is started, the authentication of the user is delegated to Microsoft (Azure AD).
- The Microsoft Identity Server returns an ID token after successful authentication.
- In Vertec, based on the properties of the ID token, we can determine the assigned Vertec user and log in, of course only after we have checked the ID token for its validity.
So instead of using a username/password, access to Vertec is based on an ID token. We don’t care how the user is authenticated, we have delegated this process. To be able to trust the ID token, we need to ensure two things:
- The token must come from our trusted publisher (Azure AD) and be intended for our app
- The token must not fall into the wrong hands during transfer
We can cover point 1 by checking the ID token’s signature, issuer and target audience. Point 2 is a bit more sensitive and depends on the type of app involved.
The OpenID Connect Flow
How is the implementation done in the different Vertec apps?
We have web clients, desktop and hybrid clients such as cloud and mobile app. OpenID Connect comes from the web area. The actual user interaction for authentication is always based on a web browser.
The critical point is how the ID token gets from the Microsoft server to the Vertec application. OpenID Connect relies on browser redirects to transfer the data from the Identity Provider to the app. In its response to a successful authentication, the Identity Server instructs the browser to call a specific URL of the app. In the case of the Vertec Web App, this is a call-back URL on the Vertec cloud server.
The callback call is secured by TLS (https://), the transmitted data are therefore secure and cannot fall into the wrong hands. The sequence of calls between the app, browser and identity server is commonly called “flow”.
The current state of affairs with OpenID Connect is the “Authorization Code Flow”. In this case, the Identity Server does not transmit the actual ID token in its callback, but only an authorization code, a random string of characters. The application then uses this code to request the actual ID token from the Identity Server. If the application is a web server-based app, it is called a “Confidential Application,” since the token is only known on the server. An attacker has little chance of intercepting the ID token because it is transmitted directly from server to server.
It becomes more difficult for apps that do not run in a normal web browser or do not use a server connection at all, such as the Vertec Desktop or Cloud App. These are native Windows applications, without their own web servers, that run on the client computer.
The trick here is to specify a custom URL as the callback URL for which the app registers with Windows (e.g. ms-appx-web://some-callback). This allows the Identity Server to reach a native app with a browser redirect. However, this is not optimal from a security point of view:
While a web server with TLS is certified by a certificate that the recipient of the callback is really that server, a custom URL can be registered by any app on the machine, including malware. This means that the data in the callback can be eavesdropped and misused. In the case of the authorization code flow, an attacker could use the eavesdropped code itself to request an ID token.
Help from Pixy
To close this gap, Desktop App must use an advanced method: Authorization Code Flow with PKCE (English “pixy”). At the start of the authentication process, the app generates a random, secret Verifier Code and sends a derived challenge value to the Identity Server. Only together with Verifier Code can the app redeem the received Authorization Code at the server for an ID token.
Since both the initial transmission of the Challenge value to the Identity Server and the redemption of the Authorization Code with the Verifier take place via https, security is guaranteed again. Since the implementation of the Authorization Code Flow with PKCE, the earlier “implicit” flow, where the token is transmitted directly in the callback, is considered insecure and should no longer be used, also in the web scenario.
Down to the code
For the actual implementation of OpenID Connect, the rule of thumb for security-relevant code applies: never write yourself, but use an established library. This, of course, only from a trusted source.
The most secure version of the implementation is that for the Web App. There the authorization code is delivered to the server and the ID token is obtained directly on the server. The browser never sees the ID token.
Since our server is based on the Owin Stack, the whole thing will be set using the Microsoft.owin.security.openidconnect Package that takes care of the entire flow. The Cloud App as native Windows apps obtains the ID token on the client side, as described above, and then sends it to the server via https. The Msal library for .net supports the client-side scenario and also takes care of the deployment of a browser for the user interaction. On the server side we check the ID token with support of the .NET packages “System.identitymodel.tokens.jwt “ and “Microsoft.identitymodel.protocols.openidconnect “.
The WAM Factor
In order for SSO to work with Windows apps, we need a browser for these apps that already has a Microsoft login session. MSAL does this with the support of a Windows own broker component called WAM (short for Windows Authentication Manager). This is a kind of built-in browser that can save various logins internally. WAM is used by Windows itself as well as by Office applications for Windows. As a result, with the app accounts configured in Windows, SSO is also possible for non-web-based applications.
Wrap Up
The main points regarding SSO with OpenID Connect can be summarized as follows:
- OpenID Connect is a mature technology for user authentication with good library support on all platforms.
- Up to date state of the art in terms of security is the Authorization Code Flow with PKCE, which is supported by most libraries and should be used.
- The OpenID Connect Flow can take place on the client (“native” applications) or on the server (web apps). Both variants guarantee the security of the ID token. The server variant is preferable if possible.
- For Single Sign On with “native” applications, there is a built-in broker (WAM) under Windows.
Next Steps
The OpenID Connect support in Vertec is currently still in development and will be generally available as soon as all apps, including the Outlook and Phone App, are integrated. The conversion of a Vertec environment to SSO with OpenID Connect needs to be well thought out and planned. In addition to the clear advantages offered by a connection to Azure AD as an Identity Server, it has to be taken into account that it also creates new dependencies. Should the Microsoft Identity Server infrastructure fail, it is also no longer possible to log in to Vertec.