OpenID Redirect URI adds a # symbol - asp.net

I have configured an OpenID Connection application on OneLogin (not sure the provider matters) with a configured post MFA authentication redirect uri of
http://localhost:4200/LoginResponse.aspx?
The code behind my LoginResponse.aspx page grabs the returned id_token and processes it.
The issue is that after my initial redirect to the MFA login and successful login/MFA validation, the redirect is coming to
http://localhost:4200/LoginResponse.aspx#id_token=12345678987...........
Note the "#" symbol after my .aspx extension. This is corrupting the parameter string that is returned and not allowing me to grab the value of id_token from the Response.
After the redirect comes back, if I simply manually replace the "#" with a "?" and hit enter, my LoginResponse.aspx page loads fine and finds the id_token and processes it with my business logic.
My question is, how can I get the redirect to actually return to "LoginResponse.aspx?" so that I can grab the parameters.
On my OpenID Application I have tried the following options as Redirect URIs
LoginResponse
LoginResponse.aspx
LoginResponse.aspx?
LoginResponse.aspx?action=test
Did that last one to see if I could get around the ? not being there. But that just redirected the page to "LoginResponse.aspx?action=test#id_token=..............." So again, I could not grab the "id_token" variable out of the URL Response/QueryString.
I just cannot figure out how to get rid of this unwanted "#" sign and have a "?" after my .aspx extension.
Any help would be greatly appreciated!

I assume you are using the implicit flow to retrieve the tokens and in this flow you can either get back the tokens in the URL with the #. The # is added to make sure the tokens are not sent back to the server, instead they just stay in the browser. If it was a #, then the secret tokens would be sent back to the server and end up in various logs and creating various security issues.
I don't know how you implemented the client, but in OpenID Connect, if you add this parameter "&response_mode=form_post" to the initial authorization request, then you will get back the token using a POST request instead. just like this picture shows:
PS, I doubt you can get back the tokens using a ? instead of #.

Related

Asp.net - prevent parameters replication during redirection to login page

Asp.net, when it sees an unauthenticated request, typically send the request to the login page.
An example is below:
http://localhost:9001/?a=x&b=y&c=z
Request to the login page:
http://localhost:9001/Account/Login.aspx?ReturnUrl=%2f%3fa%3dx%26b%3dy%26c%3dz&a=x&b=y&c=z
Notice how Asp.net creates a new parameter ReturnUrl but still retains the original parameters while redirecting to the login page.
I have a situation where the initial url length is around 1000+ characters and after this redirection, it becomes 2000+ which is kind of going beyond some browser limits.
Is there a quick way (configuration/httpmodule etc) to prevent the automatic parameters forwarding to the login page? (I can manage the login page needing these parameters to be extracted from ReturnUrl.)
For anyone who is wondering about this issue, the issue happens even in a default asp.net application but I was able to implement a fix for it.
Following is the fix:
Implement an HttpModule; handle the EndRequest event and check for 302/unauthenticated request
We have to use Response.RedirectLocation for most steps below
Using HttpUtility.ParseQueryString, get collection of all parameters
Using HttpUtility.ParseQueryString, get collection of all parameters within ReturnUrl value
Except ReturnUrl, strip out all other parameters which exist in ReturnUrl value
Update Response.RedirectLocation with ReturnUrl and remaining parameters (none in most cases), Url encoding as necessary
This will ensure the Url now has only ReturnUrl and other parameters which aren't copied in ReturnUrl.
You need to ensure that the login page (Account/Login in above e.g.) does not use any of these parameters or if they do, you have code to pull those out from value of ReturnUrl.
Hope this solution helps anyone with similar situation.

HTTP Header Request

I have looked through many sites but I have yet to find the answer to this question:
I have a login page and after the user logs in I want to redirect to a completely different URL. But while redirecting it I want to pass the username with the http request. So for example:
request.setHeader(“test”,“testing.request) and then from the server side they can retrieve the header by request.getHeader(“test”).
I assume that with "redirect" you mean doing response.sendRedirect(newURL);. That means, that your login servlet, after a successful login, tells the browser, that it should send new request. The new request uses GET method, so the only way to add parameters is to add them directly to the new URL, e.g. response.sendRedirect("http://your.server/new/location?username=johndoe");.
If you want to use and modify the original request, I would suggest you to read http://www.javapractices.com/topic/TopicAction.do?Id=181 (Forward versus redirect).

Spring Security # in URL

I'm currently using a Preauthentication with Spring Security through an SSO solution, and was having a problem with #'s in the URL. I noticed if you URL encode the #, the redirect would work correctly if the user was not logged in, so I wrote a filter that would look for URL encoded parameters, and decode them. The problem is, now if you are logged in, it seems like the URL is being decoded, and my filter is never being touched.
This is a really confusing question, but I'll try to explain what I am seeing through how the requests are handled.
Not Logged In:
/%23/some/resource
Redirect to SSO:
SSO Redirects to:
/#/some/resource
This works well.
Logged In:
/%23/some/resource
:
/#/some/resource is the URI passed, so no rewrite needed, verified through debug logging that the URL is being passed through.
/%23/some/resource is returned to browser, 404 is returned.
Where I am getting confused is why it's decoding, then it seems to be re-encoding the URL after the filter-chain (maybe?)
Thanks for any help!

URL redirected to provides GET parameters with # (and not ?)

According to the Dropbox API documentation, a GET to https://www.dropbox.com/1/oauth2/authorize will render the Dropbox authentication website, and upon authenticating will redirect the client to the specified redirect URI with the access token as a GET parameter. However, the URL redirected to provides its GET parameters with # (and not ?).
For example, if I do https://www.dropbox.com/1/oauth2/authorize?response_type=token&client_id=foo&redirect_uri=https://www.httpsnow.org/, I will get https://www.httpsnow.org/#access_token=foo&token_type=bearer&uid=bar (note the presence of the # symbol and the lack of a ? symbol at the start of the query string).
Any ideas?
You're using the OAuth 2 "token flow" (response_type=token). The token flow is designed mostly for mobile and JavaScript-based apps. As the documentation says:
Token flow
These parameters are passed in the URL fragment (after the # in the
URL):
It sounds like you want to use the "code flow" instead (response_type=code):
Code flow
These parameters are passed in the query string (after the ? in the
URL):

How to know if the current Servlet request is the result of a redirect?

Is there a way to know if the request has been redirected or forwarded in the doGet method of a Servlet?
In my application, when a user (whose session has timed out) clicks on a file download link, they're shown the login page, which is good. When they login, they are immediately sent the file they requested, without updating the page they see, which is bad. Basically, they get stuck on the login screen (a refresh is required).
What I want to do is interrupt this and simply redirect to the page with the link, when a file is requested as a result of a redirect.
Perhaps there are better ways to solve this?
The redirect happens client-side. The browser is instructed by the previous request to send a new request, so to the server it does not make a difference. The Referer header might contain some useful information, but it's not certain.
When redirecting you can append some parameter, like ?targetPage=dowloadpage and then check if the parameter exists. You may have to put this in a hidden field on the login page if you want it to be transferred through multiple pages.
If you're using container managed authentication, then I don't believe you can detect this since the server will only involve your resource once authentication has been completed successfully.
If you're managing authentication differently, please explain.

Resources