Office365 SSO for Web app



  • I'm working on a webapp for my day job, and we use Office 365 for our email. Is there a way to hook my webapp into their single sign on system?

    I want it to work like, for example, Stack Overflow's login system, where the user visits our site, clicks a button to sign in, signs into the Microsoft ecosystem, and then my website gets a token or whatever telling us it's okay to let them in. (Yes, I know OAuth is a bit more complicated than that, but not so much more).

    What are my options?



  • @captain Yes; Office 365 is an OAuth2 provider.

    Check out the Microsoft Graph Explorer and related documentation: https://developer.microsoft.com/en-us/graph/graph-explorer

    Let me know if you have any more specific questions. I actually did pretty much exactly this in my last job using the ADAL.js OAuth2 library provided by Microsoft.



  • Note that they typically would prefer you to redirect to their page for the login, rather than accept the username and password yourself and using the web API. Not that you can't do that, but you really probably shouldn't.



  • @blakeyrat Thanks so much, that's a great place for me to start.



  • @magus said in Office365 SSO for Web app:

    Not that you can't do that, but you really probably shouldn't.

    You really shouldn't, because there's no guarantee that Microsoft knows the username/passwords. It's not uncommon to get redirected to an organisation's STS (most often ADFS) when you type in your email address.



  • @alexmedia Which is why that call normally requires the AD tenant, which is easy enough. We have to do that here for some testing.



  • @magus said in Office365 SSO for Web app:

    Note that they typically would prefer you to redirect to their page for the login,

    AFAIK, you have to do this. That's just how OAuth2 works. (OAuth1 and OpenID had different ways of doing it.)

    You can compromise by opening the Microsoft login page in an iframe or pop-up window, but that's not ideal and should be avoided if possible.

    @magus said in Office365 SSO for Web app:

    Not that you can't do that, but you really probably shouldn't.

    AFAIK you literally can't do that. The only exception is if you've previously authed the person, the token you get is good for some period of time I no longer remember (24 hours?) so within that period of time they can come and just be on the site immediately. (EDIT: of course you as a site owner don't know if the token's still good until you try to query some info with it, at which time you might be told you have to auth.)

    Also, if the user has previously authed, when you do the Microsoft login page redirect it will sometimes redirect directly back to you with the right token, because it knows it already granted permissions. Not sure what the rules are for when it does this.



  • @blakeyrat Good point, you can't just hit the web API to log in unless the user has already logged in and accepted the account connection whatever.



  • @magus It's better to look at it like a 2-step process:

    Step 1: "Does this person have a valid account on Office 365 for your company?"
    Step 2: "Does this person consent to giving your application data X?" (Where X is the Android-esque list of permissions you're asking for).

    Now you can in theory skip Step 2 and use OAuth2 just for auth. But the instant you try to get ANY data (possibly even something as petty as their avatar image), you'll have to re-auth or you'll be denied.



  • @blakeyrat said in Office365 SSO for Web app:

    You can compromise by opening the Microsoft login page in an iframe or pop-up window, but that's not ideal and should be avoided if possible.

    Iframe won't work, as the Microsoft logon page sends an X-Frame-Options: Deny header, blocking any attempts at iframing that stuff.



  • @alexmedia Ah well there you go. The only reason I mentioned auth without redirect is I was writing a Chrome extension where we had to do that, letting the parent page redirect would ruin our survey because it wouldn't come back where it left off. But I'm always working on the "weird" use-cases the library writers didn't anticipate, and constantly have to find weird workarounds for everything.

    Point is: OAuth2 is supposed to use a redirect, if you let it, you'll be much happier.



  • OK, quick question time.

    The "get access token" phase of Azure AD's OAuth2 pipeline seems to require a client_secret, per:

    The application secret that you created in the app registration portal for your app. It should not be used in a native app, because client_secrets cannot be reliably stored on devices. It is required for web apps and web APIs, which have the ability to store the client_secret securely on the server side.

    But the Azure AD portal didn't ask me for a secret. (I even went as far as registering a new Azure AD app in the portal). What gives?



  • @captain Usually such a secret is created upon also either creating the app or upon registration of said app with the OAuth provider.



  • @captain Welcome to the joys of AzureAD where the same value is referred to with 3 or 4 names simultaneously.

    Does this article help? Hopefully it's up-to-date with the current Azure Portal.

    Or in a line of English, you need to enter your Azure AD application page, go to the Keys settings, and create a new Key. The ClientKey and ClientSecret are the same value by a different name. Because everything in Azure has 3 different names, for maximum confusion.

    EDIT: also that help file is wrong, you're not required to use a ClientSecret on the web if you don't want to. (Again: the Chrome Extension development process I was doing made this impossible, as all Chrome Extensions are open-source by definition, so you couldn't securely store a key in them.) You should though.



  • @blakeyrat Aha. I saw that Keys screen, but it didn't make sense to me to "just" put in a key, especially since it lets me put in multiple keys with descriptions and public keys and so on.

    Edit: maybe I should be scripting all of this with PowerShell so it's easier to productize my thing.



  • I agree with @blakeyrat, Azure AD stuff is bloody confusing.



  • @captain The idea is if you lose your key (it gets checked-in to GitHub or something) you can revoke it and generate a new one. So the ability to make keys on demand makes sense.

    It's just that:

    • Azure's UI is confusing as shit
    • OAuth2 itself is confusing as shit
    • For some reason, the designers creating this shit like to use multiple names for the same thing ("ClientKey", "ClientSecret" being a perfect example of this.)


  • Just finished the login flow for this. (Almost -- I have to clean up my code and package it into a library).

    Notes:

    • None of the tutorials mention how to use the resource parameter (most don't even mention it), when requesting an Access Token, but Microsoft's OAuth2 1.0 implementation requires it or bad things happen. I ended up using https://graph.microsoft.com.

    • Once I have an access token, I have to set HTTP headers to use it. OK, but this isn't how OAuth2 works for almost every other implementation; so I had to basically rewrite a library to get it to work in my language.

    • Debugging all this was a pain in the ass.

    Thanks for your help everybody.


Log in to reply