I am using Azure AD, in which access token comes to teh redirect URL when the user is successfully signed in into their Microsoft account. Can we avoid getting this token in the URL, and get it somewhere else? Or is there any different approach required for this?
As if someone gets that token, they can hit the backend server of my application and can get data.
Your concern is well-founded, but receiving a token in the redirect URI is central to how OAuth flows work, regardless of whether that's Azure AD or any other OAuth IdP.
From an OAuth redirect URI overview:
Because the redirect URL will contain sensitive information, it is critical that the service doesn’t redirect the user to arbitrary locations.
The best way to ensure the user will only be directed to appropriate locations is to require the developer to register one or more redirect URLs when they create the application.
You're redirecting them to a source you control, using an encrypted channel, and that's considered good enough for current Internet security operations.
Related
We have a backend service that can return a json result (Elasticsearch result) or an interactive browser web page (Kibana) based on the route. This service is gated behind an API Management service. Our developers need to be able to access the web page (Kibana). We are currently using a client certificate and we have it set to require this in our API definition. When browsing to the path in the browser, the user is prompted for the cert and the connection is made.
I would like to get rid of having to manage the certificate and instead use AAD to allow only users in a specific group to be able to access. I understand how to do this when making an API call. Is it possible to also have an experience similar to the cert where if the user is not logged in, they are prompted to log in, and then if they are in the correct group, access would be allowed?
Thanks
I imagine you want to enforce authentication at APIM level and not in Kibana. For that you'll have to handle two flows:
Initial flow, when non authenticated user requests URL, you should of check for persistent auth, possible in Cookie header and if not found - redirect user to login.microsoft.com.
Returning flow, when Azure AD redirects user back to APIM with a token, you'll need to validate that token and add it to Set-Cookie header, better encrypted.
And finally when any call is made also check and validate the cookie to see if it has expired.
I'm integrating Azure Active Directory into a cloud platform. As our application is multi-tenant and relies on platform-specific claims, we've identified the simplest way to go about this is get an Azure AD token via our SPA, pass it back to our WebApi, validate it and return to the SPA a platform token with all the claims we need to go about our normal business (as if it was a simple username/password athentication request).
I'm concerned at the level of security for this though.
Some Context
As our platform is multi-tenant, we request that clients each register the application on their Azure AD portal, then supply us with the generated Application (client ID) and Directory (tenant) ID. We use these two pieces of information to make the initial request to Azure via our front-end SPA (following the node.js example provided by Microsoft's Quickstart guide when registering an app). Now because the user is unauthenticated at this point, we needed some way to return those two specific ids for the client. We have accomplished this using a sub-domain for identification.
E.g. acmeinc.mydomain.com will return a different Application (client ID) and Directory (tenant) ID than billy.mydomain.com. These are obviously public now as this request happens from an un-authenticated front-end route.
I can handle the token response just fine, both in the front-end and in the back-end when I pass it along, and validate that these two pieces of information are correct in the token, but seeing as the front-end is given them to begin with, validation on these is redundant. Also, validating the issuer seems equally redundant as someone who knows the Directory (tenant) ID, can fake that too (right?)
Am I missing something here? I would feel far more at ease if it were possible to request the client also include a claim that my platform generates privately such that I could validate this claim alongside the normal JWT validation. Custom claims do not seem possible from the Azure AD Portal.
Am I missing a critical step, or just overthinking this?
Someone cannot fake the issuer in the token because the token is digitally signed.
Without the private keys of Azure AD, it isn't feasible to generate a valid signature.
Without that, any modifications to the token will be immediately noticed because the signature does not match.
Your back-end should already be validating this signature if you are using standard JWT validation.
Requiring customers to register an app in their tenant is a bit of work that I would prefer not to put on them.
Have you considered making your app a multi-tenant app in Azure AD?
That way your customers could login to your app, consent to the permissions required, and start using it. Without needing to manually register anything.
This could be done in an on-boarding flow where the user signs in, and then they can decide what sub-domain they want.
You will at that point know their tenant id, which you can store. So in the future you can always use the correct tenant/directory id when signing them in.
The downside of this approach is managing the reply URLs.
With the specially registered apps, they can register their own sub-domain version as a reply URL.
With this generic multi-tenant app, you'll need to manage them.
And you can't add an infinite amount of them, and wildcards aren't supported anymore either.
So, your authentication would have to happen with a generic authentication reply URL like auth.mydomain.com, from which they would be redirected to their tenant URL.
I'm new to using Azure Active Directory authentication with a Web API. Right now the login page on my Single Page Application simple directs the user to the Microsoft login page where they enter their credentials and then are redirected back to my SPA. Upon the redirect the access token is now part of the URL. Is it possible to get that token via JSON rather than part of the URL? Is that a security risk making the token visible to user like that? If there is no other way to get the token what's the best way of processing that? Should I read the URL and pull the token from there and then redirect the user again to the actual website?
You have to be mindful in implicit flow the token will still be maintained at the client site (local storage normally). So even if you are hiding the token from URL , you still will be storing at client side and that's one of things you have to manage in SPA. You will have to send token with every HTTP request to your web api to get that authenticated on that end.
In implicit flow tokens are shortlives and you can't issue refresh token for longer period of access. For this kind of flow you need to use official library (ADAL.js)
https://github.com/AzureAD/azure-activedirectory-library-for-js
More resources
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow
You can use ADAL.js library to acquire the token. There is a pre defined function which you have to call after the Ad authentication or at the beginning check if you are logged in, you can use isauthenticated function to check if you have already logged in, and use getaccesstoken function to acquire the token after authentication.
Why does the redirect URL have to match completely? Wouldn't matching at the domain level be sufficient enough for proper security?
What if I had hundreds of paths?
example urls:
https://myawesomesite.com
https://myawesomesite.com/account/profile
https://myawesomesite.com/games/fungame/points
https://www.myawesomesite.com/games/fungame/points
...
I would have to enter the 4 above redirect urls into my B2C app configuration.
It is common (and easiest) for all authentication requests to contain two redirect URLs:
One (often known as the reply URL) that is passed in the "redirect_uri" parameter, which must be registered with Azure AD B2C, to which all authentication responses are returned from Azure AD B2C to the relying party application. An example of this is https://www.myawesomesite.com/oidc-signin.
Another (often known as the return URL) that is round-tripped in the "state" parameter, which doesn't have to be registered with Azure AD B2C, to which the end user is returned after the relying party application has handled the authentication response. An example of this is https://www.myawesomesite.com/games/fungame/points.
An authentication handler, such as the ASP.NET Core authentication middleware, manages these redirect URLs for you.
For instance, when the authentication handler creates the authentication request, it encodes the currently protected URL (e.g. https://www.myawesomesite.com/games/fungame/points) in the "state" request parameter.
To ensure this URL isn't tampered with, the "state" parameter should be protected, using encryption or signing.
When the authentication handler processes the authentication response, assuming it is a successful response, it creates an identity cookie and redirects the end user from https://www.myawesomesite.com/oidc-signin to the originally protected URL in the "state" response parameter.
This is actually discussed in RFC 6819 "OAuth 2.0 Threat Model and Security Considerations" sections 4.1.5, 4.2.4 and 5.2.3.5.
4.1.5. Threat: Open Redirectors on Client
An open redirector is an endpoint using a parameter to automatically
redirect a user agent to the location specified by the parameter value
without any validation. If the authorization server allows the client
to register only part of the redirect URI, an attacker can use an open
redirector operated by the client to construct a redirect URI that
will pass the authorization server validation but will send the
authorization "code" or access token to an endpoint under the control
of the attacker.
Impact: An attacker could gain access to authorization "codes" or access tokens.
Countermeasures:
o Require clients to register full redirect URI (Section 5.2.3.5)."
Section 5.2.3.5 talks about the cases where this may be too restrictive and purposes alternate solutions.
Often times, the state parameter can also be used to redirect deterministically as suggested by Chris. However, you have to ensure that such a solution also does not end up being an open redirector, so the state parameter will either need to be protected (e.g. encrypted/signed), or used in conjunction with cookies.
In my case, company B (domain B) hosts a portal, which has link to my web app (domain A). If user clicks on hyperlink on the portal to my domain, he/she should be automatically logged into my app.
Existing poilicies that i cannot change:
User also has the ability to log into my domain directly, without going through the portal by supplying user id/password.
Also, existing company policy for user provisioning is that even if user log through portal of company B, they first need to have a user account with my company. Hence, the user will have account with portal company and my company.
Given these constraints, my plan for is following to provide automatic login from the portal.
When the user logs in to the portal, the portal company will generate a temporary token (UUID) and attach it as a query parameter to the hyperlink to my web app. When user clicks on my web app's hyperlink, my web app will receive a GET/POST request on the server side for a protected resource. At the server side, my web app will over https (probably two way SSL) invoke a URL on the portal's side, passing the temporary token. The portal side responds with a user id. My web app will map the user id with user's credentials and create a session for the user and allow access to the protected resource.
When the user logs out of the portal application, the portal server will make an Https request to my web app at a prespecified URL to log the user out. Since it would be two way SSL, logout url is protected.
My questions are following:
Is there a standards based approach to achieving the above scenario. In near future, my company is planning to support OAuth 2.0 and i want to ensure that the above scenario will not violate any OAuth standard. As per my understanding, OAuth 2.0 leaves the validation of the access-token to the implementations. I am hoping that the temporary token described above is sort of access-token.
Once the user closes the portal browser, is it possible for browser to destroy the cookie. In this case, if user opens another browser later on, he/she should authenticate again.
Is there a standards based approach to achieving the above scenario. In near future, my company is planning to support OAuth 2.0 and i want to ensure that the above scenario will not violate any OAuth standard.
You kind of like answered your question already. That "standard-based approach" is OAuth which a Standards Track already documented by IETF in RFC 6749 and has been adopted by many software entities. If you don't implement OAuth then you are not violating the standardisation rules, you will be violating it if you claim to have implemented OAuth authorization in your system which clearly you haven't.
As per my understanding, OAuth 2.0 leaves the validation of the access-token to the implementations.
Well, OAuth is a bit more complex than just generating an access token, there's an authorization grant request involved before you can request an access token. You could also expose a token refresh endpoint if the life span of the access token needs to be extended by the client. So, there's more than just access token requests involved in OAuth authorization process
I am hoping that the temporary token described above is sort of access-token
What's an access token? It is up to you how you implement an access token, the implementation details belong to you and nobody else. The only thing that you need to guarantee is that the access token represents the authorization issued to client and its scope, in other words, given an access token your system should be able to identify a client and the scope of this client...what the client is allowed to do, what resources the client is allowed to request. Be aware that OAuth defines clients which doesn't directly translate to users, it could well be a user, another system, component or app.
Once the user closes the portal browser, is it possible for browser to destroy the cookie. In this case, if user opens another browser later on, he/she should authenticate again
Absolutely, yes. This is not related to OAuth at all, it's up to the client what they do with the access token and how they store it. If your system issues a non-persistent cookie, then as soon as the user closes the browser then the browser session is destroyed and also the cookie. All modern web development technologies offer cookie management implementations such as JSP, ASP.NET, PHP, etc. So I would suggest to store the access token in a non-persistent cookie and have your authorization server inspect requests to all protected resources by checking for the authentication ticket/cookie (where the access token is) and validate the access token, if the access token (or cookie) is not present then reject the request since it is an anonymous request to a protected resource.
Hope it makes sense