Apache 2.2 重定向到 SSL *然后* 进行身份验证(解决方案 < 但这是废话吗?)

发布于 2024-11-17 03:51:07 字数 1255 浏览 4 评论 0 原文

似乎是 apache 的地方,所以这里是:)

老问题:如何重定向 HTTP->HTTPS,然后且仅当 HTTPS 时,才进行身份验证?

哦 - 我希望其中的大部分内容都在一个片段中,可以包含在多个 中或<位置>块,因此没有基于虚拟主机级别随机路径的重写...

好吧,这就是我所拥有的似乎确实有效的方法:

在 VirtualHost 块的顶部

# Set ssl_off environment variable 
RewriteEngine on
RewriteCond %{HTTPS} =on
RewriteRule ^ - [E=ssl]

在位置或目录块中< /strong>

RewriteEngine on
# Case 1 redirect port 80 SSL
RewriteCond %{HTTPS} !=on
RewriteCond %{SERVER_PORT} =80
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [R=301]

AuthType Basic
AuthBasicProvider external
AuthExternal auth_pam
AuthName "My Underpants"
AuthzUnixgroup on
Order Deny,Allow
Deny from all
Allow from env=!ssl
Satisfy any
Require group nice-users

优点

所有这些要求都可以抽象为一个片段文件,以包含在每个位置的一行中

它修复了对每个位置强制使用 SSL 和身份验证的问题,因此减少了出错的机会

<血腥

​天哪,这太不直观了!据我所知可能很脆弱......

有更好的方法(不是我发现的......)?

非常欢迎评论是否有任何严重缺陷:)

旁白 生活会变得容易得多

如果 Apache 有一个合理的配置语法和通用的 , 。

可以在任何地方使用的块。它有某些特殊情况块,例如 IfModule,然后还有特殊情况条件,例如 RewriteCond(如果您不习惯的话,很难理解)。

干杯,

蒂姆

Seems to be the place for apache so here goes :)

Age old problem: how so I redirect HTTP->HTTPS, then and only if HTTPS, do an auth?

Oh - and I'd like most of it in a single snippet that can be Include-ed in multiple <directory> or <location> blocks, so no virtual host level random path based rewrites...

Well, here's what I have that does seem to work:

In the top of a VirtualHost block

# Set ssl_off environment variable 
RewriteEngine on
RewriteCond %{HTTPS} =on
RewriteRule ^ - [E=ssl]

In the location or directory block

RewriteEngine on
# Case 1 redirect port 80 SSL
RewriteCond %{HTTPS} !=on
RewriteCond %{SERVER_PORT} =80
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [R=301]

AuthType Basic
AuthBasicProvider external
AuthExternal auth_pam
AuthName "My Underpants"
AuthzUnixgroup on
Order Deny,Allow
Deny from all
Allow from env=!ssl
Satisfy any
Require group nice-users

Pluses

All of that bar the Require's can be abstracted out to a snippet file to Include in one line on each location

It fixes forcing SSL and authentication together for each location, so less chance of mistakes

Minuses

Bloody hell, it is hardly intuitive! Might be fragile for all I know...

Is there a better way (not that I've found...)?

Comments would be very welcome on whether that has any serious flaws :)

Aside
Life would be so much easier if Apache had a sensible config syntax with a generic

<If expression> </If>

block that could be used anywhere. It has certain special case blocks such as IfModule, and then you have special case conditionals like RewriteCond (which is very hard to grok if you're not used to it).

Cheers,

Tim

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

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

发布评论

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

评论(3

祁梦 2024-11-24 03:51:07

如果您想强制整个网站使用 https,您可以使用 VirtualHost 指令,然后就非常简单了:

<VirtualHost *:80>
    ServerName example.com

    RedirectMatch (.*) https://example.com$1

</VirtualHost>

<VirtualHost *:443>
    ServerName example.com

    ...
    ...
    ...
</VirtualHost>

If you're wanting to force the entire site to https, you can use the VirtualHost directives, and then it's quite simple:

<VirtualHost *:80>
    ServerName example.com

    RedirectMatch (.*) https://example.com$1

</VirtualHost>

<VirtualHost *:443>
    ServerName example.com

    ...
    ...
    ...
</VirtualHost>
好多鱼好多余 2024-11-24 03:51:07

蒂姆·瓦茨的解决方案似乎最适合我,但需要一些调整。另外,我的情况略有不同,因为我希望允许某些 IP 地址无需 HTTP 身份验证,但这只是添加了额外的一行。

默认情况下,mod_rewrite 不会从 VirtualHost 继承配置。

请参阅:http://httpd.apache.org/docs/2.2/mod /mod_rewrite.html#rewriteoptions

我打算使用“RewriteOptions继承”,但似乎这在子规则之后应用父规则。无论如何,我想到了一个不同的解决方案。

在我的 SSL 中我有一行:

SetEnvIf Request_URI "/" using_ssl=yes

如果请求 URI 包含正斜杠(即始终),则设置 using_ssl 环境变量。这有点黑客,因为我更喜欢使用无条件 SetEnv 但显然:

此指令设置的内部环境变量是在大多数早期请求处理指令运行后设置的,例如访问控制和 URI 到文件名映射。如果您设置的环境变量是作为处理早期阶段的输入(例如 RewriteRule 指令),则您应该使用 SetEnvIf 设置环境变量。

(来源:http://httpd.apache.org/docs/2.2/ mod/mod_env.html#setenv

我的容器中的配置如下所示:

# Require a basic HTTP auth user
AuthName "realm-name-goes-here"
AuthType Basic
AuthUserFile /var/www/etc/htpasswd
Require valid-user

# OR allow from non-SSL (which will be redirected due to mod_rewrite below!)
Order Allow,Deny
Allow from env=!using_ssl

# OR allow from a trusted IP range
# NB: This allows certain IPs without a username & password
Allow from 192.168.0.0/16

Satisfy Any

# Force a redirect to HTTPS
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=permanent]

出于测试目的,您可能想首先尝试仅使用“R”而不是“R=permanent”。

希望这对其他人有用:)

Tim Watts' solution seems to work best for me but needed a bit of tweaking. Also my situation is slightly different in that I wish to allow certain IP addresses without HTTP auth but this just adds an extra line.

mod_rewrite won't inherit config from the VirtualHost by default.

See: http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriteoptions

I was going to make use of "RewriteOptions inherit" but it seems that this applies the parent rules AFTER the child ones. In any case, I thought of a different solution.

Within my SSL <VirtualHost> I have the line:

SetEnvIf Request_URI "/" using_ssl=yes

This sets the using_ssl environment variable if the request URI contains a forward slash (i.e. all the time.) It's a bit of hack as I'd prefer to use the unconditional SetEnv but apparently:

The internal environment variables set by this directive are set after most early request processing directives are run, such as access control and URI-to-filename mapping. If the environment variable you're setting is meant as input into this early phase of processing such as the RewriteRule directive, you should instead set the environment variable with SetEnvIf.

(source: http://httpd.apache.org/docs/2.2/mod/mod_env.html#setenv)

My config within my container looks like this:

# Require a basic HTTP auth user
AuthName "realm-name-goes-here"
AuthType Basic
AuthUserFile /var/www/etc/htpasswd
Require valid-user

# OR allow from non-SSL (which will be redirected due to mod_rewrite below!)
Order Allow,Deny
Allow from env=!using_ssl

# OR allow from a trusted IP range
# NB: This allows certain IPs without a username & password
Allow from 192.168.0.0/16

Satisfy Any

# Force a redirect to HTTPS
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=permanent]

You probably want to try with just 'R' instead of 'R=permanent' first for testing purposes.

Hope this is useful for others :)

抱猫软卧 2024-11-24 03:51:07

我已经测试了你的解决方案,但它不起作用......

经过很长一段时间搜索解决方案,谷歌搜索太多,发现总是相同的东西不起作用,我终于这样做了:我使用 SSLRequireSSL< /code> 和一个 ErrorDocument 403 配置了包含 JavaScript 代码的静态页面(感谢 此博客页面)。

/etc/apache2/conf.d.opt/redirect_if_not_https.conf 中:(

SSLRequireSSL
ErrorDocument 403 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\
<html><head>\
<title>403 Forbidden</title>\
<script language=\"JavaScript\">\
window.location='https://'+window.location.hostname+window.location.pathname;\
</script>\
</head><body>\
<h1>Forbidden</h1>\
<p>You don't have permission to access that resource using simple HTTP. Please use HTTPS instead.</p>\
</body></html>"

请注意,我创建了 /etc/apache2/conf.d.opt/

在 appconf,包含该文件(例如在 /etc/apache2/conf.d/trac.conf 中):

<LocationMatch "/trac">
    # All the classical configurations here
    # ...

    Include conf.d.opt/redirect_if_not_https.conf
</LocationMatch>

I've tested your solution and it didn't work ...

After a loooong time searching the solution, googling too much and found always the same things which didn't work, I finally did this : I use SSLRequireSSL and an ErrorDocument 403 configured with a static page containing a JavaScript code (thanks to this blog page).

in /etc/apache2/conf.d.opt/redirect_if_not_https.conf :

SSLRequireSSL
ErrorDocument 403 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\
<html><head>\
<title>403 Forbidden</title>\
<script language=\"JavaScript\">\
window.location='https://'+window.location.hostname+window.location.pathname;\
</script>\
</head><body>\
<h1>Forbidden</h1>\
<p>You don't have permission to access that resource using simple HTTP. Please use HTTPS instead.</p>\
</body></html>"

(note that I created /etc/apache2/conf.d.opt/)

And in an app conf, include that file (for example in /etc/apache2/conf.d/trac.conf) :

<LocationMatch "/trac">
    # All the classical configurations here
    # ...

    Include conf.d.opt/redirect_if_not_https.conf
</LocationMatch>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文