获取没有非标准端口的原始 url (C#)

发布于 2024-12-08 14:58:27 字数 1776 浏览 0 评论 0原文

第一个问题!


环境

MVC、C#、AppHarbor。

问题

我正在调用 openid 提供商,并根据域生成绝对回调 URL。

在我的本地计算机上,如果我点击 http://localhost:12345/login ,效果很好。

Request.Url; //gives me `http://localhost:12345/callback`

但是,在我部署的 AppHarbor 上,因为它们使用非标准端口,即使我'我点击“http://sub.example.com/login

Request.Url; //gives me http://sub.example.com:15232/callback

,这搞砸了我的回调,因为端口号不在原始来源网址!

我尝试过

  • Request.Url
  • Request.Url.OriginalString
  • Request.RawUrl

All 给了我“http://sub .example.com:15232/callback”。

另外为了澄清这不是领域问题,我从 DotNetOpenAuth 收到的错误消息是

'http://sub.example.com:14107/accounts/openidcallback' not under realm 'http://*.example.com/'. 

我认为我没有把它填满?

现在,我要考虑一些 hacky 的东西,比如

  • 预处理器命令 (#IF DEBUG THEN PUT PORT)
  • 字符串替换 (Request.URL.Contains("localhost"))

所有这些都不是 100% 的解决方案,但我生病了仔细思考我所缺少的一个简单的属性。我还读过 this 但这似乎没有公认的答案(更多的是关于路径而不是权威)。所以我把它送给你们。

摘要

因此,如果我有 http://localhost:12345/login,我需要从 http://localhost:12345/callback 获取请求上下文。

如果我有“http://sub.example.com/login”,我应该得到“ http://sub.example.com/callback",无论它位于哪个端口。

谢谢! (睡觉时间,早上会回答任何问题)

First question!


Environment

MVC, C#, AppHarbor.

Problem

I am calling an openid provider, and generating an absolute callback url based on the domain.

On my local machine, this works fine if I hit http://localhost:12345/login

Request.Url; //gives me `http://localhost:12345/callback`

However, on AppHarbor where I'm deploying, because they are using non-standard ports, even if I'm hitting it at "http://sub.example.com/login"

Request.Url; //gives me http://sub.example.com:15232/callback

And this screws up my callback, because the port number wasn't in the original source url!

I've tried

  • Request.Url
  • Request.Url.OriginalString
  • Request.RawUrl

All gives me "http://sub.example.com:15232/callback".

Also to clear up that this isn't a Realm issue, the error message I am getting from DotNetOpenAuth is

'http://sub.example.com:14107/accounts/openidcallback' not under realm 'http://*.example.com/'. 

I don't think I've stuffed that up?

Now, I'm about to consider some hacky stuff like

  • preprocessor commands (#IF DEBUG THEN PUT PORT)
  • string replace (Request.URL.Contains("localhost"))

All of these are not 100% solutions, but I'm sick of mulling over what could be a simple property that I am missing. I have also read this but that doesn't seem to have an accepted answer (and is more about the path rather than the authority). So I'm putting it towards you guys.

Summary

So if I had http://localhost:12345/login, I need to get http://localhost:12345/callback from the Request context.

And if I had "http://sub.example.com/login", I should get "http://sub.example.com/callback", regardless of what port it is on.

Thanks! (Sleep time, will answer any questions in the morning)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

陌伤浅笑 2024-12-15 14:58:27

这是 AppHarbor 等负载平衡设置中的常见问题 - 我们提供了 解决方法示例

更新:对于许多 ASP.NET 应用程序来说,更理想的解决方案可能是将 aspnet:UseHostHeaderForRequestUrl appSetting 设置为 true。我们 (AppHarbor) 发现一些客户在其 WCF 应用程序中使用它时遇到了问题,这就是为什么我们没有默认启用它,但仍然建议针对这些情况使用上述解决方案。您可以使用 AppHarbor 的“配置变量”对其进行配置,以在部署时注入应用程序设置。有关详细信息,请参阅本文

This is a common problem in load balanced setups like AppHarbor's - we've provided an example workaround.

Update: A more desirable solution for many ASP.NET applications may be to set the aspnet:UseHostHeaderForRequestUrl appSetting to true. We (AppHarbor) have seen several customers experience issues using it with their WCF apps, which is why we haven't enabled it by default and stil recommend the above solution for those situations. You can configure it using AppHarbor's "Configuration Variables" to inject the appsettings when deployed. More information can be found in this article.

葬﹪忆之殇 2024-12-15 14:58:27

我最近遇到了一个问题,我将 URL 与当前 URL 进行比较,然后基于此突出显示导航。它在本地有效,但在生产中无效。

我将 http://example.com/path/to/file.aspx 作为我的文件,但是当查看该文件并运行 Request.Url.ToString() 时,它在负载平衡的生产环境中生成了 https://example.com:81/path/to/file.aspx

现在,我使用 Request.Url.AbsolutePath 只提供 /path/to/file.aspx,从而忽略架构、主机名和端口号。

当我需要将其与我使用的每个导航项上的 URL 进行比较时:
新 Uri(theLink.Href).AbsolutePath

I recently ran into an issue where I compared a URL to the current URL, and then highlighted navigation based on that. It worked locally, but not in production.

I had http://example.com/path/to/file.aspx as my file, but when viewing that file and running Request.Url.ToString() it produced https://example.com:81/path/to/file.aspx in a load balanced production environment.

Now I am using Request.Url.AbsolutePath to just give me /path/to/file.aspx, thus ignoring the schema, hostname, and port numbers.

When I need to compare it to the URL on each navigation item I used:
New Uri(theLink.Href).AbsolutePath

傲娇萝莉攻 2024-12-15 14:58:27

如果您在框架中使用 UrlBuilder 类,您可以轻松解决这个问题。在构建器类上,如果将端口设置为 -1,则端口号将被删除:

new UriBuilder("http://sub.example.com:15232/callback"){ Port = -1}

returns : http://sub .example.com/callback

要将端口号保留在本地计算机上,只需检查 Request.IsLocal 并且不要对端口应用 -1。

我会将其包装到扩展方法中以保持干净。

If you use the UrlBuilder class in the framework you can easly get around this. On the builder class if you set the port to -1 then the port number will be removed:

new UriBuilder("http://sub.example.com:15232/callback"){ Port = -1}

returns : http://sub.example.com/callback

To keep the port number on a local machine just check Request.IsLocal and don't apply -1 to the port.

I would wrap this into a extension method to keep it clean.

演出会有结束 2024-12-15 14:58:27

我最初的想法是获取引用变量并检查它是否包含端口,如果包含则使用它,否则不要使用。

如果这不是一个选项,因为代理可能会删除引用标头变量,那么您可能需要使用一些客户端脚本来获取位置并将其传递回服务器。

我猜测 AppHarbor 使用端口转发到 IIS 服务器,因此即使该站点公开位于端口 80 上,IIS 也将其托管在另一个端口上,因此它无法知道客户端连接的端口。

My initial thoughts are get the referrer variable and check if that includes a port, if so use it otherwise don't.

If that’s not an option because a proxy might remove the referrer header variable then you might need to use some client side script to get the location and pass it back to the server.

I'm guessing that AppHarbor use port forwarding to the IIS server so even though publicly the site is on port 80 IIS has it hosted on another port so it can't know what port the client connected on.

梦过后 2024-12-15 14:58:27

像这样的东西

String port = Request.ServerVariables["SERVER_PORT"] == "80" ? "" : ":" + Request.ServerVariables["SERVER_PORT"];
String virtualRoot = Url.Content("~/");
destinationUrl = String.Format("http://{0}{1}{2}", Request.ServerVariables["SERVER_NAME"], port + virtualRoot, "/callback");

Something like

String port = Request.ServerVariables["SERVER_PORT"] == "80" ? "" : ":" + Request.ServerVariables["SERVER_PORT"];
String virtualRoot = Url.Content("~/");
destinationUrl = String.Format("http://{0}{1}{2}", Request.ServerVariables["SERVER_NAME"], port + virtualRoot, "/callback");
岁月无声 2024-12-15 14:58:27

我看到这是一个旧线程。我在 IIS 7.5 上运行 MVC5 时遇到了这个问题,前面有一个 Apache 代理。在服务器之外,我会得到“空响应”,因为 asp.net 应用程序使用自定义端口从 apache 获取 Url。

为了让应用程序重定向到子路径而不包含“自定义”端口,请忘记 Response/Request 对象,并使用 Transfer 方法。例如,如果我希望用户在尚未登录的情况下自动重定向到登录页面:

if (!User.Identity.IsAuthenticated)   
    Server.TransferRequest("Account/Login");

I see that this is an old thread. I had this issue running MVC5, on IIS 7.5, with an Apache proxy in front. Outside of the server, I would get "Empty Response", since the asp.net app gets the Url from apache with the custom port.

In order to have the app redirect to a subpath without including the "custom" port, forget the Response/Request objects, and use the Transfer method. For instance, if I want that users are automatically redirected to the login page in case they are not logged already:

if (!User.Identity.IsAuthenticated)   
    Server.TransferRequest("Account/Login");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文