I know there are a lot of questions about Azure ACS, but I want to ask a more general one:
Should I use ACS, or it's not worth the effort? :)
What I want is a secure WebService in Azure that will be called from 2 places: a mobile app and another service inside Azure. Users will never access this webService directly.
Thanks
Update:
I don't care much about the identity of the user that is behind my mobile app.
I think it depends on the specific scenario, you say that users will not access the service dicrecly, but presumably it is the user who will use the mobile and/or web app.
Thinking of authentication and authorisation - if all you need to do is identify that you're coming from your own appilcation, than there are defintiely leaner approaches. simple certificate based solution would do, or even username/password based solution.
If, however, you wish to use the identity of user beheind the app to drive the authentication and authorisation for the service, than you do need to worry about the user's identity, and of course you can manage it yourself, but this is where the ACS comes very handy in that it lets you leverage one or more existing identity providers, which makes it easier for you and the user.
It's probably not worth it.
ACS is great for managing user identity on your behalf: in other words, for allowing your users to make identity claims.
If your Web service needs to know about your users' identities then it's definitely worth the (small) effort to implement, as it takes care of much of the work for you.
If your Web service doesn't know about user identity, and there's no external endpoint defined for the service -- then, yes, I'd not bother with ACS either.
Related
The Microsoft docs state:
Registering your application establishes a trust relationship between your app and the Microsoft identity platform. The trust is unidirectional: your app trusts the Microsoft identity platform, and not the other way around.
What exactly is meant by "trust" here and how does the app registration establish said trust?
The way I understand it the registration basically makes the app known to the AD, but how does that make the AD, the app is redirecting to for interactive logins, more trust-worthy to the app? Couldn't a malicious AD just pretend to know any app that's using it for logins? Wouldn't it need some kind of shared secret to assure the app that the AD really is the AD? And isn't HTTPS establishing that trust already?
It makes more sense to me the other way around: the AD receives a login request along with a redirect URI set by the app. But if the redirect URI is not known to the AD then the request is not trust-worthy and will be rejected.
I'm probably misunderstanding something, so could someone please explain the idea behind this?
In authentication world trust is a complicated word. In my opinion, the easiest way to approach this thing is taking the Google Sign-In -button as an example. You can use it to log in with your Google account on almost every website out there. Does this mean Google trusts every website out there using it? No, of course not. Do those websites trust Google? Sure they do, they have no visibility if Google returns the correct information about the users to them.
The case is very similar here as in most cases you will be using the same protocol to implement it (OAuth2 OIDC).
You are correct, you need to configure secrets & returnUrls to make sure that the App Registration is not used for malicious purposes, however, this does not create trust between the identity provider and the application. It's just technical measures to protect the client.
However, you can of course trust the application if you want to. The most common way is to grant it access to scopes so the application can do actions on behalf of the user. Usually this is done by those consent screens you probably know ("grant access to your email and phone number"). In enterprise setting, they are often omitted and access is granted with admin constent.
TL;DR; There is no inherit trust just because there is an App Registration, however you can trust an app to access user data.
Looking for guidance to understand the use case behind ForceAuthn=true for SAML-driven Single Sign-On.
We know that ForceAuthn=true will always challenge the user for credentials which creates friction thus negative experience for the user.
However, that's UX story. What about security?
If ForceAuthn=false, I authenticate once and the second time a seamless login will happen.
This might create an issue where unware user using public PC can leave the access open for the next person.
If you have are (or work) for a provider (e.g. SaaS) and have SAML-driven SSO with clients, what is your policy/experience around this topic?
It's not common for service providers to set ForceAuthn=true. As the service provider, it's not your decision on how to authenticate a user when you are entrusting that process to the identity provider. And, what happens when the IdP is using a non-interactive authentication mechanism like Kerberos? While they may see the redirects occurring, there's no user interaction with or without forcing authentication. Point being, if you're outsourcing authn, then outsource it, and then have the IdP indemnify you for anything around authentication.
What I do see service providers doing is using ForceAuthn=true to use as "singular transaction authorization" like for authorization of steps in workflows and digital signing.
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).
As with many applications, my service's authentication logic lives in the application code. Now however, I need to expand my authentication to incorporate 3rd party identity providers for single sign on.
I want to retain the old authentication behavior (database lookup) but also want to add support for 3rd party identity providers.
With this increase in complexity, does it make sense to separate the authentication logic to its own service? In this model the application server will redirect unauthenticated users to the authentication server. After authentication is successful, the authentication server will redirect back to the application server.
Is this approach sound?
If you have available servers and infrastructure budget, let your web application perform the authentication, using a community maintained library.
Generally its no recommended to build one by yourself.
Store your users in a database table.
Authentication using other sites problems:
Your visitor may not want to have an account with 3rd party site.
It results in giving too much information to the 3rd party site (who share much of it with other sites which use their authentication mechanism).
It is generally a good idea to separate your authentication logic and have a different service perform that task. This is also true for other 'cross cutting' concerns such as authorization and SSL offloading. It gives you a simpler development environment and in general an app that is easier to reason about (for example, you don't have to worry about authentication while in development mode and you can develop the services independently which goes a long way in terms of productivity and velocity).
In order to compose the authentication service with your application, it is better to have a third component that orchestrates and routes the calls accordingly (as opposed to having autentication related code in your application).
With the recent release of Azure AD, we would like to use Azure AD for our web application authentication, but we do not want to use SSO. We do not want users to be redirected to the Microsoft Account login screen, and then come back. We want to supply them with the login credential screen where we capture their username and password, and then we want to programatically do the authentication against Azure AD, and get back the claims identity.
The problem I have is that I cannot see how I can do that using the Graph API, and all the examples that look like it might work, only works on the previous [0.8] release. There is such a mix of examples that is supposed to work, but they don't simply because of the new release.
Can anyone tell me if this is even possible, and maybe point me in the direction of how to do it please.
I do not want to use ACS.
What you are asking for is not technically possible with Azure Active Directory today. That scenario could possibly be supported in the future, so check back from time to time.
We really encourage developers to rely on the in browser sign in experience. The reason is that because the browser allows the server to define the experience, it allows for much greater flexibility with respect to the kinds of credentials that can be employed. For instance, if you code your app to use only username and password, then it may need to be updated in order to take advantage of two factor authentication. If you rely on the browser based experience then your app can be totally agnostic to whether 2FA is being employed, or any other kind of authentication dance.
We recognize that there are some scenarios where this is not ideal or even practical and are looking at solutions to those scenarios that may be supported in the future.