Re: Switching basic auth to client-cert with realms - how?

2015-03-13 Thread Neven Cvetkovic
Graham,

On Fri, Mar 13, 2015 at 3:39 PM, Graham Leggett minf...@sharp.fm wrote:

 Hi all,

 I have a basic authentication setup that works great as below.

 login-config
 auth-methodBASIC/auth-method
 realm-namePatricia/realm-name
 /login-config

 !-- Security roles referenced by this web application --
 security-role
 role-nameadministrator/role-name
 /security-role
 security-role
 role-nameunderwriter/role-name
 /security-role
 security-role
 role-nameaccountant/role-name
 /security-role
 security-role
 role-namebroker/role-name
 /security-role
 security-role
 role-namefeeds/role-name
 /security-role

 It is backed up with a realm like this:

   Realm className=“org.apache.catalina.realm.DataSourceRealm
  [snip]
  userTable=person userNameCol=mail
  userCredCol=user_password
  userRoleTable=company_person roleNameCol=serial /

 I need to switch basic authentication to client certificates, as provided
 by Apache httpd and proxied in with AJP. The username is provided by Apache
 httpd in REMOTE_USER.

 In theory, changing the auth-method to CLIENT-CERT should do the trick,
 but I just get forbidden.

 What doesn’t seem to fit is the realm definition - specifying userCredCol
 is marked as mandatory, but this is obviously not present with a client
 certificate. What do you specify in this field?

 Does anyone have a working example of authentication using client
 certificates and authorization using a realm backed with a DataSource?


Here's a nice article, detailing how to add CLIENT-CERT:
http://java.dzone.com/articles/enabling-client-cert-based

It is based on MemoryRealm, not DataSourceRealm, but the idea is similar.

Here's a summary:

1. You need to define user/pass/roles:

role rolename=secureconn/
user username=CN=client1, OU=Application Development, O=GoSmarter,
L=Bangalore, ST=KA, C=IN password=null  roles=secureconn/

2. You define in web.xml the login type:
login-config
auth-methodCLIENT-CERT/auth-method
realm-nameDemo App/realm-name
/login-config

You would get a 403 if an invalid certificate is sent based on the security
constraints you set earlier.

Ultimately, you need to turn on extra logging on that realm so you would
know why the 403s were generated.

Try doing some online searching for the type of errors you got. Here's what
pops up in my quick google search:
http://stackoverflow.com/questions/5086457/setting-up-client-cert-authentication-with-roles-on-tomcat-6-0

This person had an issue how CNs were handled, and as a result extra
inserted spaces between commas, e.g.
(1) no spaces: CN=testuser,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU
(2) with spaces: CN=testuser, O=Internet Widgits Pty Ltd, ST=Some-State,
C=AU

The issue was how X509Principal.getName() call returned:
X500Principal.RFC2253
X500Principal.RFC1779

Let us know what you find by turning on extra logging.

Cheers!
Neven


Re: Switching basic auth to client-cert with realms - how?

2015-03-13 Thread Neven Cvetkovic
Graham,

On Fri, Mar 13, 2015 at 3:39 PM, Graham Leggett minf...@sharp.fm wrote:

 What doesn’t seem to fit is the realm definition - specifying userCredCol
 is marked as mandatory, but this is obviously not present with a client
 certificate. What do you specify in this field?


You define the password column, which could have NULL values now, since we
don't use passwords anymore.



 Does anyone have a working example of authentication using client
 certificates and authorization using a realm backed with a DataSource?



 Try doing some online searching for the type of errors you got. Here's
 what pops up in my quick google search:

 http://stackoverflow.com/questions/5086457/setting-up-client-cert-authentication-with-roles-on-tomcat-6-0


Here's another interesting article that tackles the old version of Tomcat,
but the ideas are very similar. Here's a link:
http://stackoverflow.com/questions/163113/can-client-cert-auth-method-be-used-with-a-jdbc-realm-within-tomcat

Summary:

User Names
The user name column should contain the certificate subject's distinguished
name, as a character string. Unfortunately, the method Tomcat uses to
obtain this string produces an implementation-dependent result, so it's
possible if you were to switch to a new security provider or even just
upgrade your Java runtime, you might need to map your user names to a new
form. You'll have to test your deployment to find out what format is used.

Specifically, getName() is called on the Principal returned by
X509Certificate.getSubjectDN() to obtain a String, which is used as the
user name. If you read the documentation, you'll find that this is no
longer the best approach.

Authentication
The simplest set up would be to load your trust anchors into Tomcat's trust
store, which is configured in the server.xml file. With this setup, any
client certificate chain that is root in one of your trusted CAs will be
considered authenticated, and rightly so—authentication means that an
identity is known, and is distinct from authorization, which determines
what that identity is allowed to do.

Authorization
Since anyone with a signed certificate will be authenticated, you need to
set up roles in order to protect private resources in your application.
This is done by setting up security constraints, associated with roles, in
your web.xml file. Then, in your database, populate the roles table to
grant trusted users with extra roles.

The relationship between the user table and the roles table works exactly
as it would with FORM-based authorization, and should be utilized to grant
appropriate permissions to users that you trust.

A Note on Passwords
The JDBCRealm will create a new Principal, which does carry a password, but
unless your application downcasts this Principal to the Tomcat-specific
implementation (GenericPrincipal), this property won't be visible to you,
and it doesn't really matter what you put in that column. I recommend NULL.

In other words, when using JDBCRealm with client-auth, the password field
is ignored. This GenericPrincipal has a method to access an underlying
principal, but unfortunately, the Principal from the certificate is not
passed along; the JDBCRealm will set it to null; the only useful method in
this scenario might be getName() (returning the subject DN is some possibly
non-standard form).

Table Structure and Content
Use exactly the same table structure you would for a FORM-based JDBCRealm
(or DatasourceRealm). The only difference will be in the content. The user
name will be a text representation of the subject distinguished name, and
the password will be NULL or some dummy value.

I don't know how much of it is still relevant in Tomcat7/Tomcat8.

By the way, what platform, what JVM and what version of Tomcat do you run?

Hope that helps!

Cheers!
Neven


Re: Switching basic auth to client-cert with realms - how?

2015-03-13 Thread Graham Leggett
On 13 Mar 2015, at 10:34 PM, Neven Cvetkovic neven.cvetko...@gmail.com wrote:

 What doesn’t seem to fit is the realm definition - specifying userCredCol
 is marked as mandatory, but this is obviously not present with a client
 certificate. What do you specify in this field?
 
 
 You define the password column, which could have NULL values now, since we
 don't use passwords anymore.

I don’t follow, do you mean I shouldn’t define the password column?

 Here's another interesting article that tackles the old version of Tomcat,
 but the ideas are very similar. Here's a link:
 http://stackoverflow.com/questions/163113/can-client-cert-auth-method-be-used-with-a-jdbc-realm-within-tomcat

I’ve already found all of these, and have trawled through them to no avail. It 
appears all the information is stale.

I am currently stuck on two specific areas:

- None of the debug logging seems to work any more in any kind of predictable 
fashion, as detailed in my other message.
- Turning on SQL statement logging in postgres shows that at no point is any 
SQL statement executed against the database.

If I had some kind of meaningful error that accompanied the 403 it would be a 
huge help.

Is anyone able to confirm where I might place a breakpoint to step through the 
tomcat code?

Regards,
Graham
—


-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Switching basic auth to client-cert with realms - how?

2015-03-13 Thread Graham Leggett
Hi all,

I have a basic authentication setup that works great as below.

login-config
auth-methodBASIC/auth-method
realm-namePatricia/realm-name
/login-config

!-- Security roles referenced by this web application --
security-role
role-nameadministrator/role-name
/security-role
security-role
role-nameunderwriter/role-name
/security-role
security-role
role-nameaccountant/role-name
/security-role
security-role
role-namebroker/role-name
/security-role
security-role
role-namefeeds/role-name
/security-role

It is backed up with a realm like this:

  Realm className=“org.apache.catalina.realm.DataSourceRealm
 [snip]
 userTable=person userNameCol=mail
 userCredCol=user_password
 userRoleTable=company_person roleNameCol=serial /

I need to switch basic authentication to client certificates, as provided by 
Apache httpd and proxied in with AJP. The username is provided by Apache httpd 
in REMOTE_USER.

In theory, changing the auth-method to CLIENT-CERT should do the trick, but I 
just get forbidden.

What doesn’t seem to fit is the realm definition - specifying userCredCol is 
marked as mandatory, but this is obviously not present with a client 
certificate. What do you specify in this field?

Does anyone have a working example of authentication using client certificates 
and authorization using a realm backed with a DataSource?

Regards,
Graham
—


-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: Switching basic auth to client-cert with realms - how?

2015-03-13 Thread Neven Cvetkovic
Graham,

On Fri, Mar 13, 2015 at 4:49 PM, Graham Leggett minf...@sharp.fm wrote:

 On 13 Mar 2015, at 10:34 PM, Neven Cvetkovic neven.cvetko...@gmail.com
 wrote:

  What doesn’t seem to fit is the realm definition - specifying
 userCredCol
  is marked as mandatory, but this is obviously not present with a client
  certificate. What do you specify in this field?
 
 
  You define the password column, which could have NULL values now, since
 we
  don't use passwords anymore.

 I don’t follow, do you mean I shouldn’t define the password column?


According to my understanding - password field will be irrelevant. Since we
use certificates to authenticate, not username/password combo. Thus, keep
the field as is.


  Here's another interesting article that tackles the old version of
 Tomcat,
  but the ideas are very similar. Here's a link:
 
 http://stackoverflow.com/questions/163113/can-client-cert-auth-method-be-used-with-a-jdbc-realm-within-tomcat

 I’ve already found all of these, and have trawled through them to no
 avail. It appears all the information is stale.

 Yes, indeed - most of the info on these pages is very stale. Once we
resolve it, we should add a nice article about this, and add to Tomcat Wiki
:)))


 I am currently stuck on two specific areas:

 - None of the debug logging seems to work any more in any kind of
 predictable fashion, as detailed in my other message.


From your other log files (your last email in the other thread) - it seems
your pages are not secured at all, e.g.
FINE:  Not subject to any constraint

Do you have security-constraint defined in your web.xml?


 - Turning on SQL statement logging in postgres shows that at no point is
 any SQL statement executed against the database.


Well, we are not hitting the database yet, as secured page was not hit yet
- just unsecured / - judging from your provided log files.

That's why I would first make sure the logging does work properly with the
other login method (BASIC/FORM), just to make sure you can see stuff being
logged.

Then you can switch to new CLIENT-CERT, and troubleshoot the problem.


 If I had some kind of meaningful error that accompanied the 403 it would
 be a huge help.

 Is anyone able to confirm where I might place a breakpoint to step through
 the tomcat code?


I would try constructors on RealmBase, AuthenticatorBase base classes or
their derived subclasses, e.g. BasicAuthenticator, SSLAuthenticator,
DataSourceRealm.

Try also - the authenticate() method on the DataSourceRealm ... that's
probably going to be called at some point :))

Hope that helps!

Cheers!
Neven