Commit | Line | Data |
d0102990 |
1 | Catalyst::Authenticatio\bUn\bs:\be:\brRe\bCa\bol\bnm\bt:\br:\biA\bbd\bua\bt\bCp\be\bat\bd\bto\bar\bP\bl(\be\by3\br\bs)\bl\bt:D\b:o\bAc\buu\btm\bhe\ben\bnt\bta\bit\bci\bao\btn\bion::Realm::Adaptor(3) |
c6a2d572 |
2 | |
c6a2d572 |
3 | |
c6a2d572 |
4 | |
d0102990 |
5 | N\bNA\bAM\bME\bE |
6 | Catalyst::Authentication::Realm::Adaptor − Adjust parameters of authen‐ |
7 | tication processes on the fly |
c6a2d572 |
8 | |
d0102990 |
9 | V\bVE\bER\bRS\bSI\bIO\bON\bN |
10 | Version 0.01 |
c6a2d572 |
11 | |
d0102990 |
12 | S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS |
13 | The Catalyst::Authentication::Realm::Adaptor allows for modification of |
14 | authentication parameters within the catalyst application. It’s basi‐ |
15 | cally a filter used to adjust authentication parameters globally within |
16 | the application or to adjust user retrieval parameters provided by the |
17 | credential in order to be compatible with a different store. It pro‐ |
18 | vides for better control over interaction between credentials and |
19 | stores. This is particularly useful when working with external authen‐ |
20 | tication such as OpenID or OAuth. |
c6a2d572 |
21 | |
d0102990 |
22 | __PACKAGE__‐>config( |
23 | ’Plugin::Authentication’ => { |
24 | ’default’ => { |
25 | class => ’Adaptor’ |
26 | credential => { |
27 | class => ’Password’, |
28 | password_field => ’secret’, |
29 | password_type => ’hashed’, |
30 | password_hash_type => ’SHA‐1’, |
31 | }, |
32 | store => { |
33 | class => ’DBIx::Class’, |
34 | user_class => ’Schema::Person’, |
35 | }, |
36 | store_adaptor => { |
37 | method => ’merge_hash’, |
38 | merge_hash => { |
39 | status => [ ’temporary’, ’active’ ] |
40 | } |
41 | } |
42 | }, |
43 | } |
44 | } |
45 | ); |
c6a2d572 |
46 | |
d0102990 |
47 | The above example ensures that no matter how $c−>_\ba_\bu_\bt_\bh_\be_\bn_\bt_\bi_\bc_\ba_\bt_\be_\b(_\b) is |
48 | called within your application, the key ’status’ is added to the |
49 | authentication hash. This allows you to, among other things, set |
50 | parameters that should always be applied to your authentication process |
51 | or modify the parameters to better connect a credential and a store |
52 | that were not built to work together. In the above example, we are mak‐ |
53 | ing sure that the user search is restricted to those with a status of |
54 | either ’temporary’ or ’active.’ |
c6a2d572 |
55 | |
d0102990 |
56 | This realm works by intercepting the original authentication informa‐ |
57 | tion between the time "$c−>authenticate($authinfo)" is called and the |
58 | time the realm’s "$realm−>authenticate($c,$authinfo)" method is called, |
59 | allowing for the $authinfo parameter to be modified or replaced as your |
60 | application requires. It can also operate after the call to the creden‐ |
61 | tial’s "authenticate()" method but before the call to the store’s |
62 | "find_user" method. |
c6a2d572 |
63 | |
d0102990 |
64 | If you don’t know what the above means, you probably do not need this |
65 | module. |
c6a2d572 |
66 | |
d0102990 |
67 | C\bCO\bON\bNF\bFI\bIG\bGU\bUR\bRA\bAT\bTI\bIO\bON\bN |
68 | The configuration for this module goes within your realm configuration |
69 | alongside your credential and store options. |
c6a2d572 |
70 | |
d0102990 |
71 | This module can operate in two points during authentication processing. |
72 | The first is prior the realm’s "authenticate" call (immediately after |
73 | the call to "$c−>authenticate()".) To operate here, your filter options |
74 | should go in a hash under the key "credential_adaptor". |
c6a2d572 |
75 | |
d0102990 |
76 | The second point is after the call to credential’s "authenticate" |
77 | method but immediately before the call to the user store’s "find_user" |
78 | method. To operate prior to "find_user", your filter options should go |
79 | in a hash under the key "store_adaptor". |
c6a2d572 |
80 | |
d0102990 |
81 | The filtering options for both points are the same, and both the |
82 | "store_adaptor" and "credential_adaptor" can be used simultaneously in |
83 | a single realm. |
c6a2d572 |
84 | |
d0102990 |
85 | m\bme\bet\bth\bho\bod\bd |
c6a2d572 |
86 | |
d0102990 |
87 | There are four ways to configure your filters. You specify which one |
88 | you want by setting the "method" configuration option to one of the |
89 | following: "merge_hash", "new_hash", "code", or "action". You then |
90 | provide the additional information based on which method you have cho‐ |
91 | sen. The different options are described below. |
c6a2d572 |
92 | |
d0102990 |
93 | merge_hash |
94 | credential_adaptor => { |
95 | method => ’merge_hash’, |
96 | merge_hash => { |
97 | status => [ ’temporary’, ’active’ ] |
98 | } |
99 | } |
c6a2d572 |
100 | |
d0102990 |
101 | This causes the original authinfo hash to be merged with a hash |
102 | provided by the realm configuration under the key "merge_hash" |
103 | key. This is a deep merge and in the case of a conflict, the |
104 | hash specified by merge_hash takes precedence over what was |
105 | passed into the authenticate or find_user call. The method of |
106 | merging is described in detail in the "HASH MERGING" section |
107 | below. |
c6a2d572 |
108 | |
d0102990 |
109 | new_hash |
110 | store_adaptor => { |
111 | method => ’new_hash’, |
112 | new_hash => { |
113 | username => ’+(user)’, # this sets username to the value of $originalhash{user} |
114 | user_source => ’openid’ |
115 | } |
116 | } |
c6a2d572 |
117 | |
d0102990 |
118 | This causes the original authinfo hash to be set aside and |
119 | replaced with a new hash provided under the "new_hash" key. The |
120 | new hash can grab portions of the original hash. This can be |
121 | used to remap the authinfo into a new format. See the "HASH |
122 | MERGING" section for information on how to do this. |
123 | |
124 | code |
125 | store_adaptor => { |
126 | method => ’code’, |
127 | code => sub { |
128 | my ($realmname, $original_authinfo, $hashref_to_config ) = @_; |
129 | my $newauthinfo = {}; |
130 | ## do something |
131 | return $newauthinfo; |
132 | } |
133 | } |
134 | |
135 | The "code" method allows for more complex filtering by execut‐ |
136 | ing code provided as a subroutine reference in the "code" key. |
137 | The realm name, original auth info and the portion of the con‐ |
138 | fig specific to this filter are passed as arguments to the pro‐ |
139 | vided subroutine. In the above example, it would be the entire |
140 | store_adaptor hash. If you were using a code ref in a creden‐ |
141 | tial_adaptor, you’d get the credential_adapter config instead. |
142 | |
143 | action |
144 | credential_adaptor => { |
145 | method => ’action’, |
146 | controller => ’UserProcessing’, |
147 | action => ’FilterCredentials’ |
148 | } |
149 | |
150 | The "action" method causes the adaptor to delegate filtering to |
151 | a Catalyst action. This is similar to the code ref above, |
152 | except that instead of simply calling the routine, the action |
153 | specified is called via "<$c−"forward>>. The arguments passed |
154 | to the action are the same as the code method as well, namely |
155 | the realm name, the original authinfo hash and the config for |
156 | the adaptor. |
157 | |
158 | H\bHA\bAS\bSH\bH M\bME\bER\bRG\bGI\bIN\bNG\bG |
159 | The hash merging mechanism in Catalyst::Authentication::Realm::Adaptor |
160 | is not a simple merge of two hashes. It has some niceties which allow |
161 | for both re‐mapping of existing keys, and a mechanism for removing keys |
162 | from the original hash. When using the ’merge_hash’ method above, the |
163 | keys from the original hash and the keys for the merge hash are simply |
164 | combined with the merge_hash taking precedence in the case of a key |
165 | conflict. If there are sub‐hashes they are merged as well. |
166 | |
167 | If both the source and merge hash contain an array for a given |
168 | hash−key, the values in the merge array are appended to the original |
169 | array. Note that hashes within arrays will not be merged, and will |
170 | instead simply be copied. |
171 | |
172 | Simple values are left intact, and in the case of a key existing in |
173 | both hashes, the value from the merge_hash takes precedence. Note that |
174 | in the case of a key conflict where the values are of different types, |
175 | the value from the merge_hash will be used and no attempt is made to |
176 | merge or otherwise convert them. |
177 | |
178 | A\bAd\bdv\bva\ban\bnc\bce\bed\bd m\bme\ber\brg\bgi\bin\bng\bg |
179 | |
180 | Whether you are using "merge_hash" or "new_hash" as the method, you |
181 | have access to the values from the original authinfo hash. In your new |
182 | or merged hash, you can use values from anywhere within the original |
183 | hash. You do this by setting the value for the key you want to set to |
184 | a special string indicating the key path in the original hash. The |
185 | string is formatted as follows: "<’+(key1.key2.key3)’"> This will grab |
186 | the hash associated with key1, retrieve the hash associated with key2, |
187 | and finally obtain the value associated with key3. This is easier to |
188 | show than to explain: |
189 | |
190 | my $originalhash = { |
191 | user => { |
192 | details => { |
193 | age => 27, |
194 | haircolor => ’black’, |
195 | favoritenumbers => [ 17, 42, 19 ] |
196 | } |
197 | } |
198 | }; |
199 | |
200 | my $newhash = { |
201 | # would result in a value of ’black’ |
202 | haircolor => ’+(user.details.haircolor)’, |
203 | |
204 | # bestnumber would be 42. |
205 | bestnumber => ’+(user.details.favoritenumbers.1)’ |
206 | } |
207 | |
208 | Given the example above, the value for the userage key would be 27, |
209 | (obtained via "<’+(user.details.age)’">) and the value for bestnumber |
210 | would be 42. Note that you can traverse both hashes and arrays using |
211 | this method. This can be quite useful when you need the values that |
212 | were passed in, but you need to put them under different keys. |
213 | |
214 | When using the "merge_hash" method, you sometimes may want to remove an |
215 | item from the original hash. You can do this by providing a key in your |
216 | merge_hash at the same point, but setting it’s value to ’−()’. This |
217 | will remove the key entirely from the resultant hash. This works bet‐ |
218 | ter than simply setting the value to undef in some cases. |
219 | |
220 | N\bNO\bOT\bTE\bES\bS a\ban\bnd\bd C\bCA\bAV\bVE\bEA\bAT\bTS\bS |
221 | The authentication system for Catalyst is quite flexible. In most |
222 | cases this module is not needed. Evidence of this fact is that the |
223 | Catalyst auth system was substantially unchanged for 2+ years prior to |
224 | this modules first release. If you are looking at this module, then |
225 | there is a good chance your problem would be better solved by adjusting |
226 | your credential or store directly. |
227 | |
228 | That said, there are some areas where this module can be particularly |
229 | useful. For example, this module allows for global application of |
230 | additional arguments to authinfo for a certain realm via your config. |
231 | It also allows for preliminary testing of alternate configs before you |
232 | adjust every "$c−>authenticate()" call within your application. |
233 | |
234 | It is also useful when combined with the various external authentica‐ |
235 | tion modules available, such as OpenID, OAuth or Facebook. These mod‐ |
236 | ules expect to store their user information in the Hash provided by the |
237 | Minimal user store. Often, however, you want to store user information |
238 | locally in a database or other storage mechanism. Doing this lies some‐ |
239 | where between difficult and impossible normally. With the Adapter |
240 | realm, you can massage the authinfo hash between the credential’s veri‐ |
241 | fication and the creation of the local user, and instead use the infor‐ |
242 | mation returned to look up a user instead. |
243 | |
244 | Using the external auth mechanisms and the "action" method, you can |
245 | actually trigger an action to create a user record on the fly when the |
246 | user has authenticated via an external method. These are just some of |
247 | the possibilities that Adaptor provides that would otherwise be very |
248 | difficult to accomplish, even with Catalyst’s flexible authentication |
249 | system. |
250 | |
251 | With all of that said, caution is warranted when using this module. It |
252 | modifies the behavior of the application in ways that are not obvious |
253 | and can therefore lead to extremely hard to track‐down bugs. This is |
254 | especially true when using the "action" filter method. When a devel‐ |
255 | oper calls "$c−>authenticate()" they are not expecting any actions to |
256 | be called before it returns. |
257 | |
258 | If you use the "action" method, I strongly recommend that you use it |
259 | only as a filter routine and do not do other catalyst dispatch related |
260 | activities (such as further forwards, detach’s or redirects). Also |
261 | note that it is E\bEX\bXT\bTR\bRE\bEM\bME\bEL\bLY\bY D\bDA\bAN\bNG\bGE\bER\bRO\bOU\bUS\bS to call authentication routines |
262 | from within a filter action. It is extremely easy to accidentally cre‐ |
263 | ate an infinite recursion bug which can crash your Application. In |
264 | short − D\bDO\bON\bN’\b’T\bT D\bDO\bO I\bIT\bT. |
265 | |
266 | A\bAU\bUT\bTH\bHO\bOR\bR |
267 | Jay Kuri, "<jayk at cpan.org>" |
268 | |
269 | B\bBU\bUG\bGS\bS |
270 | Please report any bugs or feature requests to "bug−catalyst−authentica‐ |
271 | tion−realm−adaptor at rt.cpan.org", or through the web interface at |
272 | <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Catalyst−Authentica‐ |
273 | tion−Realm−Adaptor>. I will be notified, and then you’ll automatically |
274 | be notified of progress on your bug as I make changes. |
275 | |
276 | S\bSU\bUP\bPP\bPO\bOR\bRT\bT |
277 | You can find documentation for this module with the perldoc command. |
278 | |
279 | perldoc Catalyst::Authentication::Realm::Adaptor |
280 | |
281 | You can also look for information at: |
282 | |
283 | * Search CPAN |
284 | <http://search.cpan.org/dist/Catalyst−Authentication−Realm−Adap‐ |
285 | tor/> |
286 | |
287 | * Catalyzed.org Wiki |
288 | <http://wiki.catalyzed.org/cpan−modules/Catalyst−Authentica‐ |
289 | tion−Realm−Adaptor> |
290 | |
291 | A\bAC\bCK\bKN\bNO\bOW\bWL\bLE\bED\bDG\bGE\bEM\bME\bEN\bNT\bTS\bS |
292 | C\bCO\bOP\bPY\bYR\bRI\bIG\bGH\bHT\bT &\b& L\bLI\bIC\bCE\bEN\bNS\bSE\bE |
293 | Copyright 2009 Jay Kuri, all rights reserved. |
294 | |
295 | This program is free software; you can redistribute it and/or modify it |
296 | under the same terms as Perl itself. |
297 | |
298 | |
299 | |
300 | perl v5.8.9 20\bC0\ba9\bt‐\ba0\bl7\by‐\bs2\bt6\b::Authentication::Realm::Adaptor(3) |