Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for InTune Single-Sign-On #1280

Merged
merged 1 commit into from
Jun 4, 2024

Conversation

KrissN
Copy link
Contributor

@KrissN KrissN commented Jun 3, 2024

This add support for communicating with the Microsoft Authentication Broker over its DBus interface in order to retrieve an authentication cookie, that can be used to automatically login the user currently logged-in via InTune. This also adds support for MFA and Conditional Access, which allows use of Teams outside of corporate network in case the organization has chosen to only allow access from registered devices.

Behind the scene this uses the same mechanism as Microsoft Edge on Linux: upon loading a website from login.microsoftonline.com the URL is passed to the authentication broker in order to prepare a token based on the PRT (Primary Refresh Token). The returned refresh token is passed to the server via the 'X-Ms-Refreshtokencredential' HTTP header. With this token in place the server will skip any interactive prompts and generate a proper OAuth authentication token. Since the PRT is tied to the device credentials, the resulting refresh token carries the MFA attribute, which causes it to be accepted even if the Conditional Access policy mandates strong, device-based authentication.

@IsmaelMartinez
Copy link
Owner

Thanks a lot for your contribution! snyk seems to have found a few issues on the dbus package you added. I will have a look tomorrow to see how "bad" they are and/or if there is a more secure alternative out there. Thanks again! Left a few small comments (nothing ridiculuous).

@IsmaelMartinez
Copy link
Owner

the dbus-native repository seems to be not maintained (no updates in the last 2 years).

This fork seems to be a bit more maintained (updated 2 months ago)
https://www.npmjs.com/package/@homebridge/dbus-native

Can we change that and see if the snyk then passes ? Thanks!

@IsmaelMartinez
Copy link
Owner

I always forget!

Can you update the https://github.com/IsmaelMartinez/teams-for-linux/blob/develop/package.json#L3 number to 1.5.3 and create a wee note in the https://github.com/IsmaelMartinez/teams-for-linux/blob/develop/com.github.IsmaelMartinez.teams_for_linux.appdata.xml#L17 with the 1.5.3 release? Thanks again!

This add support for communicating with the Microsoft Authentication
Broker over its DBus interface in order to retrieve an authentication
cookie, that can be used to automatically login the user currently
logged-in via InTune. This also adds support for MFA and Conditional
Access, which allows use of Teams outside of corporate network in case
the organization has chosen to only allow access from registered
devices.

Behind the scene this uses the same mechanism as Microsoft Edge on
Linux: upon loading a website from login.microsoftonline.com the URL
is passed to the authentication broker in order to prepare a token
based on the PRT (Primary Refresh Token). The returned refresh token
is passed to the server via the 'X-Ms-Refreshtokencredential' HTTP
header. With this token in place the server will skip any interactive
prompts and generate a proper OAuth authentication token. Since the
PRT is tied to the device credentials, the resulting refresh token
carries the MFA attribute, which causes it to be accepted even if the
Conditional Access policy mandates strong, device-based
authentication.

Signed-off-by: Krzysztof Nowicki <[email protected]>
@IsmaelMartinez IsmaelMartinez merged commit 0896927 into IsmaelMartinez:develop Jun 4, 2024
1 of 2 checks passed
@IsmaelMartinez
Copy link
Owner

Thanks for your contribution! I hope this is released as a pre-release soon (or tomorrow).

@IsmaelMartinez
Copy link
Owner

brokerService.getInterface(
'/com/microsoft/identity/broker1',
'com.microsoft.identity.Broker1', function(err, broker) {
broker.acquirePrtSsoCookie('0.0', '', JSON.stringify({'ssoUrl':detail.url, 'account':intuneAccount, 'authParameters':{'authority':'https://login.microsoftonline.com/common/'}}), function(err, resp) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KrissN Last week I developed a plugin for Firefox on Linux that uses exactly the same approach. This will be OSSed soon. I'm currently working on a similar thing for EWS in Evolution.

I'm just wondering if the authParameters part here is really sufficient (apparently it works), as the Edge Browser puts more data in there:

Sample request from Edge

            'accessTokenToRenew': '',
            'account': account,
            'additionalQueryParametersForAuthorization': {},
            'authority': 'https://login.microsoftonline.com/common',
            'authorizationType': 8,  # OAUTH2
            'clientId': EDGE_BROWSER_CLIENT_ID,
            'decodedClaims': '',
            'enrollmentId': '',
            'password': '',
            'popParams': None,
            'redirectUri': 'https://login.microsoftonline.com'
                           '/common/oauth2/nativeclient',
            'requestedScopes': scopes,
            'username': account['username'],
            'uxContextHandle': -1

The interesting parts here are:

  • repetition of the account
  • authorization type
  • client ID
  • requested scopes (which usually is just https://graph.microsoft.com/.default)
  • username

Did you find documentation about the exact interface, or also just reverse engineered it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also here, a client ID can be passed. I recommend to use the one from edge here, as Edge itself is technically more or less a chrome (webkit). An alternative would be to make it configurable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I have found no documentation about this DBus interface. I have reverse-engineered it, in a way that I have found a minimum set of arguments that have worked.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KrissN thanks for the confirmation. It would be good if we could at least make the client id configurable. Apart from that, we should also ensure that the service is running before calling it on DBus. Otherwise, the sign-in does not work directly after boot (before another application like Edge activates it via DBus). For reference, you might want to have a look how I implemented that in the Firefox / Chrome plugin: https://github.com/siemens/linux-entra-sso/blob/main/linux-entra-sso.py#L63

logger.warn('Failed to find microsoft-identity-broker DBus interface');
return;
}
broker.getAccounts('0.0', '', JSON.stringify({'clientId': '88200948-af09-45a1-9c03-53cdcc75c183', 'redirectUri':'urn:ietf:oob'}), function(err, resp) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interestingly you get a different response from the broker if you use a specific client id (like the one from Edge, d7b530a4-7680-4c23-a8bf-c52c121d2e87). When using that, I just get a single account back instead of three time the same.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That single account is highly likely the MS Entra identity for the synchronized work profile in MS Edge. I'm not sure how this is going to react in case you have a second work profile synchronized to a different MS Entra user identity.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I already experienced that MS Intune had issues in the past in that multiple work profiles scenario.

brokerService.getInterface(
'/com/microsoft/identity/broker1',
'com.microsoft.identity.Broker1', function(err, broker) {
broker.acquirePrtSsoCookie('0.0', '', JSON.stringify({'ssoUrl':detail.url, 'account':intuneAccount, 'authParameters':{'authority':'https://login.microsoftonline.com/common/'}}), function(err, resp) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also here, a client ID can be passed. I recommend to use the one from edge here, as Edge itself is technically more or less a chrome (webkit). An alternative would be to make it configurable.

@Zegorax
Copy link

Zegorax commented Jun 21, 2024

Hello everyone,

Thanks a lot for this PR, it works!

Just a FYI, the documentation / code is incorrect regarding the variables names. In my case, I had to use ssoInTuneEnabled and ssoIntuneAuthUser for it to work. Notice that on the first one, the T of Intune is in capital, whereas the second one it is not.

Maybe a little code / doc update would be welcome?

@fmoessbauer
Copy link
Contributor

Just a FYI, the documentation / code is incorrect regarding the variables names. In my case, I had to use ssoInTuneEnabled and ssoIntuneAuthUser for it work. Notice that on the first one, the T of Intune is in capital, whereas the second one it is not.

Oh... that's why I never got it working for me. IMHO this should be unified and cleaned up in the the code as well (accepting an interface break).

@IsmaelMartinez
Copy link
Owner

IsmaelMartinez commented Jun 21, 2024

oops 😄 . Can someone file a bug? That should be easy to fix... but it should be a breaking change (so version up for 1.7.x to 1.8.x)

@nsballmann
Copy link

oops 😄 . Can someone file a bug? That should be easy to fix... but it should be a breaking change (so version up for 1.7.x to 1.8.x)

Is this an option for the situation: Allowing both variable names, emitting a deprecation warning in case the undesired one is used and allowing the desired one to take precedence over the undesired one in case both are specified, including a warning?

@IsmaelMartinez
Copy link
Owner

I tend to be more brutal and just increase the package version (middle number) and release it as pre-release (putting a message in this channel).

Ideally you can phase out people's configuration and/or support all versions, but is it worth it? Probably no as I don't think many people are using this feature (also, I think people only look at the logs when there is a problem 😄). Saves me the time to then remove the deprecation version and code at a later stage.

Ideally we can pop a message (pop-up) for those deprecations, so people change it as it is annoying, but that would then require some extra coding... that is double, but again not sure if worth it for the few times we have this problem.

@IsmaelMartinez
Copy link
Owner

Ok, I have changed this to inTune, but forgot to put the warning!!! Meaning @KrissN / @nsballmann / @fmoessbauer / @Zegorax , change that if you move to 1.7.5!!!

@fmoessbauer
Copy link
Contributor

Ok, I have changed this to inTune, but forgot to put the warning!!! Meaning @KrissN / @nsballmann / @fmoessbauer / @Zegorax , change that if you move to 1.7.5!!!

Isn't this still inconsistent? The config option is called ssoInTuneEnabled , here, while the documentation states ssoIntuneEnabled.

@IsmaelMartinez
Copy link
Owner

oh, I did miss that one up. looks like my vs code is playing with me and only does the search on open files.

I have updated the REAME as the config options already had the InTu format. Thanks for reporting!

@nsballmann
Copy link

@IsmaelMartinez just a question out of curiosity: Is the reason to use InTune an intentional wordplay (maybe to dissociate from MS)? Because according to MS website (https://learn.microsoft.com/en-us/mem/) the product name is Intune.

@IsmaelMartinez
Copy link
Owner

Nope but definitely yes. I didn't know anything about Intune until recently (and don't know much about it tbh). But yes, definitely just playing with the wording.... Sure...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants