users@grizzly.java.net

Re: What does Grizzly report for GrizzlyRequest.getPrincipal

From: Tim Quinn <tim.quinn_at_oracle.com>
Date: Tue, 22 Jun 2010 06:25:45 -0500

[Alexey and I have been discussing this off-line; it makes sense to
talk about it more broadly - hence I'm moving it to the list.

My original question was whether GrizzlyRequest.getUserPrincipal
returns the security Principal that was authenticated if the
connection uses client certificate authentication, or if not how the
adapter could find that out.

Alexey pointed me to some of the code in the web container that does
this. ]


I know that client authentication is relatively rarely used, but this
seems like something that any adapter that does use client
authentication might need.

Any chance of Grizzly doing this for us rather than each individual
adapter having to do so for itself?

Thanks.

- Tim

On Jun 22, 2010, at 4:41 AM, Oleksiy Stashok wrote:

> Hi Tim,
>
> I found some code in web container, which you can use [1].
>
> IMO instead of cc'ing more people we can move discussions to grizzly
> mailing list, if it's fine for you?
>
> Thanks.
>
> WBR,
> Alexey.
>
> [1]
>
> --------- Constants:
>
> /**
> * SSL Certificate Request Attributite.
> */
> public static final String SSL_CERTIFICATE_ATTR =
> "org.apache.coyote.request.X509Certificate";
>
> /**
> * The request attribute under which we store the array of
> X509Certificate
> * objects representing the certificate chain presented by our
> client,
> * if any.
> */
> public static final String CERTIFICATES_ATTR =
> "javax.servlet.request.X509Certificate";
>
>
> -------------- Getting X509Certificates
>
>
> X509Certificate certs[] = (X509Certificate[])
> request.getAttribute(Globals.CERTIFICATES_ATTR);
> if ((certs == null) || (certs.length < 1)) {
> certs = (X509Certificate[])
> request.getAttribute(Globals.SSL_CERTIFICATE_ATTR);
> }
> if ((certs == null) || (certs.length < 1)) {
> if (debug >= 1)
> log(" No certificates included with this request");
> return (false);
> }
>
> // Authenticate the specified certificate chain
> principal = authenticate(certs);
>
> ----------- authenticate
>
> /**
> * Return the Principal associated with the specified chain of
> X509
> * client certificates. If there is none, return <code>null</
> code>.
> *
> * @param certs Array of client certificates, with the first one
> in
> * the array being the certificate of the client itself.
> */
> public Principal authenticate(X509Certificate certs[]) {
>
> if ((certs == null) || (certs.length < 1))
> return (null);
>
> // Check the validity of each certificate in the chain
> if (log.isLoggable(Level.FINE))
> log.fine("Authenticating client certificate chain");
> if (validate) {
> for (int i = 0; i < certs.length; i++) {
> if (log.isLoggable(Level.FINE))
> log.fine("Checking validity for '" +
> certs[i].getSubjectDN().getName() + "'");
> try {
> certs[i].checkValidity();
> } catch (Exception e) {
> if (log.isLoggable(Level.FINE))
> log.log(Level.FINE, "Validity exception", e);
> return (null);
> }
> }
> }
>
> // Check the existence of the client Principal in our database
> return (getPrincipal(certs[0].getSubjectDN().getName()));
> }
>
>
> On Jun 21, 2010, at 16:04 , Tim Quinn wrote:
>
>> Hi, Alexey.
>>
>>
>> On Jun 21, 2010, at 7:39 AM, Oleksiy Stashok wrote:
>>
>>> Hi Tim,
>>>
>>> I worry that Grizzly just has get/set methods for Principal, but
>>> AFAIK the actual implementation, which uses Grizzly should take
>>> care of setting it appropriate way.
>>> I don't see any code in Grizzly, which sets that.
>>> What is the usecase you have?
>>
>> First, I apologize -- it's getUserPrincipal not getPrincipal.
>>
>> The use case:
>>
>> In GF 3.1 we are planning to use SSL mutual certificate
>> authentication to secure the admin messages between the DAS and
>> instances in the domain (if the user chooses to use admin security).
>>
>> The SSL layer will make sure that the other end of the connection
>> has identified itself in a way that we trust (that is, it presents
>> a certificate we trust). But the Grizzly adapter which processes
>> the incoming admin requests still needs to make sure that whatever
>> that identity is has been authorized in the DAS as an
>> administrator. Since that identity is established at the SSL level
>> I thought (was hoping) that req.getUserPrincipal would return a
>> Principal for the certificate that had been presented by the other
>> end of the connection.
>>
>> I now see the setUserPrincipal method also which I did not notice
>> before.
>>
>> My real need is that a Grizzly adapter's service method needs to be
>> able to find out if SSL client cert. authentication was used (which
>> includes mutual auth) in establishing the incoming connection and,
>> if so, what identify was given by the cert that was trusted.
>>
>> I thought maybe the req.getSession() might have a way to lead me to
>> the SSLSession which has getPeerPrincipal which I think would give
>> the admin adapter what it needs, but I couldn't find a way from the
>> Grizzly request object to the SSLSession.
>>
>> By the way, should I include anyone else on these sorts of
>> questions? Justin?
>>
>> Many thanks.
>>
>> - Tim
>>
>>
>>
>>
>>>
>>> Thanks.
>>>
>>> WBR,
>>> Alexey.
>>>
>>>
>>> On Jun 19, 2010, at 0:47 , Tim Quinn wrote:
>>>
>>>> Hi, Alexey. I hope this is a quick question.
>>>>
>>>> Is the Principal returned by GrizzlyRequest.getPrincipal valid
>>>> only if I've configured the port for SSL and for client
>>>> authentication?
>>>>
>>>> Thanks.
>>>>
>>>> - Tim
>>>>
>>>>
>>>>
>>>>
>>>>
>