Video details

Demystifying Azure AD, JWTs & OIDC - Graeme Foster - NDC Melbourne 2022


OIDC and OAuth2 have been the goto for authentication and authorisation Azure Active Directory for years now. But when things start to go wrong, it can all become a bit of a black-box with no obvious place to look for help.
In this live-code session I will uncover some common errors I see when setting up applications to work with AAD, and dive that next level down to give you an understanding of why they occur, and how to fix them.
By the end of the session you'll understand - What an AAD Application is, - What an AAD Service Principal is, - MSAL vs ADAL - The difference between AAD V1 and V2 endpoints - How AAD represents OAuth2 scopes, - Why scopes aren't permissions, and how roles can help
Check out more of our featured speakers and talks at


Cool. I'm getting the thumbs up. I think we're good to go. Yep. Awesome. So, hi everybody. Thanks for coming to my talk this morning because there's some really good talks on in those other rooms. So there's a moment where I wonder if anyone was going to walk through that door. So I'm feeling quite pumped now. She's really good and it's so good to be back to an inperson conference as well. So that's also fabulous. So today we're going to be talking about Azure Active Directory. JWTs OIDC PKCe, claimed scopes, all these fabulous identity concepts. So I'll give you a little bit of information about myself before we get cracking. My name is Graham and I work as a cloud solution architect at Microsoft. I've been there for about two years now, but to be honest, have you taken an architect title? Was a little bit kind of like, weird. I've been a developer engineer for 25 years before that and managed to resist being an architect, but here we are. That's okay. I still managed to keep relatively hands on, which is good. Now, in those 25 years, I've seen a lot of different ways of dealing with identity authentication and authorization. If you think back many, many years ago, we all used to roll our own username password databases, right? Pretty insecure stuff, but we had them. Every application had its own username password database. Not a good place to be in. Then we had Active Directory. A lot of people might still have to use that today. It's still everywhere, really. But we fast forward, we go through LDAP. Anyone in here has tried to roll their own secure token server. That's a barrel of fun and really, really unpleasant experience if you've ever tried that. And about 15, maybe 1015 years ago, there was a real change in the industry where this thing called all off Two suddenly came along and anyone who's been in the WS Star WS Federation world will know that that was a criminally, horrible place to be in. Like really, really disgusting, really complicated, just enterprise to the extreme. And all of two came along with the idea of really simplifying a common story, which was, I've got something like Facebook, I've got a third party client, I've got users who have data on Facebook. How do they access that? Now, luckily, most applications today start with OLF Two, oridc it's super simple to get going on it, right? And what I don't want to do today is take you through that kind of, let's get started, let's set an application up. In my job at Microsoft, it's not uncommon for me to get calls from customers who have got problems with their OIDC flows. And what always strikes me is that whenever we set this up, there's about three different things that are involved in it. We've got Azure Active Directory. It could be any identity server, to be honest. It could be all zero. It could be your own custom rolled Doende, whatever, doesn't really matter. But there's this thing, it's managed by a team. We've got our client applications and then we have our users. And we always have teams that focus on those individual boxes. But where it gets complicated is that everything has to be just right between those three boxes for everything to work. And when it's not, people often don't know where to look or how to go about diagnosing these issues. So that's really the main focus for my talk today. So I want to COVID the tools and techniques and show you some of the common classes of errors that I see all the time in the wild when people are trying to set these folds up. We're going to talk about a flow called PKCe. So if you're building web applications or native applications, it's something that if you haven't heard about, you really want to start thinking about moving to it. We're going to break down JWTs, have a look what's inside them, and we want to think about how those concepts in those tokens relate to identity and authentication and authorization. And finally we'll look at scopes and groups and roles and have a think about what they are and again, how we can use those to kind of build authorization into our applications. Now, when I do a talk, I kind of like to come up with a scenario to hang my talk off. And I gave a smaller version of this in December, and it was Christmas, so I kind of had a bit of a theme going on with Santa Claus and how do we make sure Christmas is a success? So I'm going to rebadge that today because it's Australia and Christmas in July is obviously coming up. So we're going to use a fictitious application that Santa and his elf built to show you the kind of errors and how to go about diagnosing them. And here it is. Now, it's a really common type of thing that I see in customers. Essentially, Santa used to use an application called Santa Web to manage Christmas. So that would handle problems like the traveling Santa problem. How does he get around to all those houses on Christmas Eve? That's quite complicated. Naughty. Nicely. It's very, very complicated. Business logic that is locked up inside a legacy application, heritage application, let's call it. In this case, Santa Web was written in ASP web forms. It's pretty old. It had its own clunky username password, and Santa was managing a lot of infrastructure. So he decided to move all of this into the North Pole Data Center. I think I've called it azure. North Pole data center. I don't think we have an Azure North Pole Data Center, but it would be kind of cool if we did. And in doing that, the elves turned Santa Web into a pass, made it run on that service platform as a service, whatever. It doesn't matter which one it is, but they also look to do a few extra things. You see, Santa was going for a digital transformation at the time, just like most customers, most companies out there in the world today. So they outsource their identity. They've decided to use Azure Active Directory to do that and they've realized that the UX is clunky, so they wanted to unlock the possibility of new user experiences. So what they've done is they've created a whole bunch of APIs which are decoupled from the ASP on their web forms to support new modern experiences that we want to build. On top of that. Now just so happens there's another crack team of elves who fancied themselves as User Experience Deliverers and they're very competent in React in this case. So they want to build Santa Lite, which is a single page application and it's going to consume those APIs from Santa web to make Christmas a beautiful experience. So the idea is they're going to use OIDC authentication flow to send users into the application and then they're going to use OAuth Two and get access tokens to call Center Web APIs on behalf of Elf and Sensor. So one of the key things in there is a word called token. As we'll see through this talk, tokens are really the core currency of identity authentication and authorization when we're dealing with Oworf and OIDC. So that's the example I'm going to use. And what we're going to do is we're going to have a mix of kind of coding and a bit of kind of talking and showing you those tools and techniques to help find out what's going wrong. Because I heard on the ground that they have some issues. So we probably should jump into the code and see if we can find out what's going wrong to help the else. Okay, so let's start in Vs code. This is going to work. The demo gods straight away. There we go. Awesome. Cool. Now the Elsie started to use React to write their application. And when they started, they were faced with their first choice they had to make. So whenever you're dealing with all of two, you don't want to roll your own library to handle tokens and deal with all the validations and checks and balances because it looks deceptively simple on paper, but there's a whole bunch of security things that are built into those tokens. So you're best off going for a third party library to help you deal with that. Now in the Microsoft space, we have two, we have one called Adal and we have one called MSEL. And it just so happens that the elves made the right choice in that in this scenario, they decided to go with Mcell. We can see that inside their package JSON. They've chosen a dependency called Whoopsie, MSL browser and MSL React in this case. Now that's great because MSIL supports more modern secure flows which are not supported by Adele. So be very confident when you make this choice that Ms the right way to go. The reason I brought this up is because I was doing a search on NPM the other day, which is the node package manager, and it was quite interesting to see if I can make my mouse work. But when you go to Adele Node on NPM in the last week, there were 411,000 downloads of that package. That has essentially been deprecated for about the last nine months. It's on life support. So that's a lot of potential applications out there that are using inherently insecure flows. And that's not really a place where you want to be. That's okay. They also chose right, they've gone with Mcell. So when they started, they had to set a couple of little parameters inside their code to wide this all up and to get it going. It's pretty straightforward. This is kind of a bare bones setup for an M cell application. There's two bits of information we need, both really common definitions. Inside OIDC we've got the authority and the client ID. Now the authority tells our MSR library where it needs to go to deal with authentication and authorization scenarios. Now, in this case, it's Azure active Directory. So everything goes to a hostname called Login Microsoft Now, if you're all zero, you're on your own identity server. That's going to be a little bit different. In fact, on those types of service, you tend to have your own dedicated host name. We don't have that in Aid. We have a CommonHost Login, and then there's a grid after it. So that's your tenant ID. Now Aid is a massively multitenanted identity platform. So there are lots of other customers that also are inside there. So that's just how we can make sure that it's you that we're working with when we are doing authentication scenarios as opposed to other customers. Now, the second bit of information is called the Client ID. So this is a really, again, common concept in Oidcflows in that every application that wants to either get tokens or look at tokens inside OAuth, two is referred to as a client. So again, you'll have a client for every single application via a back end server or a single page application that you build. And these all have to be registered inside Azure Active Directory. It's the first bit of configuration that we need to line up. So if you just remember a four, seven and be three, we're going to quickly jump into the portal and have a look at those inside AAD. So this is Graham world. My own AAD tenant. And you can spin one of these up really easily. In fact, if you're in an enterprise, it's quite often useful to spin up your own tenant because you can then do a lot more. I'm quite restricted. There's a lot of things inside Ad I can't do inside my company tenant, but I can in my own for a learning experience. It's a really good idea. Here's my tenant ID, a four seven, and then we have these things called app registrations. Now, AAD doesn't just do OIDC, it does WS Federation, it does SAML, it does a lot of different authentication mechanisms, but that predate owed to. So it's the first point of confusion. We don't call them clients in aid, we call them app registrations. But Santai is the be three one down here. And as long as those two bits of information, your tenant ID and your client ID map up and you can see we even call out it's your application. But yeah, it's really a client ID as far as OIDC is concerned then we're now in a situation where we can start to authenticate users. So let's jump into our amazing, I told you they were a good team of designers that we had with the ELFs. This is Santa Light and we're going to start a sign in flow and see what happens. So we click on the button and the internet is working. So that's a good start. We instantly get taken to log in Microsoft Online with a 47, which is our tenant ID. And there's a bunch of query string parameters that we'll look at in a minute. But the point is, Santa Lite is now taken as a way to aid to start the sign in process. So I'm going to go and grab Santa's credentials and get prompted for usernames and passwords. So again, which part of this is. Actually providing that UI? Is that the OIDC? So this is Azure Active Directory that's providing this UI and you can't customize this one, but if you're using B to C, which is the consumer identity, then you can customize that a lot more, gets a little bit confusing. We can talk more about that offline if you want as well. B to C and AAD. So we click the sign in. Now the first thing that's happened is AAD has been asked by Santa Light to ask the user to consent to provided some information. So this is the crux of OAuth Two. Basically, I'm a user. I want to use a third party that wants to do something with my identity. So it asks Azure Active Directory to ask me on its behalf to do that. In this scenario, I am being asked that Sunto Light wants to sign in and read my profile. Okay? So let's click accept on that and straight away. Now this is a really, really simple problem to solve, but I do see it all the time. So being told that the redirect Uri Santa like local test me does not match what's inside Azure Active Directory. Now if we go back to the start of OAuth Two, let's think about what's going on here. I'm an application. I'm being directed to Azure Active Directory to do something to sign in when that's done, AAD needs to take me back to my application and send back some information, which is one of these tokens that we spoke about in the olden days. OAuth Two said nothing about where that callback had to be. So a lot of authservice supported what we call wildcard redirects or open redirects. But that's a really bad security hole. Imagine if the Grinch spun up his own Santa lite copy, looked like Santa life, and he could get an elf to go and sign in in Azure Active Directory, which would then blindly redirect to Grinch localtest me and pass an identity token or an access token. You can start to see how Christmas could get spoiled because now that token's in the hand of the Grinch. So for Azure Active Directory to complete a sign in, we need to not only tell it at the point of doing the sign in where to redirect to, but it has to understand where those redirects are upfront. And if it doesn't know the redirect, it won't do it for you. So that closes a security hole. It's one of the areas where open ID connect actually really kind of not just fixes, but makes a lot of the original OAuth Two. It locks it down. It makes it much more safe to use. So in this scenario, we're going to go back into the portal in Azure Active Directory and we're going to go to should have got a piece of paper for my mouse map. We configure redirect Uris against the application. And in this case, we can see we've got one single page application. And straight away you can see that this is not the one that was requested by the app. It's actually got sign in OIDC. So I'm guessing it elsewhere. It originally using, like, an ASP net service site application. Potentially that's a common URL we see in them. So this one is pretty straightforward. We're going to remove the suffix that we don't want and we're going to save that. And we're going to go back to our application center like and we're going to do the sign in again. Santa lesson for my next talk, make sure to have a mouse map by the computer. My optical mouse doesn't like this, and boom, we're in. My application knows that it's centered. So what just happened? Well, there's a few ways we can have a look at the different URLs and the different payloads that were invoked to make this work. I'm going to use a tool called Fiddler. Okay, but first of all, let's have a quick look on a PowerPoint slide of what's going on here. So we start off with our single page application. We click the login button. The first thing that happens is we get a 302 redirect. This takes us to AAD with three main bits of information. We've got what the application wants aid to do, which is in this case, assigning our users we've got the where to send me back to that's, the redirect Uri. And then we've got a whole bunch of information around security concerns like state and nonsense and things like that that just help with the checks and balances to make sure that things are okay. Now, one of two things is going to happen for a native application, depending on the flow that you're using. If you're in Adele world or you're using a flow called the Implicit flow, azure Active Directory is going to send you back to Santa Lite with a token. Now that token normally is stored in something like a hash fragment. This flow is not recommended anymore. It's got real security concerns around it with that token inside that fragment. So to give you a few examples of that, let's say you're in an enterprise that has got some SSL traffic sniffing firewall or something like that. It might intercept this and log the URLs to disk. So that could be a potential source of an ID token being leaked in there because it's in the URL. Or if you're a native application, I don't know who's done native apps here, but you can configure application specific protocols on your apps such that if you invoke a URL on your device, that will launch your application. Now the problem with those is that unless you're Google or Facebook, you don't get DIVS on that application Uri. Like you can specify that someone else can have the same one. So whichever app is loaded by the device first is the one that's going to respond to that protocol. So if My Redirect is MyApp and the Grinch releases an app called My, he could get the tokens that way because they made us get posted to his app by the device. So the problem with the Implicit Flow is that token in the fragment is just very, very insecure. It's very easy to leak that out. Another source is third party JavaScript libraries that are running in with your application. They can look at the window object, for example, and a lot of these off libraries leave those tokens on the window object so they can be picked up from there as well. So a lot of places that can leak. So this is not the recommended flow anymore. Instead, what's come along is a flow called Proof key for Code exchange or Pixie as it's shortened to. So Pixie does something a little bit different. It doesn't send you back an ID token inside that fragment, it sends you back a code, right? And the idea is that that code is utterly useless to anybody but the application that requested the sign in in the first place. Now, if you've done any OIDC, you might have seen this before with a server side application where the same thing happens. The Authority sends you back a code, but in that scenario, your application uses a shared secret to switch that code out for a token with the authorization server. Now, the problem with a native app, of course, is that a native app can't keep a secret. So there's no point bundling up one with your APK or your IPA package or putting it in your JavaScript because someone is going to grab that secret. It's not a secret. So PKC is a little bit different in that a secret is created on the fly at the point of kicking off that authentication request. And what the PKCe flow is, is that we send a shah of that onetime secret back to Aid. So Aid associates that Sha with the token that is associated with that code and it sends the code back out. Now, in order to exchange that code for a token, you need the plain text that created that sha in the first place. And if you can present that and the code, then we will give you back the token. Okay? So it's a way to bind the request to the token with the receipt of the token later. And it means that we're not sending that token in hash fragments everywhere, which is a much better security story. So what I want to do is use a tool called Fiddler, which is a network kind of proxy debugging tool, and we're going to go and have a look at those flows. So when I did my authentication, then I was capturing traffic, network traffic in the background so we can see all the Http requests that were going backwards and forwards. Now the initial request for a token starts off at the authorization endpoint on Azure Active Directory. So I'm going to quickly find those calls to Authorization. I'm going to take this one down here and we can click on that and we can go and have a look at the parameters that we sent to Azure Active Directory. We've told it who we are. That's the client ID at the top that we saw earlier. We have this property called scope. Scope is a really, really fundamental concept in all of us to the idea of a scope is it's something you can put in front of an end user that you can ask them to consent to. Think of it like Santa Lite has already got permissions to view profile details if only those users would actually let it do that on their behalf. So the scope is a way of asking for the user to consent for the application to do something. In this scenario, the important ones are Open ID that says it's an Open ID Connect flow. It's authentication, not authorization, and then profile. So we basically want to see the user's profile. We have the redirect uri to Santellite. We just spoke about that. One response type is really important. We don't want a token back, we want a code back. And the PKCe is the code challenge and the code challenge method at the bottom. So code challenge method is s two, five, six. This is a Sha 2560f something. And then the code challenge is that Shah. So AAD uses that, and when it dishes out the code, which we can see in, it should be the last AAD one down here. And let's see if we can have a look at this one. No. It's always fun trying to find the requests that generate what it is you're looking for. That's the one that gives the token back. Okay, for the interest of time, there's another flow in here somewhere where we can see AED presenting the code back to the application. And to finish it off, Santa Light goes back to Azure Active Directory and says, hey, look, here is the code. And that didn't work, that's Emmy. There we go. Cool. Here is the code, and here's the code Verifier. So the code Verifier was the plaintext that created the Shah in the first place. And when we get those bits of information, AAD responds by sending us back, in this case, a bunch of different tokens. But the important one for authentication is the ID token. Now that is basically base 64 encoded JSON. So what we can do is we can grab this and we can use another tool to have a look inside it. So I'm going to use a tool called JWT Ms. You can also use JWT IO. That's fine as well. This one is nice for AAD tokens because it breaks down all the different claims to tell you what they actually are. But in essence, there's three points to a token. We'll call it the red part, the blue part, and the green part. The red part tells us what signing Keys Azure Active Directory used to sign this token so that we can trust it from AAD. Now there's another call, which I didn't show you, where we go to Aid and ask for its signing public keys. So we already have those, but it's now telling us which one it used to sign that. We've got the green part, which is the digital signature, and then we've got the blue part, which is a bunch of information that we asked for and it's now responded with so quickly going through some of this, we start with let's go for the preferred username. So this is an authentication flow so we can see that it's center at groundworld, and we have the name as well. Inside there, there's a bunch of timestamps issued at not before and expires as well. And there is a version which is always a source of confusion. In Aid, we have two versions, version one and version two of our endpoints. And then we have V one and V two tokens. If you use Ms, you always hit the V two endpoint. If you ask for an ID token, the version of the token you get back will always be the same as the version of the endpoint that you hit. So v two endpoint will get you a V two ID token that's different for access tokens, but that's the way these ones work. They're much the same to be honest with you. V two tokens are a bit smaller than V one tokens. The other really important bit of information in any OAuth two token is the AUD or the audience claim. Now in this scenario, the audience b three is the same client ID as my Santa Light application that was registered inside a ID. And the golden rule of owl tokens is that if the audience isn't you, then you shouldn't really be using that token because it was never meant for you. And there's a really good example of that in tokens that are issued to call our Microsoft Graph APIs. So I've had customers call me before and tell me that their Istio JWT validation plugin was failing and they want to know why. And they're trying to validate a Graph API token but it's signed in a very weird way in that I think they create a signature and then they add something else to the token after the signature is created so you can't validate them basically. But the point of it was that, well, you're not the audience, so it's kind of not yours to use or validate as that token. And that's a really, really useful thing to know, especially if you get weird issues like that. But look, that's the identity token and that's the pkcflow and how all of that hangs together. So with that we're going to move on to the next thing. So we've signed in, we know who the user is, so the next thing you want to start doing is calling those APIs that have been exposed by Santaw. So we've got a button up here which is to add Graham to the Naughty Nice list and let's click on that one and see what happens. Okay, so let's put in sansa's password. Okay, so it's nobody's aid consent windows. But this one is a little bit different to the one we saw a minute ago. This one is now saying the app would like to change the Naughty Nice list on Santa web. So this is another example of a scope. What's going on here is that Santa Web has exposed an API or a set of APIs to deal with managing the Naughty Nice list and Santa lite the client wants to access that. This is an example of incremental content, by the way. So it's an application where as we want to do things, we're going to start asking the user for extra bits of consent as opposed to asking for everything upfront. Because that can be a bit daunting as a user, right? If you log in to view some information and you get asked to edit and delete and all these kind of higher privileged permissions. So this is just going to ask at the point in time, but where's that. Scope come from? What is it? Well, we can see there's an application which is called Santa Web, so let's go and find that inside AAD and have a look at that. So we're going to go back up to groundworld and this time we're going to Santa Web and we're going to go into the exposing API section. And what we should be able to see is that if all goes well, my first demo gotcha. Come on, AAD, don't let me down. OK expose an API. Perfect. There we go. We're back in. The Elks have already been here and they've defined three scopes on this application. We've got Nori Nitas write Nordynizersread and present delivery route. Right? Now, scopes are all there for the end user experience. Scopes don't necessarily map one to one to the backend APIs, so there might be 15 or 20 APIs involved in managing the Naughty Nice list, but we wouldn't want to be prompting an end user for each and every one of those, because that consent experience is just going to be too much to take. You're asked for a list of 50 APIs to consent to. Yes, sure, whatever. So scopes allow us to create something that makes sense in front of a user and then that may map to multiple APIs behind the scenes. But in this, as far as IoT is concerned, it's really just a piece of text. It's a scope, right? There's nothing that special about it. And we can have a whole bunch of these against a API if we want to. Against an application. Sorry. Now, do you see that prefix with Apiweb? So, whenever we create an application inside Azure Active Directory, there are a bunch of different IDs that uniquely identify that, which can be a bit weird at times. We have the application or the client ID, we have an Aid object ID. And there's another piece of information that we can specify that's called an application Uri. Whenever we ask for a scope from Azure Active Directory, we can't just ask for the name of the scope. In this case, naughty. Nicelist read. We have to fully prefix it with the applications Uri, followed by the scope name. And that's a little bit different to say, Authero, where when you ask for a scope, there's another piece of information you send, which is the resource that you want to get a token for. Because a JWT, an OAuth access token, only applies to one audience. There's only one API we can give this token to, which means that all the scopes have to be from that API. So it's a little bit strange in AED in that you can ask for a token with scopes from multiple APIs, but it will reject that request and just say, no, no, it has to be from the same API. Now, in this scenario, I've explicitly set my application ID URL to be API santa web. And then if we go and look at the react code on the Naughty Nicelist button, we can see that I'm using a ML method called a choir token Popup, where I'm asking for API Santa webpresent that are not in isolate. Right, so let's go. And now I'm just going to cancel this. I had some issues with this one the other day where my actual token request expired. So let's kick it off again and see if we can get a response from AAD. We'll accept the consent and we get a token back. And that's now going to try and call the API in the back end and we get an unauthorized response. So that's interesting, right, something looks okay. We've got a token, but there's a problem somewhere else. So let's start by grabbing a token and we're going to drop it into JWT Ms and have a look at it. So it's a bit different. This is a V one token we can see down here, but let's not worry about that too much. It's just a bigger token. It's still an access token, not much difference. We've got this SCP property in here now, so that's the scopes that the user has consented to. So we can see that Santa in this case has said, yes, you can call the Naughty Nice list on behalf of me. I consent to that. The other one I want to call out is the audience at the top. So in this scenario, the audience has now changed to API Centerweb. So in an access token, the audience will be that fully qualified application Uri on the scope that you asked for. There's a little caveat in that you can ask for another scope prefix of the client ID and it will then give you a token with the client ideas and audience. But on the whole, you'll use the application ID Uri. So this looks pretty good to me. I've got a token, but for some reason something has failed. So I'm going to go to the backend application now and see what happens. So this is a net core application. We're using a library called Microsoft Web Identity, and we've had to configure it with three bits of information pretty similar to the MSR client, just different names. We use a tenant ID, which was the grid at the end of the authority. We've got the instance which just points to Azure Active Directory. And we have the client ID, which in this case is the unique ID of Santa web. And we have nothing else inside there. But if we look at the log file, what we can see is that we've been told audience validations failed IDX. Ten, two, one four. So I see this a lot with audience issues in Azure Active Directory. It's a quirk of aid, especially the Microsoft libraries, in that if you don't explicitly specify an audience, we will kind of make one up based on other data that we expect those tokens to have. In the portal, you can ask for a default application ID Uri and we just set it to API and then the grid of your client. And that's what AAD, sorry. That's what Microsoft Web Identity will expect on the token if you don't sell it. Otherwise there's a subtlety as well. There's a weird bit of code in the backend library that says if it's a B, one token, I expect API clientid. If it's a B two token I expect the client ID. That's one of a source of confusion that I've seen surprise a lot of people doing this, but in this scenario all we have is a controller AFNET and you can see we've got a post method to the Naughty Nice list and at the moment it's just got a required scope on there. So what we want to do is inside our app settings, we're going to tell Microsoft Web Identity what the audience should be on the token. So it's just API, Santa web, and then we'll restart the application and we will try that again and see what happens. So while that's moving, let's go back to here and add ground cinnamoni Nicelist. The default isn't to always prompt you every time. By the way, I've just done this to make the devils a bit easier. We actually will cache tokens in the background to make things a bit better. So if all goes good, perfect. So that's the second issue I see is audience is not set up correctly if you're using Azure App service as well. This pops up a lot if you're using the authentication feature that we have built into it. So you have to be very explicit on the audiences with that. And I've had quite a few calls where it's not set up properly. So it's just one to be aware of. But again, we can see the tokens, we can look at the configuration and the flows and get a good picture on why things aren't working. So this is awesome. We have managed to now call the downstream API with an access token. So I've heard. There's another problem though, so I'm going to log out Santa. Now, there's a fairly cheeky elf in there who's called Alabaster and he's been digging around this application and has realized something. What he's discovered is that if he signs in, which is the same flows and everything, and he can consent to the same permission that Santa has been consenting to, which is to manage the Naughty Nice list. Now, Alabaster is really not a senior elf, so he's got no business to be inside this part of the system, but he can get prompted for the consent and he can call the API. Now this is something in Azure Active Directory to be aware of, which is that as a user well, let's start with the application. If there's a permission configured on the API, then it's really the application can prompt anybody to consent for that permission, right? So just because you can consent someone if they want to do something doesn't mean they're actually allowed to do that. So scopes aren't permissions, right? At the end of the day, scopes are really there just to get delegated consent to act on behalf of a user. It doesn't mean that user is necessarily able to do that thing. Okay? Scopes aren't permissions. Now some authorization servers do actually allow you to map users to scopes. So I think identity server was one way you could literally create scope and then restrict which users could even be shown to ask for consent. But with AAD, if you're a user, if you're allowed to use an application, we don't restrict which scopes you are allowed to consent to. We will give you a token with them in. So what are we going to do? Well, there are a few different ways I can think to solve this problem, right? The first is fairly old school. We have Active Directory groups who doesn't love seeing your name in about 1500 ad groups that have been defined over like 30 years of an enterprise for applications that no longer exist even anymore. Right? It's pretty painful. It involves the ad team, which is normally quite painful to make changes in ad, which is probably not a bad thing, to be honest with you, but it's very detached from your application is Active Directory. Active Directory is like an organizational concern, right? And in my opinion, ad groups should really represent quite high level organizational constructs. So maybe that is that I'm a developer that's fairly organizational level or somebody works in marketing or there's a mentors group. They seem like really good natural fits for ad groups, not very low level application concerns. There's a bigger problem with JWTs and Active Directory groups as well, which is that when you're in an ad group, we start putting those groups on every token that we send back, which has you as the subject. So those groups grow and grow and grow and grow. The tokens get bigger and bigger and bigger and then we hit a limit. And at that point in time we don't put any more groups inside that token. So that could leave you in a scenario as an application where if you're lucky, the group might be in the token. If you're not, you might have to make another call off the graph to work out if the user is really in the group that you want to find them in. So not a great place to be in. Now, in Aid, we have another construct which is a much better fit for this. That's called a role. So roles are like groups that are really scoped to your application inside Azure Active Directory and they give us a much better location for application concerns. And the idea is that we can define roles against an app and we can assign users and groups to them. And then when we get a JWT back for the audience of the application, we will show you the roles that that user is in that are defined in the application. So they're pretty straightforward to define. Let's go into Santa web and we have this tab down here called App roles. So if we select that, we can see there are two defined. We've got Santa World employee and Santa world senior employee. So the idea is that you should only be able to manage the Naughty Nice list if you're a senior employee. So how do we get users into that? Well, we've talked about applications so far, but AAD has got this other wonderful thing that goes hand in hand with an application that depending on which day of the week we could it is either called a managed application, an Enterprise application, or a Service principle. Each name really makes very little sense to me and it took me a while to actually understand what was going on. But the idea is that an aid application is really just definition. It's metadata. It's not a thing that you actually really interact with or you hang users off or users sign into. Instead, what happens is that for every application, if you want to use that inside your Iad tenant, you need to create what's called a let's call it a Service principle, which kind of goes hand in hand with that. It's literally like the manifestation of your application inside a directory. And that's where we can start hanging things like real users and blocking users from accessing the application in the first place, looking at who's signed into it, all kinds of things like that. Conditional access are done against the Service principle, not the application. There's another way we can set an application up which is in what we call a multitenant form. And it probably makes more sense in that world because with a multitenant application we only define it once. But then we can have other directories that want to consume. Let's say I'm a SaaS provider, they want to use my SAS service. They can create the service principle in their directory where they can assign users and access and conditional access and things like that. So when we want to assign users to a role, we have to go into the managed application, service principle, enterprise application, whatever you want to call it. And in here we can effectively go to users and groups and we can start getting much more specific about who can access this application or indeed if anyone can access this application. So let's go and find Santa and we will select Santa. And when we go to role, the only roles that we are offered are the ones that were defined against the application object. So in this case, I'm going to make Santa a senior employee. It's probably more than a senior employee is center and we will assign and now let's go back to Santa Lite enter and we'll sign out and sign back in as center. So sign in and go and find center. I didn't remember it. And sign them in and then we'll click to add it to the Naughty Nice list and we'll have a quick look at the JWT. First of all, that comes back upset. There's your token. Let's put that into the third one over here. Set access or refresh. This is an access token. Yeah. And then you can see now that we get this extra array comeback of strings, which is the roles that Sansa's assigned to. Now what we can leverage in the backend API is we're using standard ASP net authentication authorization here. So we can start to use our bog standard authorized attribute and we can say that we want the in this scenario, it's the roles that we're interested in. And then we just go and find that particular role. Senior contributor was a senior employee. Oh man, what's going on there then? Okay, yeah, that's my demo bad. Basically there's a human visible version of a role and then there's the actual sort of key of the role that you get back. So I think in this scenario, what I've done is the senior employee is actually called Senior Contributor. So that's the one that comes back in the token. Thanks, thanks for playing that one out to you. Okay, great. So we are going to check for that particular role in the token. So now when we run this, the center all is going to go well and we're going to be able to call that API. But if we were to get a token as Alabaster, then of course we're not going to have that particular role inside the token and the authorization step will fail. So just to kind of finish that one off in this scenario, I think it worked last time anyway because we didn't have the off on there and happy days, hopefully bell to fetch. I'm not sure what's got on there, but anyway, that's okay. You'll have to trust me on that one. In the interest of kind of not fixing my broken code, that one should have worked. And if we do the same as Alabaster, we don't have the role inside the token, so everything fails. So really, that's what I had to walk through today. I think we've covered a fair bit if anyone's interested. There's the crazy code inside Microsoft Web Identity, which looks for specific versions of tokens and then hardwires a different expected audience depending on which one it is. There's a link on the slide deck as well to that code if anyone is interested in that. But ultimately scopes aren't permissions and that's a really important thing I want to get across now. Really, roles aren't great for permissions either. They're good for segregating users into your application. But as your business logic starts to get more and more specific, then you really don't want to be outsourcing that into a third party like AAD. You don't want to get into a trap of having roles called something like can transfer more than $100 or is allowed to transact on a Monday. Right. That is business logic concern and either get that inside your application or look to something like a policy server. Potentially, if you want to outsource that, there's a good talk tomorrow morning that Jason is doing early about ASP net core authorization policy. So if that's something that you're interested in to take that next level into getting application business authorization rules, then I fully recommend going to that talk. But that is everything from me for today. So really appreciate you all coming and I'm sure we have a few minutes potentially for questions if there are any. So, thanks. You mentioned OIDC, but they don't fully comprehend. Yeah, sure. Right. So in the beginning there was OAuth Two, and OAuth Two was a very loose framework on how to build an authorization framework. And it was possible to be like adhering to Or Two whilst having quite different implementations of your different implementations. Or Two is also just an authorization protocol. Right. So its main purpose was to get delegated consent of a user, really to consume their Facebook profile, but it said nothing about authentication. So what happened is a lot of the big providers built their own authentication APIs and used the wharf too to get tokens to access those. So you have this like proliferation where signing with Google, signing with Facebook, signing with this service, they all did it in a slightly different way. The claims are all slightly different in the tokens. So OIDC came along and really started to come up with a more standards compliant way of implementing Owath Two as a framework. So that might be a case of saying, well, look, OAuth Two said you could do this and you could do that, and maybe you could do this, but you don't need to worry about that. OIDC said, no, this is how you do it. And then it also added this new token called an ID token, which basically fixed encodes the authentication problem and gave a standard compliant way to just work out who somebody is without asking them to access another API. So I quite often interchange and I'll say OAuth Two, or I'll say, oh, IDC, and I never really know which one to say because it's not like it's an umbrella. It's not like it replaces or of two. It's more like it has these extensions to or of two. And it also just kind of makes it a little bit more concrete around how to implement OAuth Two. So when you look at Azure Active Directory, for example, I refer to as like an OIDC compliant authorization server that will give you also OAuth Two tokens as well as identity access tokens. But I'm happy if anyone else likes a lot of what I know about this. I worked with some really smart people at Bank West a few years ago and learned a lot from their identity team, so I'm happy. If anyone else in the room wants to extend that answer, then please go for it. Sure. What's the RSC? An RSC request for comment. I think it stands for if you want. This is a good one. I'm sure someone will give a much better answer for this. So you have an idea and you want to think about standardizing that idea. So the general approach needs to be 40 hours an RSC and then it will have a lot of kind of debate and discussion and feedback, go through various versions until it kind of hits a point where it's considered stable enough and the controversy has died down. And then different things referred to as different RSC numbers. So private network addresses like RSC 1819, it's where a bunch of people just said these IP addresses. We are going to say they are private use only, they are not public. And that's pretty much standardized in RSC 1819. So OAuth to an RIDC also have RSCs that go with them as well. Yeah, right. So it's normally a coalition of the willing. So you'll find a lot of the RFCs will have people, if there are enterprise products involved, they'll often have representation from the vendors of those products. But also there may be academics, just people that are really interested in that domain. So I think it's kind of a public domain thing. I'm not sure if there's a method to choose who gets to contribute in it or not. That's possibly a level I don't really know at that point. But yeah. In the AAD console you're working in the section called App registration. Yeah. How does that differ from the enterprise application section, which is also used to set up SSO with applications? Yeah. Right, okay, so which bit of it in particular was it you were thinking about in there? I haven't set up any applications in this way exactly, but I have worked in the enterprise application section. When you're registering like a third party. Cool. Yeah. Right. So what you're probably doing there is setting up a multitenant application. So when it comes to SAS providers, I was doing some work with one the other day, they own the application registration. Right. So you never see that part of the portal. You can't access it, it's inside the SaaS provider's tenant. But what you can do is you can craft these links that allow an AAD administrator to create an instance of a service principle that represents that application in their directory. So it's possible that that's where you're at is inside that service principle that represents a third party application and that's where you can start assigning users to it. Yeah, it's more about whether it's a. Third party application or something in house that you're building specifically to work with, right? Yeah. So if you want to do sign in flows in AAD, then there has to be an application somewhere and there'll be a service principle independence where you can sign into that application. There are scenarios where you can have service principles without applications as well. So if you use Azure and you create a managed identity, you'll get a service principle without an application and you can assign RBAC to that service principle, for example. But yeah, if there's a sign in flow, there'll be an application somewhere. Yes. The question is around multiple identity providers. If you want to build an application that can do, signing against all of those can be a real pain. I don't know the Azure Active Directory roadmap, but I do know that BETAC does support federation, so you can front a whole bunch of different identity providers with a B to C sign in page. Now that having said BTC, sign in doesn't give you access to like authenticator and all that kind of conditional access stuff. So I think there's still some gaps there, but I'm not sure what's on roadmap for closing those, if anything. Yeah, I don't think there's much you can change on Ad. Right. So B to C is one way you can get a lot more customized flow of defining your own UIs and all that kind of stuff. That being said, there possibly are some parameters you can tweak to change that experience a little bit. I just haven't done too much on that. So I'm afraid I don't have a great answer, but I take it offline and find out for you. Cool. Okay, so thank you everyone for coming and yeah, enjoy the rest of your conference. Cheers. Thank you.