Wednesday, April 08, 2009

Port attribute in HTTP Cookie

Recently, I have encountered a http session problem in jetty.
I start two Jetty instances on the same machine. These two jetty instances share the same base URL, but port numbers are different.
    http://example.com:8000/
    http://example.com:9000/
When I visit http://example.com:8000/, a cookie (called JSESSIONID) is set by the server automatically.
After that I visit the other URL http://example.com:9000/, the cookie set for http://example.com:8000/ is sent to the server by user agent. The the server gets confused :-(

After debugging it, I found the reason is that the server does NOT include port number in the Set-Cookie header. According to section 3.3.1 in RFC 2965, if the port attribute is missing in the Set-Cookie header, the user agent would react based on following description:

   Port    The default behavior is that a cookie MAY be returned to any
           request-port.

That means if a cookie is set for address A, the cookie also matches those addresses which share all the same URL components with A but port number.

For tomcat, I searched its email list
http://www.google.com/search?hl=en&client=firefox-a&rls=org.mozilla%3Aen-US%3Aofficial&q=cookie+port+site%3Ahttp%3A%2F%2Fmail-archives.apache.org%2Fmod_mbox%2Ftomcat-users%2F&btnG=Search
It seems that port number currently is not supported in cookie management.

Solution
(1) use different domain names which map to the same IP
(2) use different paths.
E.g.
    http://example.com:8000/webapp1
    http://example.com:9000/webapp2

Friday, April 03, 2009

OAuth + MyProxy integration prototype

Client

Client is the consumer of backend services.
Functionalities

  • A simple user management system
    Users can create new accounts, log in the system and log out the system.
  • Each user can upload her/his private key
  • For each backend service, the user can set his/her user id which is bound to the backend service.
    oauth_myproxy_consumer_uid_binding
    In above figure, the end user logins the client app as user "john". The client support accessing of three backend services. Then the user sets the binding of user id to each backend service. When the user wants to invoke backend service 1, the client app would set the user id to "mark" in the requests.

Service Provider

Functionalities of the service provider:

  • A simple user management system
  • Each user can bind a MyProxy account to his/her local account.
    The needed information of MyProxy account includes username, password, MyProxy server host and port number.
    Then the server would automatically retrieve a certificate chain from the specified MyProxy server. After parsing the certificate chain, public key of the original certificate that belongs to the user is extracted.
    Note: we don't use public key included the proxy certificate. There is just one original certificate stored in the MyProxy server while many proxy certificates can be acquired. Each time a new proxy certificate is requested, a new public/private key is created and the public key is sent to MyProxy server. Usually, this process is done by system automatically.
  • Each service could be accessed by various client applications. Users can set which client apps are allowed to access their data.

OAuth Integration

In OAuth authorization procedure, there are three main steps:

  1. Get a request token
  2. Ask user to authorize the request
  3. Exchange request token with an access token

Then the access token acquired in step (3) is used to access protected resources.
Trust relationship between client app and service provider is built out of band. Two mechanisms are supported: shared secret and RSA.
In my solution, step (2) is extended with step (1) and (3) staying the same. Two additional parameters are added: user_id and cgl_oauth_signagure. Parameter user_id is described here. The cgl_oauth_signature is calculated against user_id using the user's private key. After service provider receives the request, the corresponding public key (retrieved from MyProxy server) is used to verify the signature.

Future Work

  1. Revoke the authorized privileges
    1. Users can set an expiration time after which the access token will become invalid. Then the whole OAuth authorization process must be executed once again.
    2. Provides a way for user to revoke authorized privileges at any time they like.
  2. Trust relationship establishment.
    Developers of client apps go to specified web page of the service provider to apply for development account. Then one of the following two things happens:
    • A shared secret would be generated automatically and copied to the corresponding client app.
    • The developers of the client apps upload their certificate to backend service.