blob: d078a782d2fe0b7565d04de0f605fca279fefb5f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 BSI Business Systems Integration AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Daniel Wiehl (BSI Business Systems Integration AG) - initial API and implementation
******************************************************************************/
package org.eclipse.scout.jaxws;
import java.io.IOException;
import java.security.AccessController;
import java.security.Principal;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import javax.security.auth.Subject;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.eclipse.scout.jaxws.internal.servlet.EndpointServlet;
import org.eclipse.scout.jaxws.security.provider.IAuthenticationHandler;
import org.eclipse.scout.rt.server.commons.servletfilter.ServletFilterDelegate;
/**
* Runs the request in a Subject context.
* Soap handlers may add {@link Principal}'s to {@link Subject#getSubject(java.security.AccessControlContext)}
*
* @see {@link Subject#doAs(Subject, java.security.PrivilegedAction)}.
* @see {@link IAuthenticationHandler}.
*/
public class JaxWsServlet extends EndpointServlet {
private static final long serialVersionUID = 1L;
@Override
public final void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
new ServletFilterDelegate().delegateServiceMethod(req, res, new ServletFilterDelegate.IServiceCallback() {
@Override
public void service(final ServletRequest reqInner, final ServletResponse resInner) throws ServletException, IOException {
/*
* The request can be authenticated in two ways:
* 1. By the application server itself or a previous filter.
* In such situation, we are already running in a respective doAs call which implies that the subject obtained
* is not null and contains one principal at minimum.
* 2. By a subsequent {@link IAuthenticationHandler} handler.
* This is if the subject is null or there is no principal associated yet.
* If the current subject is null or readonly, a new one is created.
*/
Subject subject = Subject.getSubject(AccessController.getContext());
if (subject == null || subject.getPrincipals().size() == 0) {
// request is not authenticated yet
if (subject == null || subject.isReadOnly()) {
subject = new Subject(); // precondition that subject is set
}
try {
Subject.doAs(subject, new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
JaxWsServlet.super.service(reqInner, resInner);
return null;
}
});
}
catch (PrivilegedActionException e) {
if (e.getCause() instanceof ServletException) {
throw (ServletException) e.getCause();
}
else if (e.getCause() instanceof IOException) {
throw (IOException) e.getCause();
}
else {
throw new IOException("Wrapped", e);
}
}
}
else {
// request is already authenticated
JaxWsServlet.super.service(reqInner, resInner);
}
}
@Override
public ServletContext getServletContext() {
return JaxWsServlet.this.getServletContext();
}
});
}
}