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.
Allowed redirects are set in the
RedirectUri
property of your Identity ServerClient
configuration. The redirect for your client app's request is then set in theredirect_uri
request parameter (for example explicitly through your forms post usingredirect_uri
or using theUseOpenIdConnectAuthentication
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
orResourceAuthorize
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 theAuthorize
/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 yourOpenIdConnectAuthenticationOptions
for your client app.