AuthorizeAttribute for Actions

1.3k views Asked by At

TL;DR: How does an MVC app know to redirect to a certain action after going through authentication process when IdentityServer3 does a form post to the return url which is always the root url?

The examples in this question are taken from the provided sample app "MVC Authentication" that comes with IdentityServer3.

When plugging in IdentityServer3 into an MVC app, one provides some client information including a redirect url, which is usually the root url. So when an action requires authentication, it will redirect to IDP who performs authentication. After that, there is a form post to return url which looks like this:

POST https://localhost:44319/ HTTP/1.1
Host: localhost:44319
Connection: keep-alive
Content-Length: 2213
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: https://localhost:44319
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: https://localhost:44319/identity/connect/consent?client_id=mvc&redirect_uri=https%3A%2F%2Flocalhost%3A44319%2F&response_mode=form_post&response_type=id_token%20token&scope=openid%20profile%20roles%20sampleApi&state=OpenIdConnect.AuthenticationProperties%3DAzAv5NequrWeysjiZ6TDUYTh4UQkWPvgTAIQ4RNg6rCzbdNLvQsHNSwRLyJfRuR1Kvn0IbQFrbiJ4hLD3LCTRRK6PZY0eL2uB8BKEioOCou2SUSCpDTG-dkSk-0SqkOc_17_x0yFjB171-VoGfTPYzBxbd-JkFWrEQQ2_fRP4mvbw7Uo7vo9Udu9c_u2nxL_R8LYc9kS5t8iuNt4Ydbxdw&nonce=635757605373442818.ZDBkNGNkMjgtYzBkNS00OGVjLTg0MzMtNGJjMjdmODRjMDYzN2M4MmE0ZjMtMzM4YS00YzA1LTgwYzEtYmNiODFiZjdiNjZm
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: OpenIdConnect.nonce.OpenIdConnect=el9COXpSbS1PWmdPbW9oUHNTcEFfLUxkVklJQ3lPUzJsYkpTbU1NcXlfZ0JMMlVDWW9BVnowNEpNZDVNUTgyWG9lZ3hiQ3FlUXY1dUJmdmdhMHhzNkRZSnBIcmZoeHFGR214Qmt6cHl6a0lJc2NiTUJPRk1yeWduX3hoODBGaC1fMnZWbXZUajRjX2pEQ1gtMkJ2SDcyTXhRZjVVeHNoUzV2SVRlbXRPWk9iNWtRdHJfdU8weVNHQVZnQTNBSUVZelNMcFB6ZDZuT09kcW40RU9COUN1NW1TbklqMnR4MWl6NEtOcExDaVMtTQ%3D%3D

id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSIsImtpZCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSJ9.eyJub25jZSI6IjYzNTc1NzYwNTM3MzQ0MjgxOC5aREJrTkdOa01qZ3RZekJrTlMwME9HVmpMVGcwTXpNdE5HSmpNamRtT0RSak1EWXpOMk00TW1FMFpqTXRNek00WVMwMFl6QTFMVGd3WXpFdFltTmlPREZpWmpkaU5qWm0iLCJpYXQiOjE0NDAxNjM3NTIsImF0X2hhc2giOiJNTlRZTmtMVDhhY2NtcTdWQVJvOThnIiwic3ViIjoiMSIsImFtciI6InBhc3N3b3JkIiwiYXV0aF90aW1lIjoxNDQwMTYzNzQ5LCJpZHAiOiJpZHNydiIsImlzcyI6Imh0dHBzOi8vbG9jYWxob3N0OjQ0MzE5L2lkZW50aXR5IiwiYXVkIjoibXZjIiwiZXhwIjoxNDQwMTY0MDUyLCJuYmYiOjE0NDAxNjM3NTJ9.EgM5TogdDx3o25Otw9VVgXBzWQfzwt3s9pu4YmajNgiVh4ujj4eg2klrti7YDkd7jdxawNdogewc1ajxYR-r4TAxg3Brd3c8kFSCfXhEsr3DLakbYkWA8CaBJTqnVUnq_jadzUX4OkW9VPfLWlqkl0qRazogH06MAFVyge8k8PgGdf1Zk4RaRoX7bPyZ95ULivuXBt4aySQCVMS_GC03VxQksw3h3O-hzsJvm73OKKSo_wOikzsiozOkkA5sOZrVHGl7vQbLtsDTsMxXSLg6n-Kf4gySwskfAc-5okjgjBjjBm3OuzsaspHBZC2mlchaD_tllA0LHooi9Lna0REY7Q&access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSIsImtpZCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSJ9.eyJjbGllbnRfaWQiOiJtdmMiLCJzY29wZSI6WyJvcGVuaWQiLCJwcm9maWxlIiwicm9sZXMiLCJzYW1wbGVBcGkiXSwic3ViIjoiMSIsImFtciI6InBhc3N3b3JkIiwiYXV0aF90aW1lIjoxNDQwMTYzNzQ5LCJpZHAiOiJpZHNydiIsInJvbGUiOlsiR2VlayIsIkZvbyJdLCJpc3MiOiJodHRwczovL2xvY2FsaG9zdDo0NDMxOS9pZGVudGl0eSIsImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0OjQ0MzE5L2lkZW50aXR5L3Jlc291cmNlcyIsImV4cCI6MTQ0MDE2NzM1MiwibmJmIjoxNDQwMTYzNzUyfQ.nDSz4uQcyW6deZDxU2BXRjd5nKlMhbgbilEpD_yLhtbxg91N0DpNBOqVDmt4JbaOAKP9gIMDpaE8ZQR-NLQVtyKzNL8JuYLngmKrQPJJ-GM75qthpGIj72y8fo-OvOoiKEa3zQdbYjfVuSaQxmDiQ4mK4COSrvkB4SyIlEhvkMHFCrJFoktuhgpZl-jNe1ISGB6aDgZO2YTMo5LbVwBx0GS90cP0dMi8uCrDxql84P8Wg7_XTMkMYuVYeyYoukeNoaALBfWiCehOsdECQYZEMtaFTn47qaxvEpECdKaekoMCeJvqavGqpkCmRc-IK6Y3_qgtedibOhHTAIsbrpWzeg&token_type=Bearer&expires_in=3600&scope=openid+profile+roles+sampleApi&state=OpenIdConnect.AuthenticationProperties%3DAzAv5NequrWeysjiZ6TDUYTh4UQkWPvgTAIQ4RNg6rCzbdNLvQsHNSwRLyJfRuR1Kvn0IbQFrbiJ4hLD3LCTRRK6PZY0eL2uB8BKEioOCou2SUSCpDTG-dkSk-0SqkOc_17_x0yFjB171-VoGfTPYzBxbd-JkFWrEQQ2_fRP4mvbw7Uo7vo9Udu9c_u2nxL_R8LYc9kS5t8iuNt4Ydbxdw&session_state=9WBSt6Ko4espJ13yDbna9KIFe5kH8T4r8XtqeyoiIbA.ceb624206fccd4d72d79b53949693b3c

This particular request will result in a 302 redirect to /Home/Contact in the MVC application

HTTP/1.1 302 Found
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Location: https://localhost:44319/Home/Contact
Server: Microsoft-IIS/8.0
Set-Cookie: OpenIdConnect.nonce.OpenIdConnect=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT
Set-Cookie: .AspNet.Cookies=JTvNM4i1jqb21SRYih59M2T1dPrbreQAXZ5d8DRlQmQf4vH-3r6wKxOABocffMC7tDSXFbqydxyllXZChSRvlrzaUmVkrZoCuoENMzBukchjdRxsnJLCV9pf3PCJsXCBOj_b8bLLDioqaKSOOSbBgAHdHplVEdBpcmt2EDcwDfWpTsiRlhn03pd4-nKc22OA-qZuGCEenG3OlDzMitCdbufgW7p2Z1rZ0WpSv70O_DFKdcP0zvGB8nm5YazpUPGthn3f-B5u7YpeCrLTifesKFBQz4hmsczbzKI2_NUJDEw-WqUucVN4DCLaSngoRrnR-PS0xB4PqgNt39nPD2KeaiQzmTf0kBNMsqSjspOWWNpUqYzFB3zstxPipRvCG4dUOPfqnrqJwyNuDxDCe15yFpcjmvqDaXjLnXQO_-3OfxlOjxG2VDqJXo6ZufimKiKfPxm5jINPvZ_ci__ZGOeRvulFex0bZk6DD8ZgOxBuTPtW7dSqypv-h-M817MIO5Su3AITbq3tznAY_nZwo7bkfQiGmciE5BNHVPfWtBo3bSPLNBr0ZoKsgVGUfRoRBoY-dndiNTZftZNysfsEcod5aDInZvlQSv1cJpShJqdZEJA6VeIe9JUpWgDzKikDYFWsUJ3bXTNrv28aC_XJjuVyyEXH3onVrpoyvB1QD9BGQ9FKERvNf3xMV9jr_aMgJvf-Q3rdmmlPadQnvvy4S0_kYaTt69dtgJL_HIjyKPduqCAnwjWkksIIHsONU07JgClcS3C9oHwb0iUUWzk7MmgLWHP1S6GQCOUIIgxgTOUdNf8DnC6Zzthbhfev92QymQ8vQxrFIgF-ImK0TjHnJdijJBTzbRJSBdVdi-lUalDlzsO0pgePzKL3fYfQcyHKMqG9_eQ-rgo7lVYwWY10WT3ZMNawVQmIQoIIJ5AXH4RLu0tUnuzxOk-alJukEE8Z8n1k6IIcfPul50skTv2B7rrsZfJZRCJu3_zZZ6WvgRAuFvhtLVFEgCVLX5_b_9Q7kIk-ZB_j1iJ9pUe29P1SFUVC1i9Sl41RbeAQN0v7NzQ9SM2S49-4xZ7C5CkYl8_5XxhUwc4Gh0EC9-AuXRBzAQKx3UjUhwUsEfibloxVz9fdz79-ouRadNPovlII-WU9MuL6_iyijROyWzAiKYiAR800pHbmPxAZQjQ6QYt1fj-M-bckDzyI8hX4ZhKxn3Gin5mzlGCJWe2dL5sInOq5tTz2fvPP24JxuHCjASalAqDl4j-QmiL0KlNXwzL7ttXlX9dEB9ptYA50b9Wr9h8Y-HbdZW8Zs5HMRZV763z5uEL613ZCbBZuDuhgz8_y5rHkQtpDrVU8xjtyRhpB2WdMaxKBWEXO-Qw5CZR5IkXbfGJ84k6F3TH3f4IkEhVPhAwinsphht1TQnibkxRpv0xP2Zn9VLZ0lTvWL5-T9gFCNru25wl7otoDFlFqWwyQcXwjKpRgrZIH3ebbqw86iIY1DavOPEWZBe1h8HQN8OroMNgYPWiB9G1nKrIj0ZQHxaaKCHkso4IMnnPe30kXjeGoA83kSQCN8z8iVdamqoem7zHt1RfRIwQNii8cy_MPZ_He0F1p8xdjiyGzJkjGpGk0xxCAD_T_pa7rcIHtLGgi9VfP_oQy_VWqaua9pRMObuczC9mj9MTEK-mQQvWEiewHK0ioMu4yxbN22OPSRKrEbmSzF3-P4lLMgQo8MXnMGJ7CeeZuXZ4nu8qAaWIOS1jGbCNXbZWDZ5GBmB-VTn_jqR_tjvO1_p011alg7g0rCtgjnlYaO1wYtDILx79sPwvxeVOOWefVR7TkTQ__3ZFn6z4NISg4CJ9eKDTd3y7Q8eKo4_i3jljxXGhpwXyCFL2Ks2TzGQ6BWv7R9kXAbDCTGBq-PG_eUppkM1o8VUaXmQ8SQoLxA8rlgR54hO1CHPqe8fR9st_DRsk42cjn-ftsOvX63-8FxkzivIiIyaUW7y0V7HEIFuBJDGZHj_TJCK69xVLyu0KwsxhraXlQF5jhAOm5AnrPa-jQMNxdc65yj1H95nFM6SjZeCVfdMs5W_unD3WI2Q; path=/; secure; HttpOnly
X-SourceFiles: =?UTF-8?B?QzpcRGV2XElkU3J2U2FtcGxlc1xzb3VyY2VcTVZDIEF1dGhlbnRpY2F0aW9uXEVtYmVkZGVkTXZj?=
X-Powered-By: ASP.NET
Date: Fri, 21 Aug 2015 13:29:12 GMT
Content-Length: 0

My question is what in this request decides the final 302 redirect to correct controller and where in the MVC app does this happen? Reason is, I have an app where it doesn't happen so I need to understand.

2

There are 2 answers

1
Scott Brady On

Allowed redirects are set in the RedirectUri property of your Identity Server Client configuration. The redirect for your client app's request is then set in the redirect_uri request parameter (for example explicitly through your forms post using redirect_uri or using the UseOpenIdConnectAuthentication OWIN middleware. Redirects must go back to a subdirectory of your configured redirect URI.

The redirects to Identity Server itself are handled by the Authorize or ResourceAuthorize attributes in the example you mentioned. These attributes cause a 401 and then a 302 to your login page (in this case an embedded asset within Identity Server).

Identity Server only uses the redirect URIs you supply. The redirect to the correct controller in the application after login is handled entirely by the application. In the case of the example the redirect back to the /Home/Contact controller is handled by the UseOpenIdConnectAuthentication middleware and the Authorize/ResourceAuthorize attributes.

If you have an issue where this is not happening, your best bet will be to post your Client class for Identity Server and your OpenIdConnectAuthenticationOptions for your client app.

1
Danila Polevshchikov On

state=OpenIdConnect.AuthenticationProperties may have information about redirects. This data in encoded, you can use katana source for try to decode this data and check what inside.

Also nonce is the unique parameter for each authN requests and can be used by you application (by UseOpenIdConnectAuthentication middleware) to determine original URL like /Home/Contact and redirect to them