KYLE MARSH: [MUSIC]
Hi, everybody.
I'm Kyle Marsh from
the Microsoft Identity and Network Access Team,
and I appreciate your time
coming to my session here at Build.
Today, I'm going to talk about how you can make
your application more secure,
as well as making it more resilient by using one of
our latest features, Continuous Access Evaluation.
Let's start by looking at how an application
works when we're using modern authentication.
Instead of typing up a username and password screen,
we ask the identity provider Azure AD in this case.
For example, here token to call Microsoft Graph.
Now we can only do this.
What happens next is
the private conversation between
the user and Azure AD takes place.
We can then check for things
like is the condition or access policy being fulfilled?
Does this user need to do an MFA?
Are they in the right network location?
Is there a high risk, etc?
All of those checks happen
here without your application
having to write any code for it.
It's simply part of the package we provide in
Microsoft Identity platform and
then assuming everything is good,
we can go ahead and issue the tokens and
ID token for you to know who the user is,
and access token so
your application can call Microsoft Graph.
Now, the thing is, this transaction only
takes place every 60-90 minutes.
Nowadays, Azure AD issues tokens,
somewhere between 60 and 90 minutes.
We used to always issue around 60.
Now it's maybe somewhere in the middle there,
somewhere, and that's around 75 minutes.
That's the only opportunity we have
to make sure that the user still works with the company,
that they still have access to this resource,
that those Conditional Access Policies I
mentioned, have they been fulfilled?
In this world of zero trust,
where we want to verify
explicitly these need to happen on
a much more regular basis than
maybe every 60-90 minutes.
But we don't have that opportunity because
your only transaction with us
is when these initial tokens expire.
How can we add a continuous nature to this?
One of the things that happens if
I take that access token,
is I want to use that access token in order to enable
my application to call to a API-like Microsoft Graph.
Quite often my application is going to call
Microsoft Graph a lot continuously,
if you will, throughout its running.
So I get an opportunity to use
the token much more
often than I go and acquire the token.
Now, the standard thing that would happen with
Microsoft Graph is it needs to authorize
that this JSON Web Token that represents you to
Microsoft Graph and your
application's authorization to call that API,
well, it goes ahead and checks
that the validity of that token.
One of the things that it needs to do
about every 12 hours or so,
not that often is get our list of signing keys.
These JSON Web Tokens
assigned so that they can be validated,
that they haven't been altered,
or changed in any way.
But we don't need to call back to Microsoft Identity,
don't need to talk to Azure AD
every time somebody calls the API,
we simply need to get
those signing keys every 12 hours or so.
Instead, we're relying on the lifespan of
the token as dictated by the claims within that token.
In that token, there's
an exp claim that says when the token expires,
there's nbf claim that says not
before this time is the token valid.
As a result, this token is good during that timeframe.
So if I issued you a token for 75 minutes,
your application will be authorized to call this API
on behalf of the user for that full 75 minutes.
In order to be able to shut off that access
for that application before the 75 minutes is up,
one option is to implement
something called Token Introspection.
What this would mean is, instead of giving you
a standard JSON Web Token,
we'd give you some opaque and string that
would represent the token to Azure AD.
Then every time someone called your API
or made a call to something like Microsoft Graph,
that would in turn have to make a call
back to Azure AD in order to
validate that the token is still good and
find out exactly what that token means.
It's a very expensive operation.
You're waiting a lot longer to get
those responses from your APIs because we've
added an entire another round trip
over the Internet in order to make that call work.
It's not something we're particularly interested in in
terms of providing a token introspection process.
Instead, we've been very
intrigued by the work that's been
going on in the OpenID
connect Shared Signals and Events working group.
In fact, we participate very heavily
in that group and we can
see it as an opportunity as we start
to adopt some of their standards,
as they start to come out to
improve this process quite a bit.
What we're going to do is, well before we
even have an application in the picture,
the API in this case,
Microsoft Graph can set itself up to
be a listener of events from
Azure AD that pertain to the users
who might be getting tokens for this API.
We set up a push channel so
the graph API isn't polling all the time to find out
what's going on simply when there's
an event that would cause us to say,
hey, you shouldn't accept that graph
token any more of that token to call Microsoft Graph,
we can send that event,
push that event directly to
the Microsoft Graph API implementation.
When your application comes along and gives
a token that it might have been
issued maybe 35 minutes ago,
it could give you that token.
The Microsoft Graph API can look and say, hey,
do I have an event for this user that says
I shouldn't accept the token that
was issued before, say, noon?
And yet here it is at 12:30,
and I shouldn't accept the token
because I got a message saying,
"No tokens before noon" and
this token was issued at noon and it's 12:30
so I could see where I could need to
revoke the access based on when that token was issued.
If I got a message that said "No tokens before
noon" and this token had issued time,
the iss-claim in the token of,
let's say 11:00 AM,
we would reject the token.
What's changing for you as an application developer,
I should mention the types of events that we would
use to revoke that token, if you will,
or revoke the ability of that token to access
Microsoft Graph could be
things like the user's changed their password,
maybe the user's been deleted or disabled.
We even can use things like
our Azure AD Identity Protection.
If the user were to move into a high-risk category,
perhaps an impossible travel situation has occurred or
their activity is coming from
an endpoint we know under that address,
we know where a lot of bad actor activity is happening.
We could also require,
send a message to Microsoft Graph saying, "Hey,
continuous access evaluation is saying
don't accept this user's
token if it was issued before noon".
Now Microsoft Graph and the API can also
participate in this on their own.
Every time we call
Microsoft Graph from an endpoint
somewhere on the network,
of course, Microsoft Graph gets
the IP address of where that request is coming.
If I have a Conditional Access Policy
that this resource should
not be accessed unless the user will say on
my corporate network or in
these particular network locations,
then Microsoft Graph can say, well,
Gee, this user is not
coming from that IP address anymore,
let's re-evaluate to find
out if this user really should still
be able to access this resource
from their current location.
It gives us another opportunity to enforce
those location-based Conditional Access Policies.
If Microsoft Graph had been given that error,
that Continuous Access Evaluation Event that says,
"No tokens before noon"
and this token has been issued at 11:00 AM,
then it's up to Microsoft Graph,
will then return to something we refer to
as a claims challenge.
You still get your 401 you're now unauthorized.
You might have used this token a minute ago
but in it's good for another hour let's say,
but you would get a 401 unauthorized
because Continuous Access Evaluation has kicked in.
We will include in that response
a www.authenticatebearheader saying,
"I've got a bear token here. "
What we'll do then is we'll have,
for example, the authorization-uri.
I will point you back to Azure AD.
There will be an error of insufficient claims,
and this third component we call a claims challenge.
This is simply an encoded version of a string.
Something I would have seen down
below where we're saying this token is no
longer acceptable so we're returning a 401
unauthorized to your application
because the token is no longer acceptable,
and in order to have an acceptable token,
it needs to meet
this particular claims challenge in this case,
not before the specific time that's issued here.
As an application developer,
I take that 401,
and the claims challenge I
get from calling Microsoft Graph,
go back to MSO,
ask for a new token providing this claims challenge,
and then we would go ahead and get
that application would get the proper
token to go on and call Microsoft Graph.
Let's take a look at how this works in action here.
I have here,
a couple of applications so
let me get this out of the way for a minute.
On the right here,
I have an application that doesn't
support continuous access evaluation.
I'll go ahead and sign in
the user here and we're going to sign in
Moses and we'll go ahead and do his authentication.
Oops.
I get my standard token here,
so my ID token that's
telling me who the user is. It's Moses.
Great. Notice I can look at my token response,
which tells me how long this token is good for.
Here I see that this token expires in
about an hour from now
from when I'm making this recording.
If I go over to a slightly
different version of this application
that does support continuous access evaluation,
let's come here, we're going to sign
in as Moses here as well.
I get obviously a very similar-looking ID token.
It's still Moses, after all.
But if I look at the token response now,
I see some very different values.
First off, this token is going to
expire about a day from when I'm doing this recording.
Not an hour, but a day.
It's a 24-hour, it looks like,
it's about a 24-hour token.
That's one thing, my token lifespan is expanded.
I no longer have to ask for
tokens from Azure AD every hour.
That's nice gain and efficiency for your application.
But also there's another value here that's been set,
which is this Refresh On.
Notice back here on the right,
we don't have a refresh on value,
it didn't get a refresh on back from Azure AD,
but we do when we support continuous access evaluation.
That's a cue to our MSAL Library to start trying to
renew this token after we've
gone ahead after 12 hours of life.
I've got a token that's perfectly good for 24 hours,
after 12 hours,
MSAL will go out and start trying to refresh that token.
If it can't, great, I got a new token,
another 24 hours of life.
If it can't, because there's some issue between
anything going on between
your application and its ability to get a token,
well, it doesn't matter, because I've still got
another 12 hours of lifespan left.
Any outage in your application's ability to
acquire a token that's less than 12 hours,
your application won't notice.
That would be a tremendous issue for us to ever
be out anywhere close to 12 hours,
let alone this one just a couple of hours.
It's highly likely that if there's any interruption,
your application simply won't notice
because it still has valid tokens that it can use.
Let's go ahead here on my IT Pro.
I've come in, I'm looking at Moses' sessions here.
I'm going to revoke all of Moses' sessions,
because maybe Moses lost one of
his devices or some of
his devices, so we're going to say no.
Moses needs to reauthenticate on all
of these devices because something has been lost.
Now I'm going to go and let's look at
the changes we need to make through our application.
First off, I have here,
I'm calling an HTTP Web-based application
just a raw form here,
just so we can look at
the innards of the code, if you will.
First off, obviously, I don't need to worry
about if it's a successful response,
but if it's unauthorized,
then I need to look for that www-authenticate header.
If there is such a header,
then I can look to see if the error
in the header is for insufficient claims.
Then I can go ahead and check for my claims,
they're my claims challenge.
If it's there, I can decode it,
and then I'm going to go off and
acquire my access token again,
but now I'm going to pass along the claims challenge.
What we're going to do is when we go ahead
and call to get an access token,
first off, we're going to do our standard pattern
we always do with MSAL.
We're going to acquire TokenSilent first to see if it
can be acquired without bothering the user.
Perhaps the reason for
the continuous access evaluation rejection
was the user change location,
but by the time they're accessing it again,
they realize they move back to the proper location,
so I might be able to acquire it silently or highly
likely I might need to fall back to
our user interaction required,
and then I'll go ahead and acquire
the token interactively.
If I've got this code in my application,
I've got my code to take the claims challenge that's
returned from graph when CAE has been kicked off,
and then return it and use it back to
Azure AD to acquire the
token again with our MSAL Libraries,
I can also add
the client capability of CP1 to my application,
and whenever that's the case,
then we know that your application understands
continuous access evaluation,
and we can give you those long live tokens as
well as be able to cut off access to
the resource based on
the continuous access event
and not just the lifespan of the token.
Here on the right, again,
we have an application that doesn't
support continuous access evaluation.
I'll go ahead and call the Microsoft Graph Profile API.
I have no problem here, I can still
access this user's profile.
I'm allowed to call Microsoft Graph
until that token expires.
Here I'll go to the application that does
support continuous access evaluation.
Let's try to call the profile API there,
and sure enough, continuous
access evaluation has kicked in,
and the user has to reauthenticate because I
invalidated all of the sessions for Moses there,
so I have to go ahead and sign
in again in order to access the application.
Now this application on the right,
it will catch up eventually.
If I look at my token response,
about 58 minutes from now,
this application will probably have to reauthenticate.
But this application that's using
continuous access evaluation much more secure,
its access was cut off near real-time in just minutes,
and we didn't have to wait all that time,
all that 58 minutes
for the actual token expiration to happen.
That's why our applications are more secure.
We can cut off access to the resource in
moments rather than whatever the life of the token is.
The application is more resilient
because it has an ability
to proactively refresh a token well
before the token expires.
Continuous access evaluation really does
base a boost to a session protection.
We now have a dynamic session lifetime.
It's based on the events
that are happening around the user.
Again, if I lose a device,
if I change my password,
if I need to do an MFA,
all of this can be taken into account and
the application and the resource can behave accordingly,
because they can work on
these signals effectively in near real-time.
What's next for continuous access evaluation?
We're going to be working on making
continuous access evaluation work
for client credential flow applications,
so today they work for
applications with users in front of them.
We're working to make it work for
client credential flow applications as well,
so our service principle if you will, and of course,
we're going to make it so that you can have
a continuous access evaluation for your own APIs.
Today, Microsoft Graph supports some exchange,
support some SharePoint,
it supports CAE,
and we'll be working to do more
Microsoft APIs as well as
giving you the tool so that you can add it to
your own APIs as well.
Thank you very much. I really
appreciate your time coming to
the session and enjoy the rest of Build.