Detailed Response here:-
On 09/22/2011 04:23 PM, Bill Burke wrote:
I'll try to write a blog about this too, but, the security
APIs/SPIs
really need a rethink. Originally, the whole security-domain concept,
and Tomcat Realm centered around passwords or an X509Certificate (for
client cert). Passwords alone basically suck for security. We use a
soft or hard token for our VPN, why wouldn't we use something similar
for JBoss-deployed applications?
Security domain is just an abstract concept to pool in together
authentication/authorization/mapping/audit mechanisms etc. There is no
coupling to passwords.
There's all different kinds of information that needs to be
stored in a
security-domain now:
- passwords
- hashed passwords
- secret-keys (for TOTP, soft-tokens)
- remembering nonces (Digest and OAuth come to mind hear)
- remember request and access tokens (Think OAuth)
- URLs (Think OpenID)
- KeyPairs when you're dealing with digital signatures or client
certificate authentication
- JPG images. Think of Bank of America that shows you a secret
image
when you log in so that you know somebody isn't spoofing their site.
This is a
variant of "Knowledge based authentication" which gives an
additional layer of security rather than an additional factor of
authentication.
- Client IP addresses for when you want to tie a user to a client IP
Our legacy APIs/SPIs worked nicely because, since everything was
password based, the Security-Domain could also do authentication.
Extract the username/password from the HTTP request (or remote EJB
request) and just check it vs. the password storage. Now though,
there's a growing set of protocols that need access to the HTTP request
itself, especially if the request is digitally signed in some manner,
and the line between the protocol and security-domain starts to really blur.
Just write a Tomcat authenticator. You don't have to go through the
context/realm or any of the heartburning issues you have.
Another huge problem with our security SPIs is that LoginModules are
stateless. There's really no way, other than hacks, to point it at
specific storage so it can do things like: remember nonces, temporary
secrets or certificates, previous IP address connections.
Yet another that I think may come up is dual-authentication mechanisms
for the same resources (URLs). A regular user may query the site via
traditional authentication vs. a 3rd party consumer which uses OAuth.
With our current WAR/web.xml model, you can only use one or the other.
The final problem I'm currently seeing is that its hard to re-use the
storage capabilities of our security plugins (.properites, ldap, JDBC,
etc.). What you currently have is a mish-mash of weird, hard-to extend
class hierarchies with no clear line between storage of information and
the algorithm being used and the process of authentication and
authorization. If we're going to support more complex models, we need
to create better SPIs here.
So what to do?
#1 I suggest defining a Security Storage SPI. Something that is
key/value/values based that is listable. i.e. something like:
interface SecurityStore {
public Object get(String key);
public List<Object> list(String key);
public void put(String key, Object value);
public void put(String key, List<Object> value);
}
A key would look like a URL i.e.:
/users
/users/bill
/users/bill/private-key
/users/bill/public-key
/users/bill/password
/users/bill/totp-key
/applications/myapp
/applications/myapp/roles
/applications/myapp/roles/admin
/applications/myapp/roles/admin/users
/applications/myapp/roles/admin/users/bill
The the security store could be mapped to a properties file, XML file,
LDAP storage, JDBC, etc.
Whether or not we use an existing thing here i.e. Infinispan, JCR, or
whatever is irrelevant, but we need a simple generic storage mechanism
to give ultimate flexibility to security extension developers. Some
suggestions on what to use for this mechanism would be greatly appreciated.
Please influence the PicketLink IDM project. That is where the security
store api needs to be refined to your needs.
#2 Deprecate JAAS and write our own SPIs/APIs.
Agree on this. JAAS is cumbersome for developers.
#3 Decide where authentication happens. Does it happen within a
Tomcat
Valve and persistent security information queried directly from the
SecurityStore? Do we have a Security domain and delegate to it for
authentication? (In this case, the Security-Domain would need access to
the request object). I think I prefer a full delegation to a
SecurityDomain as storage, the authentication mechanism, and
configuration of the authentication mechanism pretty much go hand in hand.
You came
back to the security domain/realm abstraction.
#4 We need to make it fairly easy to develop security extensions.
#5 Try to support legacy deployment options with the new model.
#6 Going along with #3, I really like the idea of adding a<auth-method>
of JBOSS, or JBOSS-SECURITY-DOMAIN, so that authentication is handling
fully by a JBoss subsystem.
I mentioned about writing your own authenticator. You
can use that to
short circuit the JBoss Web security infrastructure.