restful_authentication 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +68 -0
- data/LICENSE +20 -0
- data/README.textile +232 -0
- data/Rakefile +54 -0
- data/TODO +15 -0
- data/generators/authenticated/USAGE +1 -0
- data/generators/authenticated/authenticated_generator.rb +493 -0
- data/generators/authenticated/lib/insert_routes.rb +69 -0
- data/generators/authenticated/templates/_model_partial.html.erb +8 -0
- data/generators/authenticated/templates/activation.erb +3 -0
- data/generators/authenticated/templates/authenticated_system.rb +189 -0
- data/generators/authenticated/templates/authenticated_test_helper.rb +12 -0
- data/generators/authenticated/templates/controller.rb +43 -0
- data/generators/authenticated/templates/features/accounts.feature +67 -0
- data/generators/authenticated/templates/features/sessions.feature +77 -0
- data/generators/authenticated/templates/features/step_definitions/ra_env.rb +7 -0
- data/generators/authenticated/templates/features/step_definitions/user_steps.rb +31 -0
- data/generators/authenticated/templates/helper.rb +2 -0
- data/generators/authenticated/templates/login.html.erb +14 -0
- data/generators/authenticated/templates/machinist_spec.rb +5 -0
- data/generators/authenticated/templates/machinist_test.rb +5 -0
- data/generators/authenticated/templates/mailer.rb +25 -0
- data/generators/authenticated/templates/migration.rb +24 -0
- data/generators/authenticated/templates/model.rb +83 -0
- data/generators/authenticated/templates/model_controller.rb +96 -0
- data/generators/authenticated/templates/model_helper.rb +93 -0
- data/generators/authenticated/templates/model_helper_spec.rb +157 -0
- data/generators/authenticated/templates/observer.rb +11 -0
- data/generators/authenticated/templates/signup.html.erb +19 -0
- data/generators/authenticated/templates/signup_notification.erb +8 -0
- data/generators/authenticated/templates/site_keys.rb +38 -0
- data/generators/authenticated/templates/spec/blueprints/user.rb +13 -0
- data/generators/authenticated/templates/spec/controllers/access_control_spec.rb +89 -0
- data/generators/authenticated/templates/spec/controllers/authenticated_system_spec.rb +107 -0
- data/generators/authenticated/templates/spec/controllers/sessions_controller_spec.rb +138 -0
- data/generators/authenticated/templates/spec/controllers/users_controller_spec.rb +197 -0
- data/generators/authenticated/templates/spec/fixtures/users.yml +60 -0
- data/generators/authenticated/templates/spec/helpers/users_helper_spec.rb +141 -0
- data/generators/authenticated/templates/spec/models/user_spec.rb +298 -0
- data/generators/authenticated/templates/tasks/auth.rake +33 -0
- data/generators/authenticated/templates/test/functional_test.rb +84 -0
- data/generators/authenticated/templates/test/mailer_test.rb +31 -0
- data/generators/authenticated/templates/test/model_functional_test.rb +91 -0
- data/generators/authenticated/templates/test/unit_test.rb +177 -0
- data/lib/authentication.rb +40 -0
- data/lib/authentication/by_cookie_token.rb +82 -0
- data/lib/authentication/by_password.rb +64 -0
- data/lib/authorization.rb +14 -0
- data/lib/authorization/aasm_roles.rb +64 -0
- data/lib/authorization/stateful_roles.rb +64 -0
- data/lib/restful_authentication.rb +6 -0
- data/lib/trustification.rb +14 -0
- data/lib/trustification/email_validation.rb +20 -0
- data/notes/AccessControl.txt +2 -0
- data/notes/Authentication.txt +5 -0
- data/notes/Authorization.txt +154 -0
- data/notes/RailsPlugins.txt +78 -0
- data/notes/SecurityFramework.graffle +0 -0
- data/notes/SecurityFramework.png +0 -0
- data/notes/SecurityPatterns.txt +163 -0
- data/notes/Tradeoffs.txt +126 -0
- data/notes/Trustification.txt +49 -0
- data/restful_authentication.gemspec +32 -0
- metadata +128 -0
@@ -0,0 +1,78 @@
|
|
1
|
+
h1. Rails Authentication, Authorization and Access Control plugins
|
2
|
+
|
3
|
+
h2. Authentication plugins
|
4
|
+
|
5
|
+
* http://github.com/technoweenie/restful-authentication/tree/master -- the accepted standard for authentication
|
6
|
+
* http://github.com/mrflip/restful-authentication/tree/master -- my fork of restful_authentication with more modularity, more specs and a few security tweaks
|
7
|
+
* http://github.com/josh/open_id_authentication/tree/master -- OpenID authentication
|
8
|
+
|
9
|
+
h2. Authorization plugins
|
10
|
+
|
11
|
+
From
|
12
|
+
* http://agilewebdevelopment.com/plugins/tag/security
|
13
|
+
* http://www.vaporbase.com/postings/Authorization_in_Rails
|
14
|
+
|
15
|
+
* http://github.com/jbarket/restful-authorization/tree/master
|
16
|
+
|
17
|
+
* http://agilewebdevelopment.com/plugins/rolerequirement
|
18
|
+
http://code.google.com/p/rolerequirement/
|
19
|
+
http://rolerequirement.googlecode.com/svn/tags/role_requirement/
|
20
|
+
9 votes
|
21
|
+
|
22
|
+
* http://github.com/ezmobius/acl_system2/
|
23
|
+
http://agilewebdevelopment.com/plugins/acl_system
|
24
|
+
http://opensvn.csie.org/ezra/rails/plugins/dev/acl_system2/
|
25
|
+
last touched 2006
|
26
|
+
57 votes on AWD
|
27
|
+
* also: http://agilewebdevelopment.com/plugins/acl_system2_ownership
|
28
|
+
|
29
|
+
bq. access_control [:new, :create, :update, :edit] => '(admin | user |
|
30
|
+
moderator)', :delete => 'admin'
|
31
|
+
<% restrict_to "(admin | moderator) & !blacklist" do %>
|
32
|
+
<%= link_to "Admin & Moderator only link", :action =>'foo' %>
|
33
|
+
<% end %>
|
34
|
+
|
35
|
+
* Authorization Recipe (from Rails Recipes #32)
|
36
|
+
http://www.vaporbase.com/postings/Authorization_in_Rails
|
37
|
+
http://opensvn.csie.org/mabs29/plugins/simple_access_control
|
38
|
+
|
39
|
+
* Active ACL
|
40
|
+
http://phpgacl.sourceforge.net/demo/phpgacl/docs/manual.html
|
41
|
+
(Access-matrix driven)
|
42
|
+
|
43
|
+
* http://github.com/aiwilliams/access_controlled_system
|
44
|
+
|
45
|
+
* http://agilewebdevelopment.com/plugins/access
|
46
|
+
|
47
|
+
* http://robzon.aenima.pl/2007/12/base-auth-is-out.html
|
48
|
+
http://agilewebdevelopment.com/plugins/base_auth
|
49
|
+
http://base-auth.googlecode.com/svn/trunk/
|
50
|
+
40 votes
|
51
|
+
|
52
|
+
* http://agilewebdevelopment.com/plugins/authorization
|
53
|
+
http://www.writertopia.com/developers/authorization
|
54
|
+
http://github.com/DocSavage/rails-authorization-plugin/tree/master
|
55
|
+
Opaque policy descriptions
|
56
|
+
19 votes
|
57
|
+
|
58
|
+
* http://github.com/shuber/access_control_list/
|
59
|
+
Not much there yet
|
60
|
+
|
61
|
+
* https://opensvn.csie.org/traccgi/tobionrails
|
62
|
+
http://agilewebdevelopment.com/plugins/access_control
|
63
|
+
http://opensvn.csie.org/tobionrails/plugins/access_control
|
64
|
+
last touched 1 year ago
|
65
|
+
|
66
|
+
* http://github.com/mdarby/restful_acl/
|
67
|
+
-- google code too --
|
68
|
+
Just does REST? More of an app than a plugin.
|
69
|
+
|
70
|
+
* http://github.com/stonean/lockdown/tree/master
|
71
|
+
http://lockdown.rubyforge.org
|
72
|
+
http://groups.google.com/group/stonean_lockdown?hl=en
|
73
|
+
"Lockdown stores an array of access rights in the session"
|
74
|
+
|
75
|
+
h2. Trust / Validation etc. plugins
|
76
|
+
|
77
|
+
|
78
|
+
* http://agilewebdevelopment.com/plugins/recaptcha
|
Binary file
|
Binary file
|
@@ -0,0 +1,163 @@
|
|
1
|
+
h1. Security from the perspective of a community site.
|
2
|
+
|
3
|
+
Better than anything you'll read below on the subject:
|
4
|
+
|
5
|
+
* "The OWASP Guide to Building Secure Web Applications":http://www.owasp.org/index.php/Category:OWASP_Guide_Project
|
6
|
+
* "Secure Programming for Linux and Unix HOWTO":http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/web-authentication.html
|
7
|
+
* "Core Security Patterns":http://www.coresecuritypatterns.com/patterns.htm
|
8
|
+
* Stephen Downes' article on "Authentication and Identification":http://www.downes.ca/post/12
|
9
|
+
|
10
|
+
h2. Snazzy Diagram
|
11
|
+
|
12
|
+
!http://github.com/technoweenie/restful-authentication/tree/master/notes/SecurityFramework.png?raw=true!:http://github.com/technoweenie/restful-authentication/tree/master/notes/SecurityFramework.png
|
13
|
+
|
14
|
+
(in notes/SecurityFramework.png)
|
15
|
+
|
16
|
+
h2. Terms
|
17
|
+
|
18
|
+
* Identification: Assign this visitor a name and an associated identity
|
19
|
+
(picture, website, favorite pokemon, trust metric, security roles).
|
20
|
+
|
21
|
+
bq. "Behold. I am not Gandalf the Grey, whom you betrayed, I am Gandalf the White,
|
22
|
+
who has returned from death." -- Tolkien
|
23
|
+
|
24
|
+
* Authentication: Verify this visitor matches the claimed identity.
|
25
|
+
|
26
|
+
bq. "My name is Werner Brandis. My voice is my password. Verify me." -- Sneakers
|
27
|
+
|
28
|
+
* Authorization: Given a request (Actions+Resource+Environment), decide if it's safe.
|
29
|
+
|
30
|
+
bq. "Of every tree of the garden thou mayest freely eat: But of the tree of
|
31
|
+
the knowledge of good and evil, thou shalt not eat of it: for in the day that
|
32
|
+
thou eatest thereof thou shalt surely die." -- Gen 2:16-17
|
33
|
+
|
34
|
+
* Trust: Confidence this visitor will act reliably.
|
35
|
+
|
36
|
+
bq. "A copper! A copper! How d'ya like that, boys? And we went for it. _I_ went
|
37
|
+
for it. Treated him like a kid brother. And I was gonna split fifty-fifty with
|
38
|
+
a copper." -- James Cagney, White Heat
|
39
|
+
|
40
|
+
** Reputation from Trust Network: Award trust to this visitor based on what other trusted parties say.
|
41
|
+
|
42
|
+
bq. "He used my name? In the /street/? He called me a punk? My name was on
|
43
|
+
the street? When we bounce from this s-t here, Y'all gonna go down on them
|
44
|
+
corners, let the people know: word did not get back to me. Let 'em know Marlo
|
45
|
+
step to any m-f-: Omar, Barksdale, whoever. My name IS my NAME." -- Marlo
|
46
|
+
Stansfield, The Wire (paraphrased)
|
47
|
+
|
48
|
+
* Reputation from Past Actions:
|
49
|
+
|
50
|
+
bq. "The man you just killed was just released from prison. He could've f-in'
|
51
|
+
walked. All he had to do was say my dad's name, but he didn't; he kept his
|
52
|
+
f-ing mouth shut. And did his f-in' time, and he did it like a man. He did
|
53
|
+
four years for us. So, Mr. Orange, you're tellin' me this very good friend of
|
54
|
+
mine, who did four years for my father, who in four years never made a deal,
|
55
|
+
no matter what they dangled in front of him, you're telling me that now, that
|
56
|
+
now this man is free, and we're making good on our commitment to him, he's
|
57
|
+
just gonna decide, out of the f-ing blue, to rip us off?" -- Nice Guy Eddie,
|
58
|
+
Reservoir Dogs
|
59
|
+
|
60
|
+
* Access control
|
61
|
+
|
62
|
+
** Role
|
63
|
+
* http://en.wikipedia.org/wiki/Role-based_access_control
|
64
|
+
* "Role-Based Access Control FAQ":http://csrc.nist.gov/groups/SNS/rbac/faq.html
|
65
|
+
* "Role Based Access Control and Role Based Security":http://csrc.nist.gov/groups/SNS/rbac/ from the NIST Computer Security Division
|
66
|
+
|
67
|
+
|
68
|
+
* Auditing & Recovery
|
69
|
+
|
70
|
+
h2. Concept
|
71
|
+
|
72
|
+
@ The below is a mixture of half-baked, foolish and incomplete. Just sos you know. @
|
73
|
+
|
74
|
+
* Identity here will mean 'online presence' -- user account, basically.
|
75
|
+
* Person will mean the remote endpoint -- whether that's a person or robot or
|
76
|
+
company. (Security papers call this "Subject" but that's awful).
|
77
|
+
* It's easy to confuse 'person' and 'identity', so easy I probably have below.
|
78
|
+
|
79
|
+
Why do you need to authenticate? For authorization. So traditionally, we think
|
80
|
+
|
81
|
+
person <- (ath'n token) <- identity <- (policy) <- actions
|
82
|
+
|
83
|
+
That is, actions are attached to an identity by security policy, identity is
|
84
|
+
attached to a person by their authentication token.
|
85
|
+
|
86
|
+
The problem is that we cannot authenticate a /person/, only the token they
|
87
|
+
present: password, ATM card+PIN number, etc.
|
88
|
+
bq. "The Doors of Durin, Lord of Moria. Speak friend, and enter" -- Tolkien
|
89
|
+
|
90
|
+
Anyone who presents that card+PIN, Elvish catchphrase, or voice print will be
|
91
|
+
authenticated to act as the corresponding identity (account holder, friend of
|
92
|
+
the elves, nerdy scientist), and we have no control over those tokens.
|
93
|
+
|
94
|
+
person <- (ath'n token) <- identity <- (az'n policy) <- actions
|
95
|
+
^^^^ This step is wrong.
|
96
|
+
|
97
|
+
The solution is to not care, or rather to reframe our goals.
|
98
|
+
|
99
|
+
What we actually want is not to /control/ users' actions, but to /predict/ them.
|
100
|
+
When Mr. Blonde helps Mr. White rob a jewelry store it's a security failure for
|
101
|
+
the store but a success for the crime gang. When Mr. Orange (an undercover cop)
|
102
|
+
shoots Mr. Blonde it's a security failure for the crime gang and a success for
|
103
|
+
the police. We want to know how to use
|
104
|
+
|
105
|
+
( identity, past actions ) => (trust, future actions)
|
106
|
+
|
107
|
+
If you can predict someone is a vandal or troll, don't let them change pages, or
|
108
|
+
only let them post to Ye Flaming Pitte of Flamage.
|
109
|
+
|
110
|
+
We can to reasonable satisfaction authenticate a token: only grant that
|
111
|
+
identity to visitors who bear that token. So this part is fine:
|
112
|
+
|
113
|
+
person (token)<- identity
|
114
|
+
|
115
|
+
But we have no control over authentication token - identity correspondence.
|
116
|
+
This part is broken:
|
117
|
+
|
118
|
+
person x (token)<- identity
|
119
|
+
|
120
|
+
The only one who does have that control is the person behind that identity.
|
121
|
+
They can reasonably guarantee
|
122
|
+
|
123
|
+
person ->(token)<- identity
|
124
|
+
|
125
|
+
If that person is going to be in your community, they have an interest in their
|
126
|
+
identity: they want to be known as someone who isn't a punk, or doesn't troll,
|
127
|
+
or does troll and better than anyone, or won't rat you out to the cops. The
|
128
|
+
actions of a person are moderated by their interest in maintaining their
|
129
|
+
reputation:
|
130
|
+
|
131
|
+
past actions -> reputation ->person
|
132
|
+
|
133
|
+
So give up authorization in favor of auditing and recoverability, and authorize
|
134
|
+
based on reputation -- on the past behavior and vouchsafes offered by the
|
135
|
+
identity,
|
136
|
+
|
137
|
+
reputation -> trust -> permissions ->actions
|
138
|
+
|
139
|
+
They want to know that they have full control of their identity; among other
|
140
|
+
things, privacy and an understanding that nobody can act without permission on
|
141
|
+
their behalf. In fact, we can assure that only a token-holder can assume the
|
142
|
+
corresponding identity:
|
143
|
+
|
144
|
+
person ->(token)<->identity ->(trust) actions ->reputation ->person
|
145
|
+
|
146
|
+
poop
|
147
|
+
|
148
|
+
reputation ->trust
|
149
|
+
|
150
|
+
|
151
|
+
So we need to
|
152
|
+
* Understand and encourage how their security interests aligns with ours,
|
153
|
+
* Understand how it doesn't, and be robust in the face of that; and
|
154
|
+
* Recover gracefully if it goes wrong.
|
155
|
+
|
156
|
+
Instead of
|
157
|
+
|
158
|
+
authorization -> user -> token -> identity
|
159
|
+
|
160
|
+
we assign roles based on
|
161
|
+
|
162
|
+
authorization <- trust <- reputation <- identity <- token <- person
|
163
|
+
|
data/notes/Tradeoffs.txt
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
Guides to best practices:
|
2
|
+
* "The OWASP Guide to Building Secure Web Applications":http://www.owasp.org/index.php/Category:OWASP_Guide_Project
|
3
|
+
* "Secure Programming for Linux and Unix HOWTO":http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/web-authentication.html
|
4
|
+
* [[http://www.coresecuritypatterns.com/patterns.htm]]
|
5
|
+
|
6
|
+
***************************************************************************
|
7
|
+
h2. Session resetting
|
8
|
+
|
9
|
+
Best practices recommend that you regenerate all session tokens (for us, the
|
10
|
+
browser session ID and the remember_token cookie) on any privilege change (for
|
11
|
+
us, logging in or logging out) -- see http://tinyurl.com/5vdvuq. This release
|
12
|
+
properly regenerates remember_token cookies, but does *not* by default
|
13
|
+
reset_session.
|
14
|
+
|
15
|
+
Calling reset_session can interact with Form Authentication tokens (a *much*
|
16
|
+
more important security feature). If a visitor logs in but has a form open in
|
17
|
+
another tab, or uses the back button to pull one up from their history (perhaps
|
18
|
+
the one that required them to log in), they will get the exceedingly unpleasant
|
19
|
+
Request Forgery error. Imagine spending twenty minutes crafting a devastating
|
20
|
+
critique of this week's Battlestar Galactica episode, finding you need to log in
|
21
|
+
before posting -- but then getting a Request Forgery when you re-attempt the
|
22
|
+
post. Frak! Thus, it's disabled by default.
|
23
|
+
|
24
|
+
On the other hand, this does moderately reduce your defense-in-depth against a
|
25
|
+
"Cross-Site Request Forgery":http://en.wikipedia.org/wiki/CSRF attack. To
|
26
|
+
enable session_resetting, look for any
|
27
|
+
# reset session
|
28
|
+
lines in the app/controllers/session_controller.rb and
|
29
|
+
app/controllers/users_controller.rb and uncomment them.
|
30
|
+
|
31
|
+
***************************************************************************
|
32
|
+
h2. Site Key
|
33
|
+
|
34
|
+
A Site key gives additional protection against a dictionary attack if your
|
35
|
+
DB is ever compromised. With no site key, we store
|
36
|
+
DB_password = hash(user_password, DB_user_salt)
|
37
|
+
If your database were to be compromised you'd be vulnerable to a dictionary
|
38
|
+
attack on all your stupid users' passwords. With a site key, we store
|
39
|
+
DB_password = hash(user_password, DB_user_salt, Code_site_key)
|
40
|
+
That means an attacker needs access to both your site's code *and* its
|
41
|
+
database to mount an "offline dictionary attack.":http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/web-authentication.html
|
42
|
+
|
43
|
+
It's probably of minor importance, but recommended by best practices: 'defense
|
44
|
+
in depth'. Needless to say, if you upload this to github or the youtubes or
|
45
|
+
otherwise place it in public view you'll kinda defeat the point. Your users'
|
46
|
+
passwords are still secure, and the world won't end, but defense_in_depth -= 1.
|
47
|
+
|
48
|
+
Please note: if you change this, all the passwords will be invalidated, so DO
|
49
|
+
keep it someplace secure. Use the random value given or type in the lyrics to
|
50
|
+
your favorite Jay-Z song or something; any moderately long, unpredictable text.
|
51
|
+
|
52
|
+
***************************************************************************
|
53
|
+
h2. Password stretching
|
54
|
+
|
55
|
+
If someone were to capture your user accounts database, they could farm it out
|
56
|
+
for brute-force or dictionary-attack password cracking. "Password Stretching"
|
57
|
+
makes brute force (even with a compromised database and site key) attacks
|
58
|
+
harder, and scales with Moore's law. Basically, you apply the password
|
59
|
+
encryption process several times, meaning that each brute-force attempt takes
|
60
|
+
that much longer. Hash your password ten times, and a brute-force attack takes
|
61
|
+
ten times longer; hash 100,000 times and an attack takes 100,000 times longer.
|
62
|
+
|
63
|
+
bq. "To squeeze the most security out of a limited-entropy password or
|
64
|
+
passphrase, we can use two techniques [salting and stretching]... that are so
|
65
|
+
simple and obvious that they should be used in every password system. There
|
66
|
+
is really no excuse not to use them. ... Choose stretching factor so computing
|
67
|
+
K from (salt, passwd) takes 200-1000 ms. Store r with the user's password, and
|
68
|
+
increase it as computers get faster." -- http://tinyurl.com/37lb73
|
69
|
+
Practical Security (Ferguson & Scheier) p350
|
70
|
+
|
71
|
+
Now, adding even a 0.2s delay to page requests isn't justifiable for most online
|
72
|
+
applications, and storing r is unnecessary (at least on your first design
|
73
|
+
iteration). But
|
74
|
+
On a 1G Slicehost already under moderate load:
|
75
|
+
irb(main):005:0> puts Time.now; (10**6).times{ secure_digest(Time.now, rand) }; puts Time.now
|
76
|
+
Fri May 16 08:26:16 +0000 2008
|
77
|
+
Fri May 16 08:30:58 +0000 2008
|
78
|
+
=> 280s/1M ~= 0.000_3 ms / digest
|
79
|
+
A modest 10 (the default here) foldings makes brute forcing, even given the site
|
80
|
+
key and database, 10 times harder at a 3ms penalty. An app that otherwise
|
81
|
+
serves 100 reqs/s is reduced to 78 signin reqs/s; an app that does 10reqs/s is
|
82
|
+
reduced to 9.7 signin reqs/s
|
83
|
+
|
84
|
+
* http://www.owasp.org/index.php/Hashing_Java
|
85
|
+
* "An Illustrated Guide to Cryptographic Hashes":http://www.unixwiz.net/techtips/iguide-crypto-hashes.html
|
86
|
+
|
87
|
+
The default of 10 is a reasonable compromise, but the security-paranoid and
|
88
|
+
resource-rich may consider increasing REST_AUTH_DIGEST_STRETCHES to match the
|
89
|
+
one-second best-practices value, while those with existing userbases (whose
|
90
|
+
passwords would otherwise no longer work) should leave the value at one.
|
91
|
+
|
92
|
+
***************************************************************************
|
93
|
+
h2. Token regeneration
|
94
|
+
|
95
|
+
The session and the remember_token should both be expired and regenerated
|
96
|
+
every time we cross the logged out / logged in barrier by either password
|
97
|
+
or cookie. ("To reduce the risk from session hijacking":http://www.owasp.org/index.php/Session_Management#Regeneration_of_Session_Tokens
|
98
|
+
and brute force attacks, the HTTP server can seamlessly expire and
|
99
|
+
regenerate tokens. This decreases the window of opportunity for a replay or
|
100
|
+
brute force attack.) It does mean we set the cookie more often.
|
101
|
+
|
102
|
+
http://www.owasp.org/index.php/Session_Management#Regeneration_of_Session_Tokens
|
103
|
+
http://palisade.plynt.com/issues/2004Jul/safe-auth-practices/
|
104
|
+
|
105
|
+
|
106
|
+
***************************************************************************
|
107
|
+
h2. Field validation
|
108
|
+
|
109
|
+
We restrict login names to only contain the characters
|
110
|
+
<nowiki>A-Za-z0-9.-_@</nowiki> This allows (most) email addresses and is safe
|
111
|
+
for urls, database expressions (the at sign, technically reserved in a url, will
|
112
|
+
survive in most browsers). If you want to be more permissive:
|
113
|
+
* "URL-legal characters":http://www.blooberry.com/indexdot/html/topics/urlencoding.htm are <nowiki>-_.!~*'()</nowiki>
|
114
|
+
* "XML-legal characters":http://www.sklar.com/blog/archives/96-XML-vs.-Control-Characters.html are <nowiki>Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]</nowiki>
|
115
|
+
* "Email-address legal characters":http://tools.ietf.org/html/rfc2822#section-3.4.1 are <nowiki>0-9a-zA-Z!#\$%\&\'\*\+_/=\?^\-`\{|\}~\.</nowiki> but see "this discussion of what is sane"http://www.regular-expressions.info/email.html (as opposed to legal)
|
116
|
+
|
117
|
+
We restrict email addresses to match only those actually seen in the wild,
|
118
|
+
invalidating some that are technically allowed (characters such as % and ! that
|
119
|
+
date back to UUCP days. The line to allow all RFC-2822 emails is commented out,
|
120
|
+
so feel free to enable it, or remove this validation. See "this discussion of
|
121
|
+
what is sane"http://www.regular-expressions.info/email.html as opposed to what
|
122
|
+
is legal. Also understand that this is just a cursory bogus-input check --
|
123
|
+
there's no guarantee that this email matches an account or is even well-formed.
|
124
|
+
|
125
|
+
If you change these validations you should change the RSpec tests as well.
|
126
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
See also
|
2
|
+
* "Trustlet Wiki":http://www.trustlet.org/wiki
|
3
|
+
|
4
|
+
Potential Ingredients for a trust metric
|
5
|
+
|
6
|
+
h2. Reputation
|
7
|
+
|
8
|
+
* Web of trust
|
9
|
+
* Reputation systems
|
10
|
+
** Akismet, Viking, etc.
|
11
|
+
|
12
|
+
* prove_as_human Completing a
|
13
|
+
* validate_email
|
14
|
+
|
15
|
+
logged_in
|
16
|
+
akismet, etc.
|
17
|
+
session duration
|
18
|
+
|
19
|
+
h2. Accountability
|
20
|
+
|
21
|
+
Does the person tied to this identity stand to lose or gain anything based on this action?
|
22
|
+
|
23
|
+
|
24
|
+
h2. Past history
|
25
|
+
|
26
|
+
* past history
|
27
|
+
** we can revisit past trust decisions based on revised trust estimates
|
28
|
+
* recency of errors (reduce trust on an application exception)
|
29
|
+
|
30
|
+
h2. Commitment
|
31
|
+
|
32
|
+
* are_you_sure -- ask for con
|
33
|
+
* willingness to pay a "hate task" (compute big hash) a la Zed Shaw
|
34
|
+
* send_me_one_cent a micropayment
|
35
|
+
** shows commitment
|
36
|
+
** secondary validation from payment system
|
37
|
+
** offsets rist
|
38
|
+
|
39
|
+
h2. Identity Binding
|
40
|
+
|
41
|
+
* Stale sessions
|
42
|
+
bq. "If your application allows users to be logged in for long periods of time
|
43
|
+
ensure that controls are in place to revalidate a user’s authorization to a
|
44
|
+
resource. For example, if Bob has the role of “Top Secret” at 1:00, and at
|
45
|
+
2:00 while he is logged in his role is reduced to Secret he should not be able
|
46
|
+
to access “Top Secret” data any more." -- http://www.owasp.org/index.php/Guide_to_Authorization
|
47
|
+
|
48
|
+
* how I authenticated: for instance, 'logged in by cookie' << 'logged in by password'
|
49
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{restful_authentication}
|
5
|
+
s.version = "1.1.6"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["RailsJedi", "Rick Olson"]
|
9
|
+
s.date = %q{2009-12-09}
|
10
|
+
s.description = %q{This widely-used plugin provides a foundation for securely managing user.}
|
11
|
+
s.email = %q{railsjedi@gmail.com}
|
12
|
+
s.extra_rdoc_files = ["README.textile"]
|
13
|
+
s.files = ["CHANGELOG", "generators", "generators/authenticated", "generators/authenticated/authenticated_generator.rb", "generators/authenticated/lib", "generators/authenticated/lib/insert_routes.rb", "generators/authenticated/templates", "generators/authenticated/templates/_model_partial.html.erb", "generators/authenticated/templates/activation.erb", "generators/authenticated/templates/authenticated_system.rb", "generators/authenticated/templates/authenticated_test_helper.rb", "generators/authenticated/templates/controller.rb", "generators/authenticated/templates/features", "generators/authenticated/templates/features/accounts.feature", "generators/authenticated/templates/features/sessions.feature", "generators/authenticated/templates/features/step_definitions", "generators/authenticated/templates/features/step_definitions/ra_env.rb", "generators/authenticated/templates/features/step_definitions/user_steps.rb", "generators/authenticated/templates/helper.rb", "generators/authenticated/templates/login.html.erb", "generators/authenticated/templates/machinist_spec.rb", "generators/authenticated/templates/machinist_test.rb", "generators/authenticated/templates/mailer.rb", "generators/authenticated/templates/migration.rb", "generators/authenticated/templates/model.rb", "generators/authenticated/templates/model_controller.rb", "generators/authenticated/templates/model_helper.rb", "generators/authenticated/templates/model_helper_spec.rb", "generators/authenticated/templates/observer.rb", "generators/authenticated/templates/signup.html.erb", "generators/authenticated/templates/signup_notification.erb", "generators/authenticated/templates/site_keys.rb", "generators/authenticated/templates/spec", "generators/authenticated/templates/spec/blueprints", "generators/authenticated/templates/spec/blueprints/user.rb", "generators/authenticated/templates/spec/controllers", "generators/authenticated/templates/spec/controllers/access_control_spec.rb", "generators/authenticated/templates/spec/controllers/authenticated_system_spec.rb", "generators/authenticated/templates/spec/controllers/sessions_controller_spec.rb", "generators/authenticated/templates/spec/controllers/users_controller_spec.rb", "generators/authenticated/templates/spec/fixtures", "generators/authenticated/templates/spec/fixtures/users.yml", "generators/authenticated/templates/spec/helpers", "generators/authenticated/templates/spec/helpers/users_helper_spec.rb", "generators/authenticated/templates/spec/models", "generators/authenticated/templates/spec/models/user_spec.rb", "generators/authenticated/templates/tasks", "generators/authenticated/templates/tasks/auth.rake", "generators/authenticated/templates/test", "generators/authenticated/templates/test/functional_test.rb", "generators/authenticated/templates/test/mailer_test.rb", "generators/authenticated/templates/test/model_functional_test.rb", "generators/authenticated/templates/test/unit_test.rb", "generators/authenticated/USAGE", "lib", "lib/authentication", "lib/authentication/by_cookie_token.rb", "lib/authentication/by_password.rb", "lib/authentication.rb", "lib/authorization", "lib/authorization/aasm_roles.rb", "lib/authorization/stateful_roles.rb", "lib/authorization.rb", "lib/restful_authentication.rb", "lib/trustification", "lib/trustification/email_validation.rb", "lib/trustification.rb", "LICENSE", "notes", "notes/AccessControl.txt", "notes/Authentication.txt", "notes/Authorization.txt", "notes/RailsPlugins.txt", "notes/SecurityFramework.graffle", "notes/SecurityFramework.png", "notes/SecurityPatterns.txt", "notes/Tradeoffs.txt", "notes/Trustification.txt", "pkg", "Rakefile", "README.textile", "restful_authentication.gemspec", "TODO"]
|
14
|
+
s.homepage = %q{http://github.com/jeremydurham/restful-authentication}
|
15
|
+
s.rdoc_options = ["--main", "README.textile"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubygems_version = %q{1.3.5}
|
18
|
+
s.summary = %q{Generates code for user login and authentication}
|
19
|
+
|
20
|
+
if s.respond_to? :specification_version then
|
21
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
22
|
+
s.specification_version = 2
|
23
|
+
|
24
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
25
|
+
s.add_runtime_dependency(%q<rails>, ["~> 2.3.4"])
|
26
|
+
else
|
27
|
+
s.add_dependency(%q<rails>, ["~> 2.3.4"])
|
28
|
+
end
|
29
|
+
else
|
30
|
+
s.add_dependency(%q<rails>, ["~> 2.3.4"])
|
31
|
+
end
|
32
|
+
end
|