2

Let's say we have a controller like this:

public class HomeController : Controller
{
    [HttpGet]
    public IActionResult Foo(string token)
    {
        return RedirectToAction(nameof(Index));
    }
}

When I type the following URL address in the webbrowser:

https://localhost:44348/home/foo#dsfdsf

I would like to be able to read the dsfdsf after the hash symbol and bind it to the token variable. Now I'm receiving null value. I'm getting such URL from the 3rd party app and I need to consume the response somehow and read the data from the query string.

I played with [FromQuery] attribute but I haven't managed it to work so far. Any ideas? Cheers

GoldenAge
  • 2,918
  • 5
  • 25
  • 63
  • Try to read information in the request. For example, you might use `this.Request.RawUrl` inside your Foo method – Roganik Jan 17 '19 at 10:03
  • 4
    Unfortunationaly the `#`(*hashed*) values cannot be retrieved on the `server-side` but you can use `javascript` to send it separately or you can send it via `query string` like: `https://localhost:44348/home/foo?token=dsfdsf`. – vikscool Jan 17 '19 at 10:08
  • 1
    #Roganik If you are thinking about `HttpContext.Request` i already did that and i didn't find anything – GoldenAge Jan 17 '19 at 10:11
  • #vikscool Good to know that. I know what to do now. If you add an answer to my question I can accept it. Ta – GoldenAge Jan 17 '19 at 11:40
  • Hey Guys I have the same question as OP and it seems like @vikscool s answer was satisfactory. Could someone explain what he is talking about? I am most confused about using the word "send" when the question was about reading the values. I know how to set the values with window.location.hash. But again, as OPs question states: how does one read these values when you paste a URL into the browser and press enter? Any guidance/advice appreciated and thanks again to all – Sam Evers May 25 '20 at 17:41
  • @SamEvers sorry for the confusion as of why I pointed that out can be rad at [How can I get the hash of an URL?](https://stackoverflow.com/a/26117474/2417602). So, as a workaround, I suggested a query string(`?field=value`). – vikscool Jun 01 '20 at 03:50

1 Answers1

1

I have a work around for you, but first of all lets get more into the problem.

The strings after the hash symbol which are called Fragment values are not query parameters but they are strings to be read by the client-side (living in the browser) and the server cannot read them because they are not sent to the server by the browser.

Some authentication providers like Google and Azure send the access token as Fragment value for security reasons so that they are not transferred over the internet after they get sent as direct response from the authentication provider.

The only way you can come around that is to use javascript to convert the fragment values to query parameters by replacing the '#' with '?' and redirecting to the endpoint in your server controller.

I suppose the easiest way is to handle all that from server, meaning you get get the request in server, send a javascript code to the browser on the fly, that replaces the '#' into '?' and redirects to your second endpoint which reads the token as strong parameter.

Here how you can do it in ASP.NET Core 3.1:

[AllowAnonymous]
[HttpGet("authredirect")]
[Produces("text/html")]
public virtual ContentResult ConvertUrlFragmentToQueryParamThenRedirect()
{
  return Content("<html><script>window.location.href=window.location.href.replace('#', '?').replace('authredirect', 'authparams')</script></html>", "text/html");
}

[AllowAnonymous]
[HttpGet("authparams")]
public virtual void GetAccessToken([FromQuery] string access_token)
{
  // now you have your access token server side here
}

Please remember to set your redirectUrl to the correct one, in this case 'YOUR REDIRECT URL/authredirect'.

YazanGhafir
  • 464
  • 3
  • 8