jersey
  1. jersey
  2. JERSEY-1160

Initialize SecurityContext for client-authenticated SSL connection

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.12
    • Fix Version/s: 2.0-m07
    • Component/s: containers
    • Labels:
      None

      Description

      Please modify GrizzlyContainer to initialize the ContainerRequest's SecurityContext with client identity from the SSL layer if available before handing it off to the WebApplication.

      I am using jersey-grizzly2 to implement a RESTful interface for my service. Having configured the Grizzly layer to require client authentication, I find there's no straight-forward (or even round-about) way to access that information at the Jersey level.

      Here's an example solution implemented in GrizzlyContainer._service():

                  final ContainerRequest cRequest = new ContainerRequest(_application,
                          request.getMethod().getMethodString(), baseUri, requestUri,
                          getHeaders(request), request.getInputStream());
                  
      // === begin new code ===
                  SSLEngine ssl = SSLUtils.getSSLEngine(request.getContext().getConnection());
                  if (ssl != null) {
                  	try {
                  		final Principal p = ssl.getSession().getPeerPrincipal();
                  		cRequest.setSecurityContext(new SecurityContext() {
                  			@Override
                  			public Principal getUserPrincipal() {
                  				return p;
                  			}
                  			@Override
                  			public boolean isUserInRole(String role) {
                  				return false;
                  			}
                  			@Override
                  			public boolean isSecure() {
                  				return true;
                  			}
                  			@Override
                  			public String getAuthenticationScheme() {
                  				return SecurityContext.CLIENT_CERT_AUTH;
                  			}
                  		});
                  	} 
                  	catch(SSLPeerUnverifiedException ex) {
                  		// no client certs
                  	}
                  }
      // === end new code ===
       
                  _application.handleRequest(cRequest, new Writer(response));
      

        Issue Links

          Activity

          Hide
          Pavel Bucek added a comment -

          there should be a workaround (not tested):

          you should be able to inject (into @Context annotated method param for example) Grizzly request and basically do what you are doing in proposed patch.

          Show
          Pavel Bucek added a comment - there should be a workaround (not tested): you should be able to inject (into @Context annotated method param for example) Grizzly request and basically do what you are doing in proposed patch.
          Hide
          CLarrieu added a comment -

          I developed a work-around that depends upon a single thread of execution from Grizzly filter chain up through the jersey level. Here's how I describe it in my code:

          /**

          • This is part of a nasty hack that is needed to propagate the SSL-provided client
          • identity up from the Grizzly layer to the Jersey level.
          • The client identity is extracted from the Grizzly Request object and stored in a thread-local
          • variable for retrieval when filter() is run after the Jersey ContainerRequest has been
          • created but before the resource method has been invoked.
          • The only guarantee that both tasks will occur in the same thread is that the source code
          • for the current version (1.12) operates this way.
          • Hopefully the jersey-grizzly2 project will accept my patch (http://java.net/jira/browse/JERSEY-1160)
          • to make this hack unnecessary.
          • @author larrieu
            *
            */
          Show
          CLarrieu added a comment - I developed a work-around that depends upon a single thread of execution from Grizzly filter chain up through the jersey level. Here's how I describe it in my code: /** This is part of a nasty hack that is needed to propagate the SSL-provided client identity up from the Grizzly layer to the Jersey level. The client identity is extracted from the Grizzly Request object and stored in a thread-local variable for retrieval when filter() is run after the Jersey ContainerRequest has been created but before the resource method has been invoked. The only guarantee that both tasks will occur in the same thread is that the source code for the current version (1.12) operates this way. Hopefully the jersey-grizzly2 project will accept my patch ( http://java.net/jira/browse/JERSEY-1160 ) to make this hack unnecessary. @author larrieu * */
          Hide
          Pavel Bucek added a comment -

          already fixed in Jersey 2.x.

          Show
          Pavel Bucek added a comment - already fixed in Jersey 2.x.

            People

            • Assignee:
              Pavel Bucek
              Reporter:
              CLarrieu
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: