We have a OWIN Web Api 2 site that needs both OAuth2 security and also Windows Integrated Security.
The problem is that when access tokens are expired. Owin returns a 401 unauthorized response. This causes the browser to popup a login box.
That's because there are XXX-Authenticate headers with Negotiate and NTLM values. Also one with Bearer
But if we disable Windows Integrated Security in IIS, then it doesn't have those headers but only has XXX-Authenticate: Bearer and so it the browser does not popup a login window.
On the client side, we want to catch the error code when the token is expired and then refresh the access token. This actually works except for the browser's ugly popup box asking for id and password.
But we must have both mixed authentication types for this application.
The solution seems to be to send back a different http status code for expired tokens so that the browser won't pop up the login box and we can still catch that code in the client.
However, I'm not having any success figuring how to do this with OWIN.
I registered a middle wear method at the top of the stack to look at
and modify the response code but when the token is expired it seems
to return 200 from OWIN but somehow gets changed to 401 when sent
to the client.
How can I change the status code returned only for expired tokens?
Related
I am trying to get a token stored in a cookie using Webview2. The login server has a complex process with many redirects, with DevTools from Edge I am able to see when my token (idToken) is received:
The problem is that I am not able to see all the requests in the code and therefore the request with the token.
I have tried using:
CoreWebView2.NavigationCompleted
CoreWebView2.SourceChanged
CoreWebView2.FrameNavigationCompleted
CoreWebView2.WebResourceResponseReceived
But none of them show all the redirects and requests of the authentication process. Can someone explain me how to see all the requests the browser goes through?
Backstory
Due to limitations on what Swagger supports and what my system needs, I find myself needing to get an access token without the assistance of my actual application. I am trying to do it in an IOperationFilter.
Question Details
The steps, as I see them, are:
Make a call to the IDP with the Callback URL (and PKCE Code Challenge).
The Browser is redirected to the IDP's login page and the user logs in.
The Browser is redirected to the callback url with the Auth Code in the URL.
Make a call to the IDP with the Auth Code and PKCE Code Verifier to get the Access Token.
I can get the URL needed to call the IDP (with the PKCE Code Challenge). But I am unsure how to make the redirect to IDP login happen or catch the Callback URL to get the Auth Code Out. I tried HttpContextAccessor.HttpContext.Response.Redirect but it had no effect.
I am also not sure how to grab the call with the AuthCode in it. I could startup my own host using Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults, but it seems like I should not need to host a separate service inside my existing service.
Question
How from code run when the page is initially loaded, how can I redirect the browser to the IDP, and then catch the redirect from there to the page with the Auth Code in the URL?
Using Hybrid flow and back-channel logout, and trying to single sign out multiple user sessions when the user signs out of one session.
If I use the same browser, then I have no problem SSO the user, one client redirects to IDSRV4 logout page, and IDSRV4 invalidates the session, sends a back channel logout request to the client and the session cookie "idsrv.session" is deleted from the browser. Client 2 then makes a request and notices that there is no authentication cookie and redirects to IDSRV4 for login.
When I open Client 1 and Client 2 in different browsers, Single Sign On fails to work, and the user must enter credentials in each browser (expected, since the browsers do not share cookies).
However, I would like to still be able to invalidate all sessions of the user when they log out of IDSRV4, and send back channel logout requests to each client
I have tried implementing the LogoutSessionManager/CookieEventHandler in each client (that's how the back-channel is working in the same browser). However, IDSRV4 never sends the Logout request to the second client, only the one that initiated the log out request. But since the logout request deletes the "idsrv.session" cookie, then the other client is effectively "logged out."
I have thought about implementing a state server as described in this SO IDSRV4 question, but have not yet started because the terminology of "lazy-signout" and triggering a challenge is new to me and I haven't researched them enough quite yet.
Any and all help, or ideas are appreciated. Thanks
I have an application that makes multiple requests to an API to render parts of the page.
When the user's access token expires the first request sends the refresh token, gets the new access token and updates the cookie storing it, but as the requests are async, sometimes before updating the cookie the other requests send the old, now invalid token, so the API returns 401 Unauthorized.
How should I handle this? Is there a way to make the other requests wait for the access token to refresh?
I have an problem in the application I am currently working that is using Windows Authentication.
I have MVC Controller and ApiController both with custom AuthorizeAttribute applied. When the Mvc.Authorization failed in MVC I can redirect it to an error page but for Http.Authorization I can only return IsAuthorized to true or false and it displays a modal dialog box same with the login modal for Windows Authentication when the user is not authorized. I can't search for the right explanation why it happens. Can I customize it? Both of them return 401 status but why do they have different behavior?
What you have mentioned is intended behavior.
Asp.NET MVC generally serves web pages to browser clients, thus in case of unauthorized access to any resource you redirect user from server itself to some another page (view) where you can show an error/message to user. So your response is redirection to another page and not unauthorized 401 status code.
But ASP.NET WebAPI is a service which should be consumed by other apps and their output is generally data rather then a particular view. So when an unauthorized access is identified, web API responds back with status code 401. (which is an intended behavior).
Now if you are trying to access web api through your browser and it receives an unauthorized response from server, it shows user a popup to give user a chance to provide credentials and hit api once again along with credentials.