Commit | Line | Data |
1763fe29 |
1 | package Catalyst::Plugin::RequireSSL; |
2 | |
3 | use strict; |
4 | use base qw/Class::Accessor::Fast/; |
5 | use NEXT; |
6 | |
eeefd598 |
7 | our $VERSION = '0.03'; |
1763fe29 |
8 | |
eeefd598 |
9 | __PACKAGE__->mk_accessors('_require_ssl'); |
10 | |
11 | sub require_ssl { |
12 | my $c = shift; |
13 | |
14 | $c->_require_ssl(1); |
15 | |
16 | if ( !$c->req->secure && $c->req->method ne "POST" ) { |
17 | my $redir = $c->_redirect_uri('https'); |
18 | if ( $c->config->{require_ssl}->{disabled} ) { |
19 | $c->log->warn( "RequireSSL: Would have redirected to $redir" ); |
20 | } |
21 | else { |
22 | $c->res->redirect( $redir ); |
23 | } |
24 | } |
25 | } |
26 | |
27 | sub finalize { |
28 | my $c = shift; |
29 | |
30 | # Do not redirect static files (only works with Static::Simple) |
31 | if ( $c->isa( "Catalyst::Plugin::Static::Simple" ) ) { |
32 | return $c->NEXT::finalize(@_) if $c->_static_file; |
33 | } |
34 | |
35 | # redirect back to non-SSL mode |
36 | REDIRECT: |
37 | { |
38 | # No redirect if: |
39 | # we're not in SSL mode |
40 | last REDIRECT if !$c->req->secure; |
41 | # it's a POST request |
42 | last REDIRECT if $c->req->method eq "POST"; |
43 | # we're already required to be in SSL for this request |
44 | last REDIRECT if $c->_require_ssl; |
45 | # or the user doesn't want us to redirect |
46 | last REDIRECT if $c->config->{require_ssl}->{remain_in_ssl}; |
47 | |
48 | $c->res->redirect( $c->_redirect_uri('http') ); |
49 | } |
50 | |
51 | return $c->NEXT::finalize(@_); |
52 | } |
53 | |
54 | sub setup { |
55 | my $c = shift; |
56 | |
57 | $c->NEXT::setup(@_); |
58 | |
59 | # disable the plugin when running under certain engines which don't |
60 | # support SSL |
61 | # XXX: I didn't include Catalyst::Engine::Server here as it may be used as |
62 | # a backend in a proxy setup. |
63 | if ( $c->engine eq "Catalyst::Engine::HTTP" ) { |
64 | $c->config->{require_ssl}->{disabled} = 1; |
65 | $c->log->warn( "RequireSSL: Disabling SSL redirection while running " |
66 | . "under " . $c->engine ); |
67 | } |
68 | } |
69 | |
70 | sub _redirect_uri { |
71 | my ( $c, $type ) = @_; |
72 | |
73 | # XXX: Cat needs a $c->req->host method... |
74 | # until then, strip off the leading protocol from base |
75 | if ( !$c->config->{require_ssl}->{$type} ) { |
76 | my $host = $c->req->base; |
77 | $host =~ s/^http(s?):\/\///; |
78 | $c->config->{require_ssl}->{$type} = $host; |
79 | } |
80 | |
81 | if ( $c->config->{require_ssl}->{$type} !~ /\/$/xms ) { |
82 | $c->config->{require_ssl}->{$type} .= '/'; |
83 | } |
84 | |
85 | my $redir |
86 | = $type . '://' . $c->config->{require_ssl}->{$type} . $c->req->path; |
87 | |
88 | if ( scalar $c->req->param ) { |
89 | my @params |
90 | = map { "$_=" . $c->req->params->{$_} } sort $c->req->param; |
91 | $redir .= "?" . join "&", @params; |
92 | } |
93 | |
94 | return $redir; |
95 | } |
96 | |
97 | 1; |
98 | __END__ |
1763fe29 |
99 | |
100 | =head1 NAME |
101 | |
102 | Catalyst::Plugin::RequireSSL - Force SSL mode on select pages |
103 | |
104 | =head1 SYNOPSIS |
105 | |
eeefd598 |
106 | # in MyApp.pm |
107 | use Catalyst; |
108 | MyApp->setup( qw/RequireSSL/ ); |
1763fe29 |
109 | |
110 | MyApp->config->{require_ssl} = { |
111 | https => 'secure.mydomain.com', |
112 | http => 'www.mydomain.com', |
113 | remain_in_ssl => 0, |
114 | }; |
115 | |
eeefd598 |
116 | # in any controller methods that should be secured |
1763fe29 |
117 | $c->require_ssl; |
118 | |
119 | =head1 DESCRIPTION |
120 | |
eeefd598 |
121 | Use this plugin if you wish to selectively force SSL mode on some of your web |
122 | pages, for example a user login form or shopping cart. |
1763fe29 |
123 | |
eeefd598 |
124 | Simply place $c->require_ssl calls in any controller method you wish to be |
125 | secured. |
1763fe29 |
126 | |
eeefd598 |
127 | This plugin will automatically disable itself if you are running under the |
128 | standalone HTTP::Daemon Catalyst server. A warning message will be printed to |
129 | the log file whenever an SSL redirect would have occurred. |
1763fe29 |
130 | |
131 | =head1 WARNINGS |
132 | |
eeefd598 |
133 | If you utilize different servers or hostnames for non-SSL and SSL requests, |
134 | and you rely on a session cookie to determine redirection (i.e for a login |
135 | page), your cookie must be visible to both servers. For more information, see |
136 | the documentation for the Session plugin you are using. |
1763fe29 |
137 | |
138 | =head1 CONFIGURATION |
139 | |
140 | Configuration is optional. You may define the following configuration values: |
141 | |
142 | https => $ssl_host |
143 | |
144 | If your SSL domain name is different from your non-SSL domain, set this value. |
145 | |
146 | http => $non_ssl_host |
147 | |
eeefd598 |
148 | If you have set the https value above, you must also set the hostname of your |
149 | non-SSL server. |
1763fe29 |
150 | |
151 | remain_in_ssl |
152 | |
eeefd598 |
153 | If you'd like your users to remain in SSL mode after visiting an SSL-required |
154 | page, you can set this option to 1. By default, this option is disabled and |
155 | users will be redirected back to non-SSL mode as soon as possible. |
1763fe29 |
156 | |
eeefd598 |
157 | =head1 METHODS |
1763fe29 |
158 | |
eeefd598 |
159 | =head2 require_ssl |
1763fe29 |
160 | |
161 | Call require_ssl in any controller method you wish to be secured. |
162 | |
163 | $c->require_ssl; |
164 | |
eeefd598 |
165 | The browser will be redirected to the same path on your SSL server. POST |
166 | requests are never redirected. |
1763fe29 |
167 | |
168 | =head1 KNOWN ISSUES |
169 | |
eeefd598 |
170 | When viewing an SSL-required page that uses static files served from the |
171 | Static plugin, the static files are redirected to the non-SSL path. |
1763fe29 |
172 | |
eeefd598 |
173 | In order to get the correct behaviour where static files are not redirected, |
174 | you should use the Static::Simple plugin or always serve static files |
175 | directly from your web server. |
1763fe29 |
176 | |
177 | =head1 SEE ALSO |
178 | |
eeefd598 |
179 | L<Catalyst>, L<Catalyst::Plugin::Static::Simple> |
1763fe29 |
180 | |
181 | =head1 AUTHOR |
182 | |
eeefd598 |
183 | Andy Grundman, <andy@hybridized.org> |
1763fe29 |
184 | |
185 | =head1 COPYRIGHT |
186 | |
187 | This program is free software, you can redistribute it and/or modify it under |
188 | the same terms as Perl itself. |
189 | |
190 | =cut |