[MUSIC]
Matthijs Hoekstra: Hello. My name is Matthijs Hoekstra
and I'm a Program Manager in the Azure
Identity Engineering Organization.
In this video, I want to talk about how to add
authentication to your applications and make sure people
can actually login securely with their existing Azure
Active Directory account and they have a single
sign on experience.
So, let's start with an application. First thing
I want to do with my application is actually login.
And instead of doing a login name with a password with a
little form and I click on submit, let's do it in
a modern, proper way.
So, how does this work?
We got Azure Active Directory on top, I got a protected API
on the right, and I got my application on the left.
So, my application wants to login a user and wants to
authenticate against this API, so what happens?
First of all, my application sends you to Azure Active
Directory and tells the Active Directory, okay I want an
ID token for this user, I want to be able to identify the
user, and I need an access token so I can actually call
this protected API.
And this access token, I want to be able to use this
access token to read the user's profile.
So, what then happens, and this is important,
there's going to be a private conversation between
the user and Azure Active Directory.
This is web based, this is what the OAuth2 standard
actually prescribes.
So, this conversation between the user and the IDP,
the application has no clue what's actually happening.
Are we asking for a login and password?
Are we asking for multi-factor authentication?
Or perhaps FIDO2 passwordless?
On Tuesday going to call your mom if it's okay to let you in?
That conversation for an application, they don't care.
In the end, when everything is satisfied between the user
and the IDP Azure Active Directory, everything is good.
We're going to set the session cookie.
This is actually how single sign on works.
So, next time another application comes in and wants to
authenticate the user, that's the same private
conversation but since that session is already
established, we can immediately login the user and then
give back the tokens for the other application as well.
So, this is an important piece of modern authentication.
Then, the user or the application receives an ID token.
What's an ID token?
Well it's based on the JWT standard or a JSON web token,
it has a header with a version, and it's got a signature.
And the signature is used to make sure this token is
actually coming from Azure Active Directory and not from
somebody else.
The issuer, that's one of the claims in the token, says
well, this is from Microsoftonline.com, that's us.
This is coming from your own Azure Active Directory,
your tenant ID.
The audience, that's your application object ID, so you
register your application that's a unique object ID,
so you know this ID token is actually meant for you and
that's not an ID token which was meant for somebody else.
A token expires and you can use it before and not before,
or we would tell you when it was issued.
And there might be other information inside of the token,
which is relevant for you as well, for example,
the name of the user or maybe a preferred username.
Subject, which is unique for this application,
for this user. And we might provide you with an OID as well.
This OID is actually unique for a user over all the
applications inside of the tenant.
And we got a tenant ID, this means this user's logging into
this application from this tenant.
In a previous video, we talked about guest accounts and
B2B, so if a guest is actually logging into your
application the tenant ID will be different than your
tenant ID.
If you want to store information about this user,
we recommend you to not use a preferred username or an
email address because those might change.
The subject will always be the same for this application
and if you want to store information which is covering
multiple applications you should use OID as a key for
this user in combination with a tenant ID.
So, this is what's all available in an ID token and this
tells you who the user actually is, and that the user is
actually logged into your environment.
You also get an access token, and the access token is
something you have to use to call the API.
You have to consider the access token as an oblique blob.
You should not look into an access token.
It happens to be something which you can read most of the
time, but you should not as an application developer.
The only job you have is to pass along this access token
to the API and don't look into it.
So, we're going to pass along this access token to the
API, the API or the resource is actually responsible of
validating and making sure the access token is valid.
If it all works out, going to allow you access and we're
going to return the results from the API call.
So, what do I do if I have to call another API?
Well, it's actually the same trick.
We're going to talk to Azure Active Directory, say now,
I need an access token to be able to call the catalog API.
There's another private conversation, this might be hidden
for the user, or it could be visible if it has to ask for
permission, for example.
Or perhaps an administrator set up a conditional access
policy where they ask you for multi-factor authentication
to be able to call this catalog API.
So, there is a chance that interaction is necessary
between the user and Azure Active Directory.
If everything pans out, we're going to give you another
access token and this is the access token you have to pass
along to the second API.
If the resource, the API, validates the token,
everything checks out, it can actually grant you access
to be able to call the API and return to you the results.
This is basically how modern authentication works.
You get an ID token to make sure you know who the user is,
you get access tokens to call APIs, and every API needs
their own access token.
So, let me show you how you can configure your application
and then get started quickly.
We go back to our most favorite blade in the Azure
Portal, which is Azure Active Directory Portal.
We go to app registrations.
I already created a demo application in a previous video,
but I didn't configure it yet so open up that one.
And what I like people to do before they start configuring
these things manually is go to the QuickStart tab.
And here you can choose between different applications.
I've demoed a JavaScript single page application before,
so let's go to this one.
And this actually tells you you can download the project
here for Visual Studio code or for Visual Studio,
but what it can do for you is make the configuration
changes so you can actually login to this application.
So, let's look at this first.
It configures a bunch of stuff like a redirect URI,
that you want ID tokens and access tokens, so I say sure,
make the updates.
And then what you can do is copy/paste this information in
your applications. So, let me fire up Visual Studio.
The configuration is something you have to paste here.
This is copy/paste. You've got a client ID, that's the
unique ID for your application.
You're going to login to Microsoftonline.com.
/common means it's a multi-tenant application.
If it's just your organization, there's only going to be a
tenant ID here.
The redirect URI, we're going to explain what it is
in a second, etc.
So, going back to this, this will actually explain the
scenario I just talked about.
I'm going to sign in, give you an ID token, I'm going to
ask for an access token, I'm going use an access token,
I'm going to call the API with the access token and then
going to return you the results.
So, now let's go over the lines of code in my application
in the QuickStart here.
So, I defined that I want to call a Graph API,
in this case it's the me API, which just gives you
the profile information of the logged in user.
I need user.read permissions to do that.
We call that a scope.
I'm going to configure my msal.useragentapplication
with the configuration I just pasted from
the QuickStart page.
I do a sign in, I show you popup for that user,
show a welcome message and I'm going to acquire a token
and call the Microsoft Graph. So what happens here.
And then this is a pattern you will see over and over
again if you start using MSAL.
First what we tried to do is I've tried to get a token
silently, that means without a popup or user interaction.
And if that's successful, I get a response and in that
response is actually an access token.
I'm not going to look at the access token, I'm just going
to receive it and I'm going to call the Microsoft Graph
the endpoint we just showed, like the me endpoint with the
access token, and once I'm done, I'm going to call the
Graph API callback function.
So, I'm going to call the Microsoft Graph and I'm going
to add the access token as a header or a bearer token,
is also referred to.
So, the authorization header contains the access token and
I'm just going to call this REST API and show the results
in the callback. This is literally
the simplest piece of code you can write to just call
a protected API from a JavaScript single page app.
If somehow there's interaction needed anyway,
we're going to catch an error, so for example,
you have to do MFA, or you have to provide some
permissions to be able to call this API,
then we do an acquired token popup.
So, the pattern is try to do it silently, if that fails,
you're going to do it interactively.
That's always the pattern you will see.
Silently gets the exception if interaction is needed and
this is the requires interaction error code we're going to
capture. Otherwise we're going to show a popup,
ask whatever permission or things like MFA or
whatever we need to do, and the application
doesn't really care, doesn't end private conversations
between the user and Azure Active Directory and
when it's satisfied, you will get an access
token and you're going to call the API.
This is simply how modern auth and JavaScript single page
app in our environment works.
If you go to the authentication piece, you'll see access
tokens and ID tokens. Where is the reply URI?
That's the one I configured here as well.
Secrets and certificates is something I need for
different kind of applications like websites and
record applications.
I also want to show you if you want to know more
information about what an ID token contains,
we actually have documentation here, and we will
provide the link in the description below this
video as well.
I got an ID token and let me just click on a really useful
website, it's called jwt.ms.
This is actually the ID token, there's a header,
there's a body, and there's a signature.
So, it's a JWT, this is the algorithm we use to assign the
ID token. I got an audience, so let me zoom in a little
bit so it's readable. I got an issuer. There's an
email address and a family name, so there's more
information in this ID token I can use in my application.
And the claims tab actually explains to you what all those
different claims mean, and they use short claim names
because we want tokens to be small, they're going to be
sent over the wire all the time.
So, this actually helps you understand what information is
available in ID tokens.
So, remember this flow we talked about before to explain
how the flow works between an application and IDP,
Azure Active Directory, and a resourced API.
So, what we actually do is when the application sends you
to Azure Active Directory is we send you to login at
microsoftonline.com with a tenant ID or /common,
we call it the common endpoint. And common endpoint is
used when you build a multi-tenant application.
And once the conversation between the user and the IDP
Azure Active Directory is done, we share the session
cookie and then we send the ID token and the access
token back to the redirect URI, that's in
this case, localhost:30662.
It's important that you actually own the redirect URI,
and in this case, I did a terrible thing because,
first of all, it was not https and it's a URI anybody
could actually host. So, the redirect URI,
see it as that's the endpoint Azure Active Directory
is going to talk to give all this
information like an ID token and access token, and
you don't want anybody to be able to steal that
information, that's why the redirect URI is so important.
If you look at the URIs in the popup, you see when you
have to login, you can actually see the redirect URI there
as well. That means that people can actually change that.
This is also the reason why you have to register an
application and actually define the allowed redirect
URIs. So, when a user tries to login to an
application, Azure Active Directory actually
validates if those redirect URIs are known by
the system, you know what I can only trust this
URI to send some confidential information like an ID
and access token back to, so if somebody would like change
the URI to badwebsite.com, Azure Active Directory will
actually tell you, yeah, this redirect URI is not known so
I'm not going to do that.
So, I showed you a JavaScript single
page application, so what do I have to do if I built
an ASP.NET core website in this case? Let me open up
that application.
So, first of all, you have to register the application
in the portal.
I like to go to the QuickStart because it will set up the
configuration for you, but you can do it manually as well.
In your application, you have to tell the ASP.NET
middleware, oh yeah, this is an Azure AD application,
there's a configuration which we have based in the app
settings JSON.
Make sure the middleware now listens to or is configured
for Azure Active Directory so if somebody tries to login,
it knows where to send the user and what to do with the
results. And if you look at your controllers, the only
thing you have to do is actually add the authorized
attributes. There's more stuff you can do, you can
actually intercept the entire flow, but the ASP.NET
folks actually did a really nice job with their
middleware to make it really easy for you as a developer
to protect your website. So, for example,
let me start this application.
It will ask me for an account  to login, and it doesn't
matter if it's username, password, MFA, passwordless,
and all that kind of stuff, the middleware takes care of that.
I'm logged in as Megan, that's it.
So, those two lines in the startup that she has to tell
the application middleware-asp.middleware-what to do if
people try to authenticate and then on your controllers,
you actually have to make sure that the application knows
okay, this is a protected resource to the challenge and
sends you to AAD to do the login.
So, now you know what ID tokens are and access tokens
are, how to write a single page app, or a ASP.NET website.
And the concepts are the same for other platforms as well.
There's a few things you should know about what you should
and should not do with tokens.
So, we call this the golden rules for tokens.
Use tokens where they're intended for, so that means that
you use an ID token to authenticate a user, and you use
an access token to authorize a user against a resource,
so you send it along.
ID tokens are to identify a user, that's it.
Access tokens authorize the app for a range of operations
so that there are scopes.
You send an access token to the resource and the resource
is responsible for validating an access token.
We see a lot of times where people build functionality
where they try to validate access tokens in their clients
before they pass them along and you should not do that.
The resource is responsible for validating that access
token. Even though you might be able to read stuff
inside of an access token today, that might change
tomorrow. If the resource decides together with Azure
Active Directory, they have like a private contract
between themselves, say well we're going to encrypt
tokens tomorrow, your application will break because
suddenly you cannot read the access tokens anymore
so you cannot validate yourself.
Assume that the client application is not aware of the
contract between the resource and Azure Active Directory.
They might go yellow means blue and blue means yellow and
we're going to makeshift everything and we're going
to encrypt, you don't know, so assume that access token is
just a binary blob you're going to pass along.
Never mess with someone else's tokens.
What I mean is that what we see is that developers get
access tokens for the Microsoft Graph and they're going to
use it for their own APIs. Don't do that.
First of all, you might not be able to read that access
token the next day.
We have seen people being creative where you know what I'm
not going to validate a token, I'm just going to call the
Graph and see if it works because then I know it's a valid
access token.
But at that moment, you open up your API for anybody who
can actually ask for an access token for Microsoft Graph,
which is literally everybody.
So, that might be secure for your API, so don't do that.
Only use the access tokens that are meant for you,
and that's by checking the audience in your APIs.
Don't use ID tokens for access control either.
ID tokens are meant for identity validation when
you login authentication.
I've seen people do this where they pass along ID tokens
because the information they want is there and they just
pass it along. You open yourself up for certain attacks
which are protocol specific.
Please don't do that.
I mentioned this, don't accept access tokens which are not
meant for you.
First of all, your administrator doesn't have the control
to figure out who can access APIs or whatnot, but you open
yourself up for certain attacks as well, like the Microsoft
Graph example I just gave.
Please don't do that. Cache tokens.
MSAL actually does that for you, so access tokens are,
at the moment, valid for around an hour. That might change.
So, you don't need a new access token or a new identity
token all the time.
If you use MSAL as a library, we actually do the caching
for you, so get acquired tokens silently, we will get you
one from the cache and you can use that one.
If they are expired, we make sure we're going to give you
a new access token as well.
And then depending on if interaction is needed because
maybe an administrator set up a new policy and suddenly
you are required to do MFA and before you weren't,
so again, the pattern, acquire token silently,
acquire token interactively. If you're using MSAL,
that's actually where the cache is used as well.
And instead of you checking for all the different error
codes you know of, please use error classes
I showed you in a JavaScript sample, and please look at the
code in your QuickStart as well, where we capture
interaction required.
So, instead of you trying to capture oh, I need MFA,
I need to do a password reset, don't try to capture all those
errors, just capture the interaction required and show a
popup and we take care of the REST.
So, the strongest argument we always get is well I need
to look into access tokens because I need to be able to
debug, I need to figure out what's going on.
So, there's a really good reason for me to look inside
access tokens. And no, we don't think you do,
and let me show you why not.
I got a little application here which is based off the
default wpf sample.
Let me start it here.
And I'm going to use this application for different videos
as well. If I sign in a user,
and we will share the link to the source code in
the comments box below. Login as Megan.
The token response actually gives you a lot of information
you can use without looking at the inside of tokens.
I did get an access token, I did get an ID token because I
want to call the Graph API to read my profile.
We give you information about okay well, this identifier
is the unique identifier of this user, there's a tenant ID
and an object ID for this user.
I logged into login.windows.net, that's the old endpoint.
I have scopes: email, openid, profile, user.read.
This is something people care about, this is the
permissions you want to use to call the API.
I know when a token is expired.
We actually have a correlation ID.
This is something you can use when you have to contact
Microsoft Support.
This is something which is not in the tokens, only on the
response object.
I give you a tenant ID and a unique ID.
This is actually all the information you need to
troubleshoot your application.
Inside of the access token, there's not much more
information which is useful for you to debug.
So, forget about the access token and looking into it,
even if the access token is encrypted, this information is
given to you to be able to figure out what's going on.
Did they get the right permissions?
Is my token still valid?
Am I logged into the right tenant?
Is it the right user?
Oh, and if I have to troubleshoot, I can use that
correlation ID and contact Microsoft Support as well and
they can figure out what's going on.
So again, don't use access tokens to figure out what's
going on, use the token response as part of the MSAL
library or any library used.
This response will always give you this kind of
information and use that to troubleshoot what's going on.
So, we talked about okay, how do users authenticate,
so what about services background applications,
do they authenticate as well? Yes, they do.
So, when we authenticate background applications,
we use so called Client Credentials.
Client Credentials is a standard in the OAuth protocols to
authenticate applications. You need a client ID,
so you have to register your application.
Doesn't matter if it's a PowerShell script or
background.net Daemon application, we need to know about
the application and you're going to create a secret or a
certificate. Certificates are the most secure.
First of all, your application will only have the name of
the certificate and you deploy certificates separately
outside of your application, and typically organizations
are more aware of how they need to handle certificates in
a more secure way.
Secrets, you can use secrets, I typically use them during
demos because it's so easy, but it's also easy to check in
your secrets in your GitHub repo which might not be
something you want to do.
Secrets actually have to be secret.
It's like a really fancy long password, so you have to make
sure you're aware of that.
And you can also use managed identities from Azure to
authenticate your app.
We advise people not to use service accounts, so don't
store a username/password somewhere to be able to do
something in the background.
I talked about conditional access in another video and
explained what it is. An administrator might force
you to do MFA or maybe reset your password because
it was compromised in another breach.
Yeah so,
and the thing is that if you have only a username and
password and you want to use it in the background, and
suddenly you're forced to do an MFA, your background
application will break.
So, you're going to use a confidential client in MSAL,
and I have a link here to a .NET Daemon example which
I will open here in my Visual Studio.
Let me see where I have it. Here it is.
So, I got some configuration app settings, which is the
tenant ID, the client ID, and the secret in this case.
What I do here is I run a background task here in written
async. I read my settings in my configuration.
It's actually an example which can work with both a
secret and a certificate.
I have it set up with just a secret.
And if I use a secret, I'm going to build this
confidential client by passing along the client ID and the
secret and the authority, that's the tenant I want to
login to. So, a background application has to know
which tenant it's going to login to, in this case,
it's my own tenant. I'm going to tell it these are
the permissions I need, and then I'm going to do
an acquired token. This one is always silent,
there's no interaction, there's no UI, so we call
it acquired token for client. And if that's successful,
I want to call my API and that's something I'm going to
do here and that is in helper function in this clause.
And what it actually does is it sets the request header
with the access token and then I call it my API and I'm
going to go show the results. So, if I run this
application, it's going to give me all the user
profiles in the background
and show me the results. This is a Deamon.net
background application, there's no UI to login
because it logs in with a client ID and a secret.
So, before we end this presentation, I want to talk about
the protocols a little bit. The protocols OAuths, OIDC,
the protocols by themselves don't guarantee security,
developers do. What I mean by that is if you
implement those protocols yourself, you might be open
up for attacks, token replays to the client,
or replays to the server, you have to make sure caching
is done correctly and the token lifetimes are respected.
And yes, you as a developer can do it yourself and as you
get started, it seems very easy to do.
You do like a few gets and you get your first token,
but you might not do a secure implementation.
It's actually a lot of work.
And even if new attacks appear, you have to start changing
your code again because this is not a static world,
attackers find new ways to try to compromise OAuth
protected applications every day.
So, our recommendation is use a library like MSAL or
the middleware from ASP.NET for example,
instead of building your own.
So, this brings us to the end of this video.
We talked about how the modern authentication works,
what ID tokens are, what access tokens are.
We gave you the golden rules how to use those tokens and
we actually had you go through the first steps of how to
protect your application and security sign in with Azure
Active Directory accounts.
I hope you enjoyed this video and see you next time.
[MUSIC]
