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

Cannot connect to Exchange Online using OAuth #183

Open
filipvh opened this issue Dec 15, 2023 · 1 comment
Open

Cannot connect to Exchange Online using OAuth #183

filipvh opened this issue Dec 15, 2023 · 1 comment

Comments

@filipvh
Copy link

filipvh commented Dec 15, 2023

I used the example provided in the readme
MSAL seems to work fine, but I get a 400 error with no other details.

The code I've used (partially modified):


import hashlib

import msal
import psrp

from cryptography.hazmat.primitives.serialization import (
    Encoding,
    NoEncryption,
    PrivateFormat,
)
from cryptography.hazmat.primitives.serialization.pkcs12 import (
    load_key_and_certificates,
)

def get_msal_token(
        organization: str,
        client_id: str,
        pfx_path: str,
        pfx_password: str | None,
) -> str:
    pfx = open(pfx_path, mode="rb").read()
    print(pfx)
    private_key, main_cert, add_certs = load_key_and_certificates(
        pfx,
        pfx_password.encode("utf-8") if pfx_password else None,
        None
    )
    assert private_key is not None
    assert main_cert is not None
    key = private_key.private_bytes(
        Encoding.PEM,
        PrivateFormat.PKCS8,
        NoEncryption(),
    ).decode()

    cert_thumbprint = hashlib.sha1()
    cert_thumbprint.update(main_cert.public_bytes(Encoding.DER))

    app = msal.ConfidentialClientApplication(
        authority=f"https://login.microsoftonline.com/{organization}",
        client_id=client_id,
        client_credential={
            "private_key": key,
            "thumbprint": cert_thumbprint.hexdigest().upper(),
        },
    )

    result = app.acquire_token_for_client(scopes=[
        "https://outlook.office365.com/.default"
    ])
    if err := result.get("error", None):
        msg = f"Failed to get MSAL token {err} - {result['error_description']}"
        raise Exception(msg)

    return f"{result['token_type']} {result['access_token']}"


def main() -> None:
    tenant_id = "214e89fc-27c2-4663-8683-210792b6496a"

    # This is the ID of the Application Role to authenticate as
    client_id = "my-client-id" #removed :p

    msal_token = get_msal_token(
        tenant_id,
        client_id,
        "app/server.p12",
        ""
    )

    conn_info = psrp.WSManInfo(
        server="https://outlook.office365.com/PowerShell-LiveId?BasicAuthToOAuthConversion=true",
        auth="basic",
        username=f"OAuthUser@{tenant_id}",
        password=msal_token,
        configuration_name="Microsoft.Exchange"
    )

    with psrp.SyncRunspacePool(conn_info) as rp:
        ps = psrp.SyncPowerShell(rp)
        ps.add_command("Get-Mailbox")
        print(ps.invoke())
        print("done")


main()

@jborean93
Copy link
Owner

I believe Exchange Online has stopped supporting PSRemoting endpoints with OAuth as per https://techcommunity.microsoft.com/t5/exchange-team-blog/deprecation-of-remote-powershell-rps-protocol-in-security-and/ba-p/3815432

The timeline of disablements in this blog post applies only to tenants in our World-Wide (WW) cloud. Final RPS disablement for customers in other Microsoft cloud environments as well as WW cloud is scheduled for October 2023.

They have their own REST API now with the new cmdlets wwhich means you can't use the PSRP library for online exchange management anymore.

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

No branches or pull requests

2 participants