{"action":"created","issue":{"url":"https://api.github.com/repos/aspnet/Security/issues/554","labels_url":"https://api.github.com/repos/aspnet/Security/issues/554/labels{/name}","comments_url":"https://api.github.com/repos/aspnet/Security/issues/554/comments","events_url":"https://api.github.com/repos/aspnet/Security/issues/554/events","html_url":"https://github.com/aspnet/Security/issues/554","id":113948133,"number":554,"title":"Breakpoint in Controller.OnAuthentication() results in catastrophic failure of OpenIDConnect","user":{"login":"dapug","id":1814306,"avatar_url":"https://avatars.githubusercontent.com/u/1814306?v=3","gravatar_id":"","url":"https://api.github.com/users/dapug","html_url":"https://github.com/dapug","followers_url":"https://api.github.com/users/dapug/followers","following_url":"https://api.github.com/users/dapug/following{/other_user}","gists_url":"https://api.github.com/users/dapug/gists{/gist_id}","starred_url":"https://api.github.com/users/dapug/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dapug/subscriptions","organizations_url":"https://api.github.com/users/dapug/orgs","repos_url":"https://api.github.com/users/dapug/repos","events_url":"https://api.github.com/users/dapug/events{/privacy}","received_events_url":"https://api.github.com/users/dapug/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-10-28T23:29:56Z","updated_at":"2015-10-29T22:44:45Z","closed_at":null,"body":"**Evil Problem:**\r\nIf you override **OnAuthentication** in your MVC controller, AND you happen to simply set a **breakpoint** in that method, your OpenIDConnect notifications will NOT fire!  **Authentication fails** despite the server returning the code and tokens.  Remove the breakpoint, and suddenly OpenIDConnect works again.\r\n\r\n**Set up:**\r\n - Create a simple hello-world MVC client with \"hybrid\" flow connecting to an OpenID authority\r\n - Configure OpenIdConnectAuthenticationNotifications as usual, with methods such as  **MessageReceived** and **AuthorizationCodeReceived**\r\n\r\n```\r\n            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions\r\n            {\r\n                ClientId = \"client\",\r\n                Authority = \"https://localhost:44302/core\", // Thinktecture IdeneityServer3\r\n                RedirectUri = \"https://localhost:44300\",\r\n                PostLogoutRedirectUri = \"https://localhost:44300\",\r\n                ResponseType = \"code id_token token\",\r\n                Scope = \"openid profile read write offline_access\",\r\n      \r\n                Notifications = new OpenIdConnectAuthenticationNotifications\r\n                {\r\n                    MessageReceived = n =>\r\n                    {\r\n                        //var foo = n.ProtocolMessage;\r\n\r\n                        return Task.FromResult(0);\r\n                    },\r\n                    AuthorizationCodeReceived = async n =>\r\n                    { ...\r\n```\r\n - Create an auth Url in your controller with an HTML Link on the view (you will click this to initiate an auth request)\r\n```\r\n        public async Task<ActionResult> Index()\r\n        {\r\n            ViewBag.AuthUrl = \"http://localhost:44302/service/connect/authorize?client_id=client&response_type=code+id_token+token&scope=openid+profile+read+write+offline_access&redirect_uri=http%3A%2F%2Flocalhost%3A2003%2Fcallback&nonce=blah\";\r\n            return View();\r\n        }\r\n\r\n        [Authorize]\r\n        public async Task<ActionResult> Callback()\r\n        {\r\n            return View();\r\n        }\r\n```\r\n - Now put this override method in you Controller\r\n\r\n```\r\n        protected override void OnAuthentication(System.Web.Mvc.Filters.AuthenticationContext filterContext)\r\n        {\r\n            base.OnAuthentication(filterContext);\r\n        }\r\n```\r\n\r\nOK, now, normally what happens when you navigate to a page requiring authorization, the middleware intercepts and sends you off to to authenticate, upon return, it signs you in (and if you have a breakpoint in AuthorizationCodeReceived, you will see this happen).\r\n\r\nHowever, you might also want to **create your own request**, as seen here in **Index()**.  When you CLICK that link, it takes you to authenticate, and upon return, you are actually returning to a page requiring authorization - in this example, **Callback()**.  By requesting this secure page, OpenIDConnect knows to apply the code/token it got from the authentication server.\r\n\r\n**Repro:**\r\n - Make sure you pointed to a valid OpenID authority, configured client as **hybrid**, with **redirects**, etc.\r\n - Put a **breakpoint** in **AuthorizationCodeReceived** and the **Callback()** action \r\n - Run the project and click the link and sign in.  you should see it hit both breakpoints upon your return, (user is authenticated or Callback would not be called)\r\n - Navigate to Index again, **clear cookies** (sign out)\r\n - Now add a **breakpoint** in your **OnAuthentication()** method.\r\n - Click the link and sign in again\r\n - Notice that NO breakpoints are hit!  **OpenIDConnect is skipped**, and user is not authorized to hit Callback()\r\n\r\n**Simply adding or removing the breakpoint in OnAuthentication() results in catastrophic failure of OpenIDConnect.**\r\n\r\n**Why?**  \r\n\r\nMaybe it seems like no big deal, but how in the world is the debugger affecting critical execution of OpenIDConnect, and how am I to feel confident about this in production? What else might affect execution here?\r\n\r\n "},"comment":{"url":"https://api.github.com/repos/aspnet/Security/issues/comments/152348555","html_url":"https://github.com/aspnet/Security/issues/554#issuecomment-152348555","issue_url":"https://api.github.com/repos/aspnet/Security/issues/554","id":152348555,"user":{"login":"Tratcher","id":1821173,"avatar_url":"https://avatars.githubusercontent.com/u/1821173?v=3","gravatar_id":"","url":"https://api.github.com/users/Tratcher","html_url":"https://github.com/Tratcher","followers_url":"https://api.github.com/users/Tratcher/followers","following_url":"https://api.github.com/users/Tratcher/following{/other_user}","gists_url":"https://api.github.com/users/Tratcher/gists{/gist_id}","starred_url":"https://api.github.com/users/Tratcher/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Tratcher/subscriptions","organizations_url":"https://api.github.com/users/Tratcher/orgs","repos_url":"https://api.github.com/users/Tratcher/repos","events_url":"https://api.github.com/users/Tratcher/events{/privacy}","received_events_url":"https://api.github.com/users/Tratcher/received_events","type":"User","site_admin":false},"created_at":"2015-10-29T22:44:45Z","updated_at":"2015-10-29T22:44:45Z","body":"It would help if you pushed your repro project to a github repo."}}