Given Azure Endpoint Domains: Hash versus *.onmicrosoft - azure

I'm creating a web app to work with Azure AD.
I'm going through the process of making the REST requests, etc., and I'm a bit confused as to the endpoint URL parameters given by AD versus those given in the help documentation versus what I'm given in the AD console online. On some of the documentation pages, the endpoints are given as "https://login.windows.net/[some domain].onmicrosoft/...", where on the AD console, I'm given a long hash, with no ".onmicrosoft/..." present. I'm having problems with both (something else is obviously wrong), but I can't proceed debugging that until I know which I should proceed with, so I know that this isn't causing the problem.

The "hash" is actually a GUID, and is your tenant ID - the unique identifier for your Azure AD tenant. When constructing the login.windows.net endpoints you can use the tenant ID and the domain name (yourtenant.onmicrosoft.com) interchangeably.
See this post from Vitorrio Bertocci for more details on the subject.

This is indeed confusing and not well hashed out in the documentation.
I've created a web-app that also uses Office 365 authentication with Azure AD, and I am using the hash generated by the Azure AD console for my endpoint URLs, and everything is functioning well. Whatever the AD console gives you online is correct, and will work for your particular app (the hash given is in fact replacing a .onmicrosoft domain, and will work well).

Related

Q: Multi-Tenant Azure API Management Design

I have implemented a number of APIs on Azure APIM which are protected by a subscription key, and it all works fine.
I do have a constraint though, as the client application cannot be modified(*) and I can only set the URL as parameter (ie: no additional headers). I have worked around that limitation by implementing a small proxy app that customers can deploy locally and which adds the subscription key. In other words, the client app connects to a local URL, then the proxy calls the API. That also works fine.
I would like however to offer a simpler evaluation for prospects, without the need to deploy the proxy. I thought I could provide each customer their own tenant URL (eg: guid.mydomain.com) and then use that information on Azure APIM to look-up the auth key and call the backend API. That is the part I can't figure out.
I am looking for either alternative design ideas or tips on how to make it work.
Any idea?
Marco
(*) it belongs to another company.
For those that may be interested, I solved the problem by adding a new set of azure functions and a custom wildcard certificate for the subdomain.
In the azure function, the domain and subdomain info can be found in the HttpRequest.Host property. In my case, the subdomain equates to the tenant id, which I can then use to retrieve the subscription key and call the APIM API.

Which Azure parameters & keys are sensitive

Is there a comprehensive list over which keys and UUIDs provided by Azure are sensitive information?
For context, I am setting up a react app using react-adal. This requires me to provide the tenantID and clientID to the app. It would be trivial for anybody with a little know-how to extract those UUIDs from the application given the way I currently have it setup. It's a static app with no back-end service, so it all runs in the browser. I have the application setup as a App registration (registered app?), in AzureAD to allow users to login with their Office365 account for my organization. Almost all the tutorials online show setting it up the same way I am. However, some tutorials with screenshots almost always have the clientID censored in the screenshots.
Edit: While this question does solve my immediate need, I am in search of documentation from Microsoft concerning security best-practices in regards to Azure keys, UUIDs, etc.
Your tenant ID is public and refers to the entire Azure AD directory. It must be in order to be used for authentication. You can find it here.
Your client app ID is not secret, as it must be used with the client secret in order to obtain a token.

Multi Instance Apps and Azure Authentication Best Practices

We have a multi-instance Saas Application:
Each of our clients is given their own instance and their own subdomain for the site.
Our application (Web app & API) is protected by Azure, currently with the ADAL javascript libraries
We also have a second API for system-level integration that needs to be protected, currently using a second 'native' azure app, but this is likely incorrect and we want to consolidate
Our application reads and writes to the Azure AD both through the AzureAD Graph API and Microsoft Graph API (including password reset calls)
We're looking at Azure AD application configuration options and want to make sure we're building the most sensible and secure Azure AD Application. Here are some of the documentation we've been looking at:
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-client-creds
https://learn.microsoft.com/en-us/azure/architecture/multitenant-identity/
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-compare
We want the application to be multi-tenant to ease configuration, and allow availability in the Gallery; but when looking into doing so we're left with some security questions.
A. Which application version to use
1) v1. Allows access to both Graph API. And as suggested by Microsoft we should use this when we're not concerned with Microsoft Accounts.
2) v2. When looking at the MS Graph API documentation it recommends using v2. Reportedly doesn't work for AzureAD Graph API? Allows the same app to be of multiple types (Web App/API and native), which we may or may not need to protect both our web api and our system api (which we're still trying to model).
B. How to manage the reply URL when our clients have different sub-domains?
I've noted the following options:
1) On the app registry, we add the reply urls for all of our customers. This seems okay because we only need to do it once, but feels odd. Is there a limit to the number of reply urls?
2) Have one reply url, but manage an external tool to route the responses to the correct instance, leveraging the state url parameter. Microsoft seems to be suggesting that in this link: https://learn.microsoft.com/en-us/azure/architecture/multitenant-identity/authenticate I'm not sure if ADAL allows us to set the state for a return subdomain url though. Is this approach common?
3) Is it possible for each ServiceProvider instance in our client's directories to configure the reply url to their own subdomain? I feel like this would be the cleanest approach, but I don't see documentation for it. It would be nice if we could set the replyURL programmatically as well.
C. How to manage authorization to the Graph APIs (AzureAD and Microsoft Graph)
I've noted the following options:
1) Use the client credential flow, with a single application key (used for all clients). As clients subscribe they will admin consent with our app to give the application permission to their directory. Of course we'd do our best to keep that key secure. But if for some reason it was compromised this would put all of our clients at risk, not just the one instance that was compromised.
2) Same as 1, but use a certificate instead of a secret key. I understand this could be a little more secure, but I don't see how it wouldn't suffer from the same issue as 1.
3) Instead of using application permissions, use delegated permissions with an admin user. This would be good, in that it inherently prevents one instance of our app from talking to the wrong directory. However changes to the administrator may interrupt service; and I think it is best audit-wise that our application is responsible for the changes it makes. (Also, do delegated permissions allow for password resetting? I know for app permissions you need to run powershell script to upgrade the application's directory role)
4) Is there some way for the service principal to generate a unique key for it's directory on creation? can this be handed back to our app programmatically? Perhaps during admin consent?
Really good questions. I'll try to answer each to the best of my knowledge, but if someone has other ideas, feel free to comment/add your own answer.
A. Which application version to use
v2 should allow you to call Azure AD Graph API. The documentation you linked shows an example of specifying Azure AD Graph scopes:
GET https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=2d4d11a2-f814-46a7-890a-274a72a7309e&scope=https%3A%2F%2Fgraph.windows.net%2Fdirectory.read%20https%3A%2F2Fgraph.windows.net%2Fdirectory.write
The main decision point if you should use v2 is: Do you need to support Microsoft accounts which are not in an Azure AD? If yes, you need to use v2. Otherwise there is no problem using v1 (well, lack of dynamic permissions).
Since you are using Azure AD Graph to modify things, I'm going to guess pure Microsoft accounts will not work for you. I would recommend sticking with v1.
v2 also has some limits: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-limitations
B. How to manage the reply URL when our clients have different sub-domains?
I could not find documentation on a limit for URLs. It could be that you can add however many you want. But I am not sure :)
If your subdomains look like this: https://customer.product.com, you can configure the reply URL as:
https://*.product.com
It will then allow any subdomain to be specified in the redirect_uri.
Though note that at the time of writing this, wildcard reply URLs are not supported in v2.
C. How to manage authorization to the Graph APIs (AzureAD and Microsoft Graph)
Using multiple keys makes no sense as they are all equal anyway :) Any of them could be used to call another tenant.
You can store the secret/certificate in an Azure Key Vault, and then use Azure AD Managed Service Identity to get it on app startup.
I would prefer using delegated permissions, but if the users of the app won't have the rights to do the things your app needs to do then that does not work.
I would just make sure it is not possible for a customer's instance to call to the APIs with another tenant id. And also make sure token caches are separated in such a way that it is not possible to get another tenant's access token (an in-memory cache on the instance would be good).

Authenticate and Call Sharepoint Online Api from Azure Function

I want to trigger a custom action when a document/file gets added on Sharepoint Online. The idea was to use Microsoft Flow, but as Flow doesn't allow you to work with the custom columns of the file added (just the title, date added, content type, etc), I was thinking of calling the Sharepoint API by hand, via an Azure Function. So the steps would be:
A user adds a new document on a document library on Sharepoint Online
A Microsoft Flow gets triggered after that document gets added.
The Flow calls an Azure Function and pass the document id to it.
The function authenticates to Microsoft Graph Api, and then request for the file with that id.
The function get the custom fields and then it does something with the custom parameters of that file.
However, I ve been trying a lot to authenticate, but it always require me to put user and pass on an HTML. Of course, the Azure Function wouldn't be able to do that. How can I authenticate to Microsoft Graph API easily? I'm stuck with that.
Any other alternative? As I said before, this is a workaround I ve been thinking because Microsoft Flow doesn't allow you to get the custom fields of a recently added/modified file, just the default ones... But what I just want to do is to manage those data when a new file is added. Solution doesn't necessarily need to use a Function or Microsoft Graph Api.
Thanks in advance.
There's not a great way to do the authentication right now - we're working on support for this. The hard part is the AD authentication, which any solution will need to deal with. We're doing some things to make this easy with Functions.
What you can do for auth is get offline access that grants you access to a refresh token, and then use the refresh token to get your access token. You can One way to build this is on Azure Website's existing EasyAuth token store (https://cgillum.tech/2016/03/07/app-service-token-store/). Then you can log in once, save the refresh token in EasyAuth's token store, and the function can pull it from there per execution.
That's the high level answer. I can elaborate on more specific steps if you're eager to do this now.
You could register the function or de Remote Web (Azure or on premise) as an app in your Sharepoint, via URL:
"http://.sharepoint.com/_layouts/15/AppRegNew.aspx
And give it permissions via:
http://.sharepoint.com/_layouts/15/AppInv.aspx
For example:
<AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="FullControl" />
</AppPermissionRequests>
In this way you will be capable of accessing your tenant or list or whatever your permissions are.
What you are seeking is app-only authentication. If you can make your document queries/updates via the SharePoint Rest API, then you have 2 options:
Granting access via Azure AD App-Only
Granting access using SharePoint App-Only (This is the same method indicated in #netadictos' answer above.)
If you prefer to make the document queries/updates with the MS Graph API, then only #1 is an option. #1 is a bit more involved, because it requires a client secret AND a self-signed security certificate. #2 will only require the app/client ID and secret.
The MSDN documentation linked above uses a PowerShell script to generate the security cert, but I prefer Bob German's instructions for manually creating/exporting one. He also includes instructions for registering an Azure AD application for your Azure function in his tutorial.

How can I change the identity, as an IDP, of the WSO2 IS?

How can I change the identity, as an IDP, of the WSO2 IS?
It seems to always call itself localhost!
Some context...
I have deployed an IS and are trying to authenticate against it using SAML2.
Every single example I can find on the internet deploys IS on the same server as the SP, so the IS is on localhost! (by the way, I do arrive at a working IS-SP login on a single computer)
But this is not my case, SP and IS are on two different VMs. When I try to authenticate, after logging in, I get an error:
Caused by: SimpleSAML_Error_Exception: Cannot retrieve metadata for IdP 'localhost' because it isn't a valid IdP for this SP.
I think this error is on the SP side, generated by simpleSamlPhp.
From what I understand, this means that:
* the SP calls the IDP (IS) with a given IDP id (not localhost!) and SP id
* the IDP manages to ask us for login/passwd
* the IDP sends a SAML2 message to the SP
-> here, the IDP probably calls itself "localhost"
* the SP tries to get config (metadata?) for localhost and can't find any!
So the question is: how can I change the IDP id that the IS uses to answer?
I have changed the server name in carbon.xml, and I have changed every localhost I could find in identities.xml, but to no avail.
Thanks for any tips!
in the management portal of WSO2 IS
go to Main / Identity Providers / List
Click on "Resident Identity Provider"
Expand "Inbound Authentication Configuration"
Expand "SAML2 Web SSO Configuration"
Fill in the "Identity Provider Entity Id:"
Note that, without knownledge of the keyword "resident", I have not found this information in any doc or web page or blog.
All examples are provided with localhost.
The place this configuration is stored in not intuitive: going to "identity providers" gives a message "No Identity Providers registered", so it's easy to ignore that this is the page where this configuration lies. The link looks like a title. Subtle, but may lose a lot of time! :-)
WSO2 make great products, but tutorials and docs would benefit from being more open or diverse, I don't know. For example one can call an endpoint "localhost/saml", but is there any other way to call it? What will change? Is there an example somewhere of a deployment with lots of strange and distinct values for fields, "foo", "bar", etc?
Hope this helps others, via google search at least! :-)

Resources