Once your users can access your application, you still need to make authorization decisions, and there
are different approaches to doing that.
The one I want to show you here is to use the groups that a user has been assigned in Active Directory
as roles in your application with which you can make authorization decisions.
Let's start by opening the application group in PDFs and the web application portion that we're accessing.
And let's modify the issuance transform roles.
Let's delete the one created in the previous example that returned all claims in a custom rule.
So let's add a new rule, and we've got several templates we can choose from.
Let's use the first one.
Send LDAP attributes as claims.
Let's give this rule a name for the interface, and now we can map incoming claims to outgoing claims.
First I'm going to choose the display name coming from Active Directory.
And let's map that to the common name claim in the outgoing claims that are returned to the application.
Next lets choose token groups unqualified name.
And these are the groups that the user has been assigned in Active Directory.
This will create a separate claim for each group assigned.
And let's map this to role in the outgoing claim.
The reason I'm using role instead of group is because ASP.NET Core will map these to a special collection
on the user identity object so you can query them as roles rather than treating them like every other
claim.
But they are still claims, as you'll see in the code.
Okay, let's choose the attribute store, which is Active Directory and click Finish.
Now I'll apply these changes and click okay and okay again.
Now let's go back to Visual Studio and let's go to the code behind for the homepage indexed CSV, HTML,
CSS.
Let's put some code in the on get method just so we can set a breakpoint and step through it.
I'm going to paste in some code.
This is just so you can see some of the properties on the user object that's available in your code
behind.
Let's resolve this by importing the correct using statement and let's set a breakpoint and debug the
application.
I'll enter my user information in the ad FS login page and because we're sent back to the home page,
we hit the breakpoint in our application.
Now let's see how those raw claims we saw on the screen previously are being parsed by ASP.NET Core.
User Identity Name gives us the Windows Domain name for the user, and the authentication type is federation,
which is interesting.
Now this next piece of code is why I translated the group names to roles.
When you do that, you can use this as an method on the user object because ASP.NET Core will parse
the role claims into a special collection that's available right on the user object.
You can do it long way also by using the has claim method and passing in the actual claim type.
And this is the most generic way to do it.
Or for common claim types, the framework has an enumeration that provides a shortcut to typing the
long claimed type names.
Here I'm using clean types role and passing in the same value as above.
Now I'll press continue and we get brought to the page.
You can see the role claims are available here and each roll has its own claim issued.
So that's how to access claims and code.
But let's see how we can make authorization easier.
I'm going to go back to Startup Dot CSS and in the Configure Services method, let's add this code below
the authentication code we added earlier services, add authorization and the options we're going to
configure is to add an authorization policy, let's call it can access add me area.
And on the policy builder use the method require claim and the claim we require is a role claim with
the value domain admins.
Let's just resolve this by adding the using statement at the top.
Now this is just a definition at this point.
We need to apply it somewhere in order to use it.
We're going to set this policy on a page in the application.
But before we can do that, we need to tell the middleware what to do when the user is denied access
to the page.
We do that in the ad cookie extension method here by configuring the access to night path.
We could redirect the user to a custom error page, but let's just redirect to the root of the application,
which is the index page.
So let's go to a different page in the application.
The template we used has this privacy page, so let's just use that.
Let's add the authorized attribute onto the class and resolve the missing using statement.
This will require that the user be authenticated in order to access this page.
But for this particular page, we want to use the authorization policy we just created in startup.
So let's add a parameter in brackets policy equals and the name of the authorization policy we created.
Now let's run the application.
I'll log in with my user credentials and were brought to the breakpoint again.
Let's remove this and click continue in the debugger.
We get brought to the home page and I'll click on the link to the privacy page.
This user account has the domain admins role assigned, so I'm successfully brought to the page.
Now let's close this and test the app again.
But this time I'll log in with a different user, one that's not a member of the Domain Admits Group.
You can see this user only has the domain users role assigned.
So let's click on the privacy page link.
And it looks like nothing happened.
But you can see in the address bar at the top that the returned URL parameter was added and we've actually
been redirected to the home page because that's what we configured to happen when the user doesn't meet
the criteria of our authorization policy.
So that's how you can use claims for authorization within your application.
Next, let's deploy this test app to an IIS server so we can focus on authentication methods in the
next module.
Now let's package the sample application and deploy to an IIS server where we'll run it for the rest
of the course.
I've made a small change to the code here in the startup CSS class.
Instead of hard coding the URL to the ADF's server and the client ID of the application in the application
group, I've used configuration to store those values in the app settings dot JSON file.
We won't need to change them in ADF RFS though since we're going to use the same application group.
But we will need to make one small change.
Let's go to Solution Explorer.
Right click on the project name and click on Publish.
That brings up the dialog where we choose a published target.
I'm just going to pick a local folder here to publish to.
Let's choose a folder and I'll go to the desktop and choose an empty folder I created for this purpose.
And then we just click on Create Profile.
Now we can publish to this profile without having to configure it again.
So I'll click on publish.
It will take a few seconds for Visual Studio to compile the project and publish the files to the local
folder.
Then we can open up File Explorer and navigate to that folder on the desktop.
Now we're going to copy these files over to the IIS server for a simple copy paste deployment.
I have a virtual machine configured with the IIS web server role, but one additional thing I had to
do was download the ASP.NET Core 3.1 runtime and install it on this web server because it doesn't come
as part of the operating system.
Over on the IIS server, we're just going to use the default website that gets configured when you install
IIS.
So let's open up file explorer on the IIS server and navigate to the C drive and that pub and the root
folder which is the root of the default website.
There are a few default files here, so let's delete these and now I'll paste in the files for the new
website.
I need to provide administrator permissions to paste these in the folder.
Let's just go back to Ice Manager.
And I did make an additional configuration here to enable Zsl.
I added a binding to the default website for https and enrolled the server with a certificate issued
from Active Directory Certificate Services, which is used as the SSL certificate.
That's important because we need to configure the redirect URI in advance to redirect back to the address
of this web server, which will be an https URL.
So let's bring up the ad FS server and in application groups, there's the app we created earlier.
I'll double click on it.
And we don't need to change the web application because we're not changing the client ID, we need to
change the native application portion.
So I'll double click on that and let's delete the redirect.
Uri that points to local host on the development VM and let's replace that with the name of the web
server.
Because remember, we installed the application at the root of the default website, not in a subfolder.
And that's all we need to do.
Let's.
Okay.
Out of this configuration and let's go back to the management VM.
Now I'll open up Microsoft Edge and navigate to HTTP, colon, slash, slash server one.
Pry, which is the root of the web server and I'm redirected to the ADF's login page.
So I'll enter my credentials and I'm authenticated to the application and the claims are displayed.
You can see in the address bar that we're now getting this web application from the deployed files on
the server one IIS server.
Since Windows Server 2016, ADF RFS has supported access control policy templates.
These replaced the need for writing policies using claims rule language.
Access control policy templates allow an administrator to enforce policy settings by assigning the template
to a group of relying parties.
Subsequent changes to the policy template will then be applied to all the relying parties automatically.
ETFs comes with default access control policy templates for common scenarios.
For increased flexibility.
You can create your own custom templates.
Lets right click on the Access Control Policies tab and click Add Access Control Policy.
I'll give this new policy a name and let's add a rule for permitting access.
There are two main areas here.
The permit options at the top and then a list of exceptions we can add.
We could allow access for everyone to start, but lets limit access to users coming from a specific
network and in the box at the bottom we can choose the network.
We can limit this to the corporate intranet from the internet or from a specific IP address or range
of IP addresses.
Let's select that.
We want this rule to apply to users coming from the Internet.
Now, let's say we want this policy to require that these users perform multifactor authentication and
let's choose a group of users to exclude from this policy so they won't need to perform MFA when coming
from the Internet.
We can require that this group is configured each time this custom access control policies apply to
relying party.
Or we can choose a security group here in the template that will always be used.
Let's select security groups and I'll add one.
I've created a custom security group in Active Directory and called it Excluded Users List.
I'll verify that name and let's click.
Okay and okay again.
Now we have a policy that requires users coming from the Internet to perform multifactor authentication,
except if they're included in the excluded users list security group.
Okay, let's save this policy.
Now, the policy shows up in our access control policies list.
If I open up the application group we created in the server application being accessed, there's a tab
of the top for access control policy.
Now, besides all the built in policies, we can select the custom policy we just added.
So that's how you can add a custom access control policy to add ZFS for use with relying party applications.
A new feature in ADF's 2019 is the ability to customize the HTTP security response headers sent by ADF's.
So why would you as an administrator of ADF's want or need to do that?
Well, there are advancements in browser based protection mechanisms that you might want or need to
take advantage of.
A good example is if you're publishing single page applications that need to take advantage of cross
origin resource sharing web browser security prevents a web page from making cross origin requests from
within scripts.
Cross Origin Resource Sharing is a W3C standard that allows the server to relax this policy for approved
URLs using CRTs.
The server can allow some cross origin requests and reject others.
CRC is turned off by default in ADF's, but you can enable it and set the origin domains to allow a
page to access a web API within another domain.
Another example is the X Frame Options header.
By default adds FFS doesn't allow external applications to use iframes when performing interactive logins.
This is to prevent certain types of phishing attacks.
But when you do want to trust a specific application to use an iframe capable interactive ADF's login
page, you can specify origins in the HTTP header that the page must match.
The PowerShell command accepts any header name and value though, so you can use it for many purposes,
like setting a content security policy, setting HTTP, strict transport security or setting completely
new custom headers specifically for your applications.
The ability to customize HTTP security headers can also be added to add 2016 by installing a couple
of KB patches.
Now let's see how to configure this in PowerShell and we'll see what the headers look like by examining
them in Fiddler.
I'm on my Windows ten Management VM and let's start by opening up the Windows Admin Center.
I already have the ADF's server added as a remote connection.
So let's navigate to that.
And once the connection is made, let's scroll down to the PowerShell tab that opens up a PowerShell
connection to the ADF's server.
Now let me clear the screen and let's zoom in the browser window a bit.
So this is easier to see.
Okay, let's use the new ADF's PowerShell command set out for response headers and type the parameter
enable course.
This will enable a cross origin resource sharing that I mentioned and let's set the value to true.
Now let's set the list of trusted origins by typing the set at Response Headers Command again, and
this time the source trusted origins parameter is used and you can list the domains that are permitted
separated by commas.
And that's it.
Now let's set a custom header and you can do this for whatever purpose you might need.
It's just a flexible way of having a PDFs.
Send an HTTP header.
Will you syntax response headers again this time using the generic parameters, set header name and
set header value.
And that's it.
Now let's see what these HTTP headers look like when returned from PDFs to the browser.
I have Fiddler installed on this VM to monitor the HTTP traffic.
So let's start monitoring by turning on captured traffic and let's go to Visual Studio on this VM and
run the sample project that opens up a web browser.
And let's zoom out to normal text size first.
Now I'll log in with my account and when we're redirected back to the local web server, I'll open up
Fiddler and let's look at the HTTP traffic that was captured.
I'll select one of the connections to the ADF's server and this is the token endpoint where the access
token is retrieved from after authentication in the response headers under miscellaneous, there's the
test header, name and value we just configured on the ADF's server.
In this module you learn about claims and ADF's and the protocols that ADF's supports for the authentication
process and the tokens returned.
You saw how application groups are used to organise groups of clients and servers that form an application.
And you created an ASP.NET Core application to display claims return from ADF's.
We examined configuring claims rules in ADF, PFS as well as how to use claims for authorization in
code.
Then we looked at custom access policies that make it easy to configure access rules in the claims pipeline.
And finally, you saw how to customize HTTP response headers that are returned from ADF's in order to
take advantage of browser based protection mechanisms.
In the next module we're going to start configuring our ADF server to perform different types of authentication,
including integrating with Azure Active Directory to enable multi-factor authentication.