Monthly Archives: January 2020

Power App Portals, Azure AD B2C, and external identities

Before you read this post, let me suggest two earlier posts first, since they are all part of the same series:

Power App Portals have identity management functionality available out of the box. What it means is that the portals can use local identities, but they can also use external identities (azure, google, facebook, etc). All those identities can be linked to the same user profile in the portal (contact record in CDS):

image

Once a portal user has logged in using some kind of authentication, they can manage their other external authentications from the profile page:

image

For example. I just set up Azure AD B2C integration for my portal (have a look at the previous post for more details). However, I did not limit portal sign in options to the azureb2c policy only (through the LoginButtonAuthenticationType parameter), so “local account” and “Azure AD” are still there:

image

If I sign in through Azure AD, I’ll be able to connect my other external identities to my portal profile – in this case I only have azureb2c configured, so there are not a lot of options, but I could have configured google and facebook, for example, in which case they would be showing up on the list as well:

image

This is where the difference between using Azure AD B2C as an external identity provider and utilizing those other “individual” identity providers becomes clearer.

When Azure AD B2C is available, it’s likely the only identity provider the portal needs to know about, so it only makes sense to instruct the portal to use that identity provider all the time through the following site setting:

Authentication/Registration/LoginButtonAuthenticationType

image

When done that way, “sign in” link on the portal will bring the users directly to the Azure AD B2C sign in page:

image

So… there is no Azure AD or other options there? This is because I now need to go back to the Azure AD B2C and configure required identity providers as described in the docs:

https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-add-identity-providers

Note: it seems Azure AD application setup instructions provided there might not work as is, at least they did not work for me. When specifying the redirect url for my Azure AD application, I had to use the following format:

https://treecatsoftwareb2c.b2clogin.com/5cb9b89d-d5d2-4e31-….-e82a2cf12121/oauth2/authresp

That ID in the url is my Azure AD B2C tenant ID:

image

Otherwise, I kept getting an error when trying to authenticate through Azure AD since the redirect url specified for my application was different from the redirect url added to the request by Azure AD B2C when it was “redirecting” authentication to Azure AD (Uh… would be good if you are still following me, since I seem to be loosing it myself in all those redirects).

Anyway, once I’ve done that, Azure AD is now showing up as a “social account” sign in option on the Azure AD B2C sign in page:

image

If I use it to sign in, that brings me to the other screen:

image

Another note: I did not enable email claim on my B2C signin flow, so, at first, once I passed through the screen above, I got the following page displayed on the portal:

image

This is not how it should be, so, if you happen to forget to enable that claim as well, just go to you Azure AD B2C portal, find the signin policy you have set up for the portal, and add email claim there:

image

Once I’ve done that, though, the portal is complaining again:

image

But this is normal. The portal is not allowing a registration for an email that’s already there – remember that original portal account was using Azure ID external identity; however, right now I’m trying to register with an Azure AD B2C external identity, and it’s different. So, the portal is trying to create a new contact record in CDS with the same email address, and it can’t.

There is a portal setting that allows auto-association to a contact record based on email:

https://docs.microsoft.com/en-us/powerapps/maker/portals/configure/azure-ad-b2c#claims-mapping

If I wanted to enable that setting, I would need to add the following site setting to the portal my Azure AD B2C external provider (and set the value to true):

Authentication/OpenIdConnect/azureb2c/AllowContactMappingWithEmail

Finally, once that is done, I can now login to the portal through Azure AD B2C… but still using my Azure AD identity.

Since I did set up the portal (see above) to use Azure AD B2C exclusively, I don’t see my other external identities (or the local portal identity) on the profile page:

image

However, behind the scene the portal just created another external identity for my contact record:

image

It’s almost all good so far except for one remaining question (I know there are more questions, but this one is important). Having the portal integrated with Azure AD B2C, I would think there should be some easy way to link multiple external identities to the same user account. Basically, what if a portal user had different external identities(Azure AD, Google, Facebook, etc) and wanted to use either of them to login into the same portal account?

While identity management was done by the portal, it was possible to connect external identities from the user profile screen.

However, since I have just outsourced identity management to the Azure AD B2C, that kind of linkage would have to be done through Azure AD B2C now.

This seems to be what the github repository below is meant for, but I am certainly going to have to spend some more time on it:

https://github.com/Azure-Samples/active-directory-b2c-advanced-policies/tree/master/account-linking

And this will have to wait until the next post.

Power App Portals and Azure AD B2C

The whole reason I started to look into the details of OAuth in the previous post is that I really wanted to see how to set up external identity providers for the portals.

There are some great blog posts out there which are describing the process in a step-by-step kind of way with all the necessary screenshots:

https://readyxrm.blog/2019/07/24/configure-azure-ad-b2c-for-powerapps-portals/

There is a documentation page as well which can walk you over pretty much the same steps:

https://docs.microsoft.com/en-us/powerapps/maker/portals/configure/azure-ad-b2c

What I was looking for is a bit better understanding of what’s happening behind the scene, though.

As a result, I think there are three items to discuss in this post:

  • OpenID Connect
  • Azure AD B2C
  • Setting up the portal to work with Azure AD B2C

 

But, again, if you have not looked at the OAuth, or if the term “implicit flow” still sounds too alien to you, have a look at the previous post and all the references there.

Because here is how it all works:

  • We can configure portals to use Azure AD B2C as an identity provider
  • Azure Active Directory B2C is a service from Microsoft that enables external customer sign-ins through local credentials and federation with various common social identity providers
  • Portals do support Open ID Connect, Azure AD B2C does support Open ID Connect… so there you have it: one can work with the other using Open ID Connect

 

What is Open ID Connect, though? It’s an extension of OAuth to start with, so we are still talking about all those client id-s and implicit/code flows. However, when utilizing Open ID Connect, we can get not only the authorization token, but, also, the so-called id_token. Which will actually represent user identity – there is a nice walkthrough in the post below if you are interested:

https://connect2id.com/learn/openid-connect

Azure AD B2C supports Open ID Connect: https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-reference-oidc

Portals support Open ID Connect and can be configured to work with Azure AD B2C: https://docs.microsoft.com/en-us/powerapps/maker/portals/configure/azure-ad-b2c

What’s interesting is that Azure AD B2C can also work as a “proxy” between the portal and external identity providers:

image

https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-overview

Even though those external identity providers have to be configured in your instance of Azure AD B2C, since, from the external identity provider standpoint, your users would have to authorize Azure AD B2C to access user identity information. So, for example, for the identity providers which are relying on OAuth, you’d have to go over the regular client registration steps to get client id & client secret so you could set up those providers in Azure AD B2C:

image

As I mentioned before, Azure AD B2C will work as a “proxy” in that sense. The portal will ask Azure AD B2C for the user identity, but Azure AD B2C will offer your users an option to authenticate through a configured external provider (and the portal does not need to even know about it).

Which may give you the benefit of single sign-on between the portal and other applications using Azure AD B2C(no matter if, ultimately, your users are using google/facebook/twitter/etc identity).

As a side note, what if you did not have Azure AD B2C and still wanted to use Google for portal authentication, for example? That would still be doable:

https://docs.microsoft.com/en-us/powerapps/maker/portals/configure/configure-oauth2-settings

With all the above, it should be easier now to answer some of the questions about all this set up process, such as:

Why do we need to register an app (OAuth client) in Azure AD B2C for the portal?

That’s simply because it’s OAuth, and we need a client id to make requests to the OAuth server

Why do we need to register an app (OAuth client) in Google if we wanted to add google identity provider to Azure AD B2C?

That’s because Azure AD B2C will be using OAuth to request authorization from the google OAuth servers for the usage of google profile API-s etc

Why would we choose Azure AD B2C over other external identity providers?

Essentially, this is because we’d be outsourcing identity management to a separate service that has a bunch of useful features available “out of the box”: https://docs.microsoft.com/en-us/azure/active-directory-b2c/technical-overview

 

As for setting up your portal to work with Azure AD B2C, I’ll just refer you to the same two pages I mentioned earlier in this post:

https://readyxrm.blog/2019/07/24/configure-azure-ad-b2c-for-powerapps-portals/

https://docs.microsoft.com/en-us/powerapps/maker/portals/configure/azure-ad-b2c

PS. There is a continuation to this post here – you will find additional details on how to set up the portals with Azure AD B2C, and, yet, how to enable additional external identity providers through Azure AD B2C: https://www.itaintboring.com/powerapps/power-app-portals-and-multiple-external-identities/

Have fun!

OAuth, Implicit Flow, and Authorization Code Flow

If you ever tried registering applications in Azure, you have probably seen the term “implicit flow”. I’ve seen it a few times, and, finally, I’ve figured I need to get to the bottom of it. What I ended up with is the post below – it’s not meant to cover OAuth in details, but it is meant to provide a conceptual explanation and required references, even if only so I would know where to look for all this information when I need it again. If you find inaccuracies there, please drop me a note.

The purpose of OAuth is to provide a way for the users to authorize application access to various API-s. Once the authorization is provided, a token will be issued which the application will be able to utilize to call those API-s.

It all starts with registering a client (which is represented by a client id) on the authorization server. That client is normally set up to require access to certain API-s. However, required access is not granted automatically – it’s the user who has to authorize the client first.

So, you might ask, why can’t we keep utilizing user identity all the time? Why introducing those client id-s etc? Actually, it’s just a matter of reducing the “attack surface”. For example… As an Office 365 user, you might be able to access Common Data Service Web API, SharePoint API-s, Exchange API-s, and a whole lot of other services. However, when authorizing a client, you will only be authorizing access to certain API-s (so, an authorized client app might get access to the CDS API-s, while it won’t have access to the Exchange API-s).

Now, imagine there is a web page, and there is a JavaScript that needs to call certain API. When the page is loaded, it should not be able to just call that API – some kind of authentication and authorization has to happen first. Imagine there is an OAuth server, and there is a client registered there which can access required API-s. The idea is that, knowing the client ID, our imaginary web page needs to do a few things:

  • It needs to somehow ask the user to authenticate and authorize the usage of that client (which essentially means providing authorization to access those API-s)
  • Once this happens, it needs to somehow confirm to the API-s that it’s been authorized to use them

 

Let’s assume for a moment that the authentication and authorization has already happened. How does the second part work?
That is, actually, relatively straightforward (at least conceptually). On the client side, we just need to add authorization token to all API calls as a request header:


POST /api?param=123 HTTP/1.1
Host: apiserver.com
Authorization: Bearer AbCdEf123456

It will be up to the API to validate those tokens – for example, the API might just confirm token “validity” with the authorization server. Well, if you want to explore this topic a little more, have a look at this post:
https://dzone.com/articles/oauth2-tips-token-validation


But how does our imaginary web page gets that token to start with?

That’s what happens as part of the authorization grant, and this is where things get messy since there are different authorization grant flows. In other words, there are different ways our web page (or our application) can get a token from the authorization server.

You’ve probably spotted two of those authorization grant flows while looking at the Azure B2C configuration, or while trying to create app registrations in Azure portal:

  • Authorization code flow
  • Implicit flow

 

However, even though the authorization server might be able to support different authorization grant flows, not all of those flows might be supported on the client side.

There is a detailed explanation of how those flows work in the following post:

https://developer.okta.com/blog/2018/12/13/oauth-2-for-native-and-mobile-apps

I’ll copy one of the images from the post above just to illustrate, quickly, what’s happening in the implicit flow:

Implicit Flow

There is a bunch of redirects in this flow. You will open the browser, it will load the page, and the script in that page will realize that it needs to get a token. So, the script will redirect your browser to the authorization server, and, as part of that redirect, it will also specify that it wants to use implicit flow by passing “token” for the “response_type” in the query string:

https://alexbilbie.com/guide-to-oauth-2-grants/

From there, the user will provide the authorization, the token will be issued, and it will be sent back to the client browser as a url fragment…

What’s a url fragment? That any part of the url following the ‘#’ character. URL fragments are special since browsers won’t add fragments to the requests – instead, fragments live on the client side and they are available to the javascript running on the browser side. If you are interested in how fragments behave, have a look at the post below:

https://blog.httpwatch.com/2011/03/01/6-things-you-should-know-about-fragment-urls/

That reduces the “exposure” of OAuth tokens on the network, so this flow becomes more secure. However, it is still less secure than the other one (authorization code flow), and, actually, it’s been deprecated:

https://oauth.net/2/grant-types/implicit/

Why was it introduced in the first place, though? This is because authorization code flow usually requires cross-domain calls, and, come to think of it, cross-domain calls from javascript were not really supported when OAuth was introduced.

Things have changed, though. JavaScript-based applications should not have a problem utilizing cross-domain calls today:

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

Although, there is probably still a lot of apps which have not been migrated, so implicit flow may still be needed in many cases.

There is one important aspect of the authorization flows which I have not mentioned so far, and it’s the “redirect url-s”.

Imagine that our web page has redirected the browser to the authorization server, the user has provided required authorization, the token is ready… where should the authorization server “redirect” the browser now (since it’s all happening in the browser in this scenario)? This is what redirect url-s are for, and, if you are interested in a bit more details, have a look at the page below:

https://www.oauth.com/oauth2-servers/redirect-uris/

Hope this helps, though, as usual in such cases, somehow I have a feeling there is still more to it:)

PS. There is a continuation to this post here: https://www.itaintboring.com/power-platform/power-app-portals-and-azure-ad-b2c/