1 00:00:03,010 --> 00:00:08,560 Now let's create a sample application in Visual Studio and we'll use this app throughout the rest of 2 00:00:08,560 --> 00:00:13,060 the course to test authentication and to view the claims that are returned from ADF's. 3 00:00:13,750 --> 00:00:18,850 If you'd rather skip this clip, you can get the deployment files for this application from the course 4 00:00:18,850 --> 00:00:19,690 downloads. 5 00:00:20,290 --> 00:00:23,440 Let's open up Visual Studio and create a new project. 6 00:00:23,440 --> 00:00:28,210 And I'm going to select ASP.NET Core Web application and give the project name. 7 00:00:28,840 --> 00:00:32,440 We're going to be configuring this to use open ID connect with ADF. 8 00:00:32,740 --> 00:00:35,380 So I'll include DC in the project name. 9 00:00:35,380 --> 00:00:36,580 So that's obvious. 10 00:00:37,300 --> 00:00:43,210 Then let's click create and here we can choose the framework and the project template. 11 00:00:43,870 --> 00:00:50,140 I'm using ASP.NET Core 3.1, which is the latest version of the framework at the time of filming. 12 00:00:50,790 --> 00:00:56,520 I'm going to use the web application template which uses razor pages and I'll leave the default of no 13 00:00:56,520 --> 00:00:57,600 authentication. 14 00:00:58,200 --> 00:01:01,560 We're going to add authentication middleware in code. 15 00:01:02,190 --> 00:01:03,960 Now I'll click Create. 16 00:01:04,560 --> 00:01:08,520 And when the project opens, let's open solutions explore. 17 00:01:09,160 --> 00:01:14,410 The first thing you need to do is right click on dependencies and choose managed NuGet packages. 18 00:01:15,010 --> 00:01:19,030 We need the NuGet package that adds the authentication middleware. 19 00:01:19,660 --> 00:01:25,990 So let's go to browse and search the package source on the Internet for Microsoft, ASP.NET Core Authentication 20 00:01:26,230 --> 00:01:27,460 OpenID Connect. 21 00:01:28,090 --> 00:01:31,030 And here's the package for the Middleware Library. 22 00:01:31,680 --> 00:01:35,130 So let's click that and on the right click install. 23 00:01:35,760 --> 00:01:39,750 You just need to agree to changes and accept the license agreement. 24 00:01:40,350 --> 00:01:45,960 Once the library is added, let's close these panes and the NuGet package manager also. 25 00:01:46,590 --> 00:01:50,610 Now let's add the code to force authentication using the middleware. 26 00:01:51,230 --> 00:01:52,850 We do that and start up. 27 00:01:54,590 --> 00:01:58,820 So let's open that up and scroll down to the Configure Services method. 28 00:01:59,610 --> 00:02:04,110 I've got some code on my clipboard that I'm going to paste in and then we'll go through it. 29 00:02:04,670 --> 00:02:10,250 But first let me just format this a bit and we need to import some using statements for these classes 30 00:02:10,250 --> 00:02:11,900 that aren't being recognized. 31 00:02:12,530 --> 00:02:17,180 You can do that by right clicking and selecting quick actions and refactoring things. 32 00:02:17,970 --> 00:02:21,240 I'll bring in the identity model protocols namespace. 33 00:02:21,870 --> 00:02:25,890 And further up here we need authentication, cookies and authentication. 34 00:02:26,160 --> 00:02:27,420 OpenID Connect. 35 00:02:28,150 --> 00:02:28,630 Okay. 36 00:02:28,630 --> 00:02:32,560 So this code calls the ad authentication method on the service collection. 37 00:02:32,560 --> 00:02:36,340 And the first thing we can figure is the default authentication scheme. 38 00:02:36,970 --> 00:02:42,670 In this case, it's the cookie authentication scheme, which means that every time the page is accessed, 39 00:02:42,670 --> 00:02:46,360 we check to see if the user has an authentication cookie already. 40 00:02:47,040 --> 00:02:51,300 If they don't, then the default challenge scheme is OpenID Connect. 41 00:02:51,930 --> 00:02:57,660 Then we add the add cookie extension and will be adding more configuration to that later in the module. 42 00:02:58,330 --> 00:03:01,270 And in the ad OpenID Connect Extension Method. 43 00:03:01,270 --> 00:03:03,490 Let's look at the configuration here. 44 00:03:04,150 --> 00:03:09,550 Normally you'd put the values in a configuration file, and we'll do that for the deployment. 45 00:03:10,150 --> 00:03:13,690 But it's easier to see the actual values in Code four now. 46 00:03:14,320 --> 00:03:17,080 The first thing is the metadata address. 47 00:03:17,710 --> 00:03:24,190 If we were using Federation as the protocol, this would point to the Federation metadata XML document 48 00:03:24,190 --> 00:03:28,930 to tell our application all about how to decrypt tokens and what claims are available. 49 00:03:29,670 --> 00:03:34,980 Because we're using open ID connect, there's a different endpoint on the ADF's server. 50 00:03:35,680 --> 00:03:39,130 For your environment, you'll need to change the server name. 51 00:03:39,730 --> 00:03:42,170 Everything else will remain the same after that. 52 00:03:42,190 --> 00:03:49,060 We're going to get the client ID value when we configure the application group in ADF's sign in scheme 53 00:03:49,060 --> 00:03:52,960 is actually redundant since we've already specified a default scheme. 54 00:03:52,960 --> 00:03:54,760 But it's good to be explicit. 55 00:03:55,420 --> 00:03:59,410 Require HTTP metadata actually defaults to true. 56 00:03:59,980 --> 00:04:04,510 But if you needed to disable it in a dev environment, you could with this value. 57 00:04:05,200 --> 00:04:11,260 Of course ADF only publishes on https, so this isn't really necessary either. 58 00:04:11,960 --> 00:04:17,990 The response type is an open ID connect parameter that tells us what we want returned. 59 00:04:18,650 --> 00:04:25,700 In our case, we want the authorization code, but we could ask for the access token, ID token or a 60 00:04:25,700 --> 00:04:26,690 combination. 61 00:04:27,290 --> 00:04:32,390 The middleware will use the authorization code to make its own call to get an access token. 62 00:04:32,990 --> 00:04:38,540 The response mode is a parameter that will tell a DFS how to send the token information back to the 63 00:04:38,540 --> 00:04:39,290 client. 64 00:04:39,980 --> 00:04:47,000 Form post is the default, so the browser will redirect to the application the user is trying to access 65 00:04:47,000 --> 00:04:50,540 and the tokens will be passed as form values in a post. 66 00:04:51,170 --> 00:04:56,990 You could also choose to have the tokens attached as a query string value or as a URL fragment in the 67 00:04:56,990 --> 00:05:00,080 case of a single page application, for example. 68 00:05:00,740 --> 00:05:06,050 Next, we need to specify scopes, and these need to correspond to scopes that have been configured 69 00:05:06,050 --> 00:05:08,960 in ADF's for this relying party application. 70 00:05:09,590 --> 00:05:12,560 The only scope we need is the opening scope. 71 00:05:13,200 --> 00:05:17,880 In order to tell ADF's that we're using the open ID Connect protocol. 72 00:05:18,510 --> 00:05:24,480 And the safe tokens value being set to true tells ASP.NET Core that we want to store the access token 73 00:05:24,480 --> 00:05:29,670 and refresh token in the authentication properties class after a successful authentication. 74 00:05:30,270 --> 00:05:32,310 This is false by default. 75 00:05:32,910 --> 00:05:38,430 So I've set this so we can query the raw token values and display them in the browser for the sample. 76 00:05:39,060 --> 00:05:42,180 Now let's move down the code to the configure method. 77 00:05:42,910 --> 00:05:43,270 Here. 78 00:05:43,270 --> 00:05:47,680 We just need to add app use authentication and the order is important here. 79 00:05:48,310 --> 00:05:51,370 This needs to come right before use authorization. 80 00:05:52,060 --> 00:05:55,840 Okay, now let's add the code to display the claims on the screen. 81 00:05:56,500 --> 00:06:01,840 I'm going to open up the default page for the app which is indexed csv html. 82 00:06:02,470 --> 00:06:05,830 Let's replace the code here with some code I've already written. 83 00:06:06,430 --> 00:06:12,670 At the top we're adding a using to Microsoft ASP.NET Core authentication, and that's so we can display 84 00:06:12,670 --> 00:06:15,670 the token values from the authentication properties. 85 00:06:16,300 --> 00:06:21,340 The actual claims are already in the user object, so we can just loop through them and display the 86 00:06:21,340 --> 00:06:23,470 claim type and value in a table. 87 00:06:24,190 --> 00:06:29,590 Then below that is where we get the raw JSON web tokens that come in base 64 format. 88 00:06:30,300 --> 00:06:32,670 I'll show you why later in the module. 89 00:06:33,300 --> 00:06:38,100 Now, the next thing is to open up the code behind for this page and add this authorized attribute to 90 00:06:38,100 --> 00:06:43,680 the top of the class, which tells ASP.NET Core that the user needs to be authenticated in order to 91 00:06:43,680 --> 00:06:49,320 access this page, which of course will force the redirect to add ZFS, since the user won't have an 92 00:06:49,320 --> 00:06:52,560 authentication cookie the first time they accessed the page. 93 00:06:53,190 --> 00:06:58,440 The last thing I'm going to add is some code to the layout page, and this is just some CSS to help 94 00:06:58,440 --> 00:06:59,820 with displaying the table. 95 00:07:00,470 --> 00:07:04,850 I already have that written, so I'll just paste it into the head of the layout page. 96 00:07:05,570 --> 00:07:06,070 Okay. 97 00:07:06,080 --> 00:07:10,520 Let's just build this and make sure there are no errors and the build succeeds. 98 00:07:11,150 --> 00:07:15,860 So next up, let's configure a PDFs to know about this application. 99 00:07:17,280 --> 00:07:22,320 Now let's configure the application group for authentication to our web application. 100 00:07:22,970 --> 00:07:28,160 I'm on the Windows ten management VM we used in previous module to set up ADF's. 101 00:07:28,890 --> 00:07:33,680 A I open up server manager which I installed with the remote server administration tools. 102 00:07:33,700 --> 00:07:38,860 Normally we can administer server features by going to tools and there should be an option for Active 103 00:07:38,860 --> 00:07:41,020 Directory Federation services here. 104 00:07:41,590 --> 00:07:44,860 But this actually isn't supported in the SAT tools. 105 00:07:44,860 --> 00:07:50,380 So we're going to need to either do the configuration remotely using PowerShell or remote into the actual 106 00:07:50,710 --> 00:07:51,550 FS server. 107 00:07:51,550 --> 00:07:57,700 In order to do the configuration, you could do a remote desktop from the Windows Admin Center. 108 00:07:58,290 --> 00:08:03,720 But for the sake of screen real estate, I'm going to remote into the VM that's running ADF's. 109 00:08:04,400 --> 00:08:10,760 I've already opened the ADF's management console from the tools menu in server manager on this VM. 110 00:08:11,360 --> 00:08:15,500 So let's go to application groups and right click and add application group. 111 00:08:16,070 --> 00:08:19,070 We went through these options in an earlier clip. 112 00:08:19,710 --> 00:08:24,870 The one we want, for the simple example is the web browser accessing a web application. 113 00:08:25,500 --> 00:08:29,100 Now let's give the application group a name and click next. 114 00:08:29,760 --> 00:08:32,400 Now we need the redirect, you or I. 115 00:08:33,030 --> 00:08:38,310 This is the address will be redirecting the browser to after a successful authentication. 116 00:08:38,940 --> 00:08:42,770 It'll be a local host address since we're running in Visual Studio. 117 00:08:42,780 --> 00:08:45,780 So we need to know the port number of the app is using. 118 00:08:46,380 --> 00:08:51,900 But first, let's copy the client identifier because we need to send this from the application. 119 00:08:52,500 --> 00:08:57,810 Now let's go back to the VM running Visual Studio and paste the client ID into our code. 120 00:08:58,410 --> 00:09:04,590 Now I know the application will be running on the local host server, but I need the port so we can 121 00:09:04,590 --> 00:09:05,940 get that from properties. 122 00:09:05,940 --> 00:09:07,920 Launch Settings JSON. 123 00:09:08,520 --> 00:09:12,930 The port for the app running on https will be 44386. 124 00:09:12,930 --> 00:09:15,330 But we could change that here if we wanted to. 125 00:09:15,930 --> 00:09:19,890 Let's just remember this port and go back to the ADF's server. 126 00:09:20,560 --> 00:09:26,740 Now we'll type in the address of the application, which is http colon slash slash local host port four 127 00:09:26,740 --> 00:09:31,380 four, three, eight, six and I need to add this path slash sign and oik. 128 00:09:32,160 --> 00:09:35,280 This isn't an actual page in the application. 129 00:09:35,850 --> 00:09:41,220 This is just the path that's picked up by the authentication middleware for Open ID Connect. 130 00:09:41,880 --> 00:09:43,890 Let's add this and click next. 131 00:09:43,890 --> 00:09:47,190 And this is where we can configure the authorization rules. 132 00:09:47,820 --> 00:09:51,060 Let's leave the default to permit all and click next. 133 00:09:51,690 --> 00:09:54,420 Here we can see a summary of the configuration. 134 00:09:54,420 --> 00:09:59,400 So let's click next and the application group has been created. 135 00:10:00,060 --> 00:10:04,590 Let's close this and right click on the application group and select properties. 136 00:10:05,220 --> 00:10:10,680 This shows us a list of all the client and server applications that are part of this application group. 137 00:10:11,340 --> 00:10:15,960 It says native application, but this is actually just the browser in our case. 138 00:10:16,620 --> 00:10:21,120 Let's close this and go back to the VM with our Visual Studio application. 139 00:10:21,810 --> 00:10:24,930 Alta save these changes and let's start debugging. 140 00:10:25,550 --> 00:10:32,420 The browser opens up to our application running on local host and because the user isn't authenticated, 141 00:10:32,420 --> 00:10:37,130 the middleware kicks in and redirects the browser to the ADF's login page. 142 00:10:37,780 --> 00:10:44,110 I have forms authentication set as the primary authentication method in advance so we can explicitly 143 00:10:44,110 --> 00:10:44,860 log in. 144 00:10:45,580 --> 00:10:48,310 I'll enter my credentials and click sign in. 145 00:10:48,880 --> 00:10:53,080 And here we can see the default claims that ADF's is sending back. 146 00:10:53,720 --> 00:10:57,410 Remember, we didn't configure any specific claims. 147 00:10:58,010 --> 00:10:59,660 We'll do that next. 148 00:11:00,280 --> 00:11:02,920 And at the bottom are the tokens that were returned. 149 00:11:02,920 --> 00:11:04,900 And these are basics for encoded. 150 00:11:04,900 --> 00:11:09,310 So they actually contain the claims information that you see above on the page. 151 00:11:10,060 --> 00:11:13,120 I'll show you how to verify that later in the module. 152 00:11:13,770 --> 00:11:21,690 There's the oath 2.0 access token at the top and below that is the ID token for open ID connect. 153 00:11:22,320 --> 00:11:27,510 Now that we have a working application, let's explore claims issuance rules a bit more in the next 154 00:11:27,510 --> 00:11:28,050 clip. 155 00:11:28,650 --> 00:11:33,570 I'm on the ADF's server where I've got the ADF's management console open. 156 00:11:34,200 --> 00:11:38,580 Let's go to the application group we just created and double click to open it. 157 00:11:39,210 --> 00:11:44,400 The web application in the applications list is where you can configure the claims that are returned 158 00:11:44,400 --> 00:11:45,690 to the application. 159 00:11:46,320 --> 00:11:49,410 So let's select that application and click edit. 160 00:11:50,030 --> 00:11:55,910 The properties are displayed and we can modify the access control policy from the tap at the top. 161 00:11:56,500 --> 00:12:02,020 We can configure the scopes in the client permissions tab and we can modify the issuance, transform 162 00:12:02,020 --> 00:12:02,680 rules. 163 00:12:03,340 --> 00:12:06,520 These are where we can figure the claims that are returned. 164 00:12:07,180 --> 00:12:09,640 Let's click that tab and add a new rule. 165 00:12:10,240 --> 00:12:13,480 What I want to do is return all the claims that are available. 166 00:12:13,480 --> 00:12:16,090 So let's do that by adding a custom rule. 167 00:12:16,750 --> 00:12:21,400 This opens a screen where we can type in a custom rule using claims rule language. 168 00:12:22,150 --> 00:12:24,190 I'll give the rule of name first. 169 00:12:24,820 --> 00:12:28,540 And getting into claims rule language is beyond the scope of this course. 170 00:12:28,540 --> 00:12:31,780 But let's just add a simple rule to issue all claims. 171 00:12:32,440 --> 00:12:34,170 That's all there is to the code. 172 00:12:34,180 --> 00:12:35,650 So let's click finish. 173 00:12:36,220 --> 00:12:42,340 We could add more rules to the list of claims rules, but this covers everything will need will use 174 00:12:42,340 --> 00:12:48,310 a different template in the next clip when we look at returning user roles now let's go back to our 175 00:12:48,310 --> 00:12:53,620 VM with Visual Studio and close the running application to clear the cookie from the browser and let's 176 00:12:53,620 --> 00:12:54,760 run the app again. 177 00:12:55,330 --> 00:13:02,620 So we need to log into ad FS, we get to the login page, so I'll enter my credentials and click sign 178 00:13:02,620 --> 00:13:04,180 in and we get an error. 179 00:13:04,880 --> 00:13:07,280 I actually traced this error using Fiddler. 180 00:13:07,280 --> 00:13:11,840 And what's happening is that we're returning so many claims in the response that it's exceeding the 181 00:13:11,840 --> 00:13:14,840 limits of the browser as it's configured by default. 182 00:13:15,440 --> 00:13:19,760 So I don't recommend sending every claim back in a production scenario. 183 00:13:20,340 --> 00:13:25,260 But since we're just training here, I'm going to show you how to override this in the registry on the 184 00:13:25,260 --> 00:13:26,400 local computer. 185 00:13:27,180 --> 00:13:30,120 Again, I don't suggest this for production. 186 00:13:30,690 --> 00:13:34,440 Let's close this and go to the search box and type in rejected. 187 00:13:35,070 --> 00:13:37,500 This opens the registry editor. 188 00:13:38,160 --> 00:13:42,870 If you're not confident with what you're doing here, you should back up your registry settings and 189 00:13:42,870 --> 00:13:44,220 proceed with caution. 190 00:13:44,820 --> 00:13:51,210 Let's go to HK underscore local underscore machine system, current control set services and scroll 191 00:13:51,210 --> 00:13:53,790 down to HTTP and click on the parameters. 192 00:13:53,790 --> 00:13:54,450 Hive. 193 00:13:55,050 --> 00:14:00,750 We need to add a couple of keys here to allow the browser to accept more data in a single response. 194 00:14:01,370 --> 00:14:05,990 And again, this is just so we can see all the claims possible from ADF's. 195 00:14:06,620 --> 00:14:12,050 Let's add a new D-word and give it the name Max Field length and set the decimal value to the maximum, 196 00:14:12,050 --> 00:14:15,200 which is 65,534. 197 00:14:15,830 --> 00:14:21,290 And let's create one more D word registry key and call it max request bytes and set the decimal value 198 00:14:21,290 --> 00:14:24,170 to 16777216. 199 00:14:24,800 --> 00:14:26,750 And that's all we need to do. 200 00:14:27,350 --> 00:14:32,900 Now let's close this and we'll need to restart this VM for the registry changes to take effect. 201 00:14:33,530 --> 00:14:35,210 So I'll speed things up a bit. 202 00:14:35,210 --> 00:14:37,700 And we're back with Visual Studio Open. 203 00:14:38,330 --> 00:14:42,500 Now let's run the app again and we're brought to the ADF's login page. 204 00:14:42,500 --> 00:14:45,230 So I'll enter my credentials and click sign in. 205 00:14:45,800 --> 00:14:50,360 And now we're brought into the application and we have considerably more claims displayed. 206 00:14:50,360 --> 00:14:55,250 Right now there's information about the authentication method used. 207 00:14:55,880 --> 00:15:01,280 There are security identifiers for the groups the user belongs to and I'll show you how to send actual 208 00:15:01,280 --> 00:15:02,990 group names in the next clip. 209 00:15:03,590 --> 00:15:07,700 There's information about the browser type the user used to authenticate. 210 00:15:08,300 --> 00:15:12,440 There's an indicator that the user came from inside the corporate network. 211 00:15:13,050 --> 00:15:18,360 There's the IP address of the user and the scopes that were sent in the open ID Connect request. 212 00:15:19,020 --> 00:15:21,600 Now let's look at the tokens below that. 213 00:15:22,200 --> 00:15:28,020 These are the values from the JSON web tokens that ADF's returned after authentication. 214 00:15:28,650 --> 00:15:33,120 Let's open another browser tab and navigate to JWT audio. 215 00:15:33,750 --> 00:15:40,080 This is a site that allows you to paste in a JSON web token and decode the base 64 encoded information. 216 00:15:40,680 --> 00:15:48,930 Let's go back to the application and let's copy the ID token and over in JWT IO, I'll paste the token 217 00:15:48,930 --> 00:15:49,410 in. 218 00:15:50,040 --> 00:15:53,310 On the right is the decoded value of the token. 219 00:15:53,880 --> 00:15:59,430 You can see the claims are here just as they were in the user claims collection that we iterated over 220 00:15:59,430 --> 00:16:00,750 in HTML. 221 00:16:01,380 --> 00:16:07,320 Now let's remove this token and let's go back and copy the access token and let's decode that value. 222 00:16:07,950 --> 00:16:11,970 It's largely the same values which may not always be the case. 223 00:16:12,600 --> 00:16:17,850 So if you ever need to debug the tokens that are returned from a PDFs, you know how to retrieve them 224 00:16:17,850 --> 00:16:20,520 in your code and where to go to decode the values. 225 00:16:21,150 --> 00:16:27,030 Next, let's look at how we can use claims in ASP.NET Core Code to perform authorization within the 226 00:16:27,030 --> 00:16:28,020 application.