com.sun.enterprise.security.jmac.provider.config.PipeHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payara-micro Show documentation
Show all versions of payara-micro Show documentation
Micro Distribution of the Payara Project for IBM JDK
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.enterprise.security.jmac.provider.config;
import com.sun.xml.ws.api.server.WSEndpoint;
import java.net.URL;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.message.AuthException;
import javax.security.auth.message.AuthStatus;
import javax.security.auth.message.MessageInfo;
import javax.security.auth.message.config.ClientAuthConfig;
import javax.security.auth.message.config.ClientAuthContext;
import javax.security.auth.message.config.ServerAuthConfig;
import javax.security.auth.message.config.ServerAuthContext;
import javax.xml.ws.WebServiceException;
//import com.sun.ejb.Container;
//import com.sun.ejb.Invocation;
//import com.sun.enterprise.InvocationManager;
//import com.sun.enterprise.Switch;
import com.sun.enterprise.deployment.Application;
import com.sun.enterprise.deployment.BundleDescriptor;
import com.sun.enterprise.deployment.EjbDescriptor;
import com.sun.enterprise.deployment.ServiceReferenceDescriptor;
import com.sun.enterprise.deployment.WebBundleDescriptor;
import com.sun.enterprise.deployment.WebServiceEndpoint;
import org.glassfish.deployment.common.ModuleDescriptor;
import com.sun.enterprise.deployment.runtime.common.MessageSecurityBindingDescriptor;
import com.sun.enterprise.security.ee.audit.AppServerAuditManager;
//import com.sun.enterprise.security.audit.AuditManagerFactory;
import com.sun.enterprise.security.SecurityContext;
import com.sun.enterprise.security.SecurityServicesUtil;
import com.sun.enterprise.security.audit.AuditManager;
import com.sun.enterprise.security.ee.authorize.EJBPolicyContextDelegate;
import com.sun.enterprise.security.common.AppservAccessController;
import com.sun.enterprise.security.common.ClientSecurityContext;
import com.sun.enterprise.security.jmac.AuthMessagePolicy;
import com.sun.enterprise.security.webservices.PipeConstants;
//TODO: replace the one below with the one above later
import com.sun.enterprise.security.jmac.config.ConfigHelper;
import com.sun.enterprise.security.jmac.config.GFServerConfigProvider;
import com.sun.enterprise.security.jmac.config.HandlerContext;
import com.sun.enterprise.util.LocalStringManagerImpl;
import com.sun.enterprise.util.io.FileUtils;
import com.sun.xml.ws.api.EndpointAddress;
import com.sun.xml.ws.api.message.Messages;
import com.sun.xml.ws.api.message.Packet;
import com.sun.xml.ws.api.model.SEIModel;
import com.sun.xml.ws.api.model.wsdl.WSDLPort;
import com.sun.xml.ws.api.SOAPVersion;
import com.sun.xml.ws.api.WSBinding;
import com.sun.xml.ws.api.message.Message;
import com.sun.xml.ws.api.model.JavaMethod;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.UnmarshalException;
import javax.xml.ws.handler.MessageContext;
import org.glassfish.api.invocation.ComponentInvocation;
import org.glassfish.api.invocation.InvocationManager;
public class PipeHelper extends ConfigHelper {
private AppServerAuditManager auditManager = null;
//AuditManagerFactory.getAuditManagerInstance();
protected static final LocalStringManagerImpl localStrings =
new LocalStringManagerImpl(PipeConstants.class);
private boolean isEjbEndpoint;
private SEIModel seiModel;
private SOAPVersion soapVersion;
private InvocationManager invManager = null;
private EJBPolicyContextDelegate ejbDelegate = null;
public PipeHelper(String layer, Map map, CallbackHandler cbh) {
init(layer, getAppCtxt(map), map, cbh);
this.isEjbEndpoint = processSunDeploymentDescriptor();
this.seiModel = (SEIModel) map.get(PipeConstants.SEI_MODEL);
WSBinding binding = (WSBinding)map.get(PipeConstants.BINDING);
if (binding == null) {
WSEndpoint endPoint = (WSEndpoint)map.get(PipeConstants.ENDPOINT);
if (endPoint != null) {
binding = endPoint.getBinding();
}
}
this.soapVersion = (binding != null) ? binding.getSOAPVersion() : SOAPVersion.SOAP_11;
AuditManager am = (SecurityServicesUtil.getInstance() != null)
? SecurityServicesUtil.getInstance().getAuditManager()
: null;
auditManager = (am != null && (am instanceof AppServerAuditManager)) ? (AppServerAuditManager) am : new AppServerAuditManager();//workaround for standalone clients where no habitat
invManager = (SecurityServicesUtil.getInstance() != null)
? SecurityServicesUtil.getInstance().getHabitat().getService(InvocationManager.class) : null;
this.ejbDelegate = new EJBPolicyContextDelegate();
}
@Override
public ClientAuthContext getClientAuthContext(MessageInfo info, Subject s)
throws AuthException {
ClientAuthConfig c = (ClientAuthConfig)getAuthConfig(false);
if (c != null) {
addModel(info, map);
return c.getAuthContext(c.getAuthContextID(info),s,map);
}
return null;
}
@Override
public ServerAuthContext getServerAuthContext(MessageInfo info, Subject s)
throws AuthException {
ServerAuthConfig c = (ServerAuthConfig)getAuthConfig(true);
if (c != null) {
addModel(info, map);
addPolicy(info,map);
return c.getAuthContext(c.getAuthContextID(info),s,map);
}
return null;
}
public static Subject getClientSubject() {
Subject s = null;
if ((SecurityServicesUtil.getInstance() == null) || SecurityServicesUtil.getInstance().isACC()) {
ClientSecurityContext sc = ClientSecurityContext.getCurrent();
if (sc != null) {
s = sc.getSubject();
}
if (s == null) {
s = Subject.getSubject(AccessController.getContext());
}
} else {
SecurityContext sc = SecurityContext.getCurrent();
if (sc != null && !sc.didServerGenerateCredentials()) {
// make sure we don't use default unauthenticated subject,
// so that module cannot change this important (constant)
// subject.
s = sc.getSubject();
}
}
if (s == null) {
s = new Subject();
}
return s;
}
public void getSessionToken(Map m,
MessageInfo info,
Subject s) throws AuthException {
ClientAuthConfig c = (ClientAuthConfig) getAuthConfig(false);
if (c != null) {
m.putAll(map);
addModel(info, map);
c.getAuthContext(c.getAuthContextID(info),s,m);
}
}
public void authorize(Packet request) throws Exception {
// SecurityContext constructor should set initiator to
// unathenticated if Subject is null or empty
Subject s = (Subject) request.invocationProperties.get(PipeConstants.CLIENT_SUBJECT);
if (s == null || (s.getPrincipals().isEmpty() && s.getPublicCredentials().isEmpty())) {
SecurityContext.setUnauthenticatedContext();
} else {
SecurityContext sC = new SecurityContext(s);
SecurityContext.setCurrent(sC);
}
// we should try to replace this endpoint specific
// authorization check with a generic web service message check
// and move the endpoint specific check down stream
if (isEjbEndpoint) {
if (invManager == null){
throw new RuntimeException(localStrings.getLocalString("enterprise.webservice.noEjbInvocationManager",
"Cannot validate request : invocation manager null for EJB WebService"));
}
ComponentInvocation inv = (ComponentInvocation) invManager.getCurrentInvocation();
// one need to copy message here, otherwise the message may be
// consumed
if (ejbDelegate != null) {
ejbDelegate.setSOAPMessage(request.getMessage(), inv);
}
Exception ie;
Method m = null;
if (seiModel != null) {
JavaMethod jm = request.getMessage().getMethod(seiModel);
m = (jm != null) ? jm.getMethod() : null;
} else { // WebServiceProvider
WebServiceEndpoint endpoint = (WebServiceEndpoint) map.get(PipeConstants.SERVICE_ENDPOINT);
EjbDescriptor ejbDescriptor = endpoint.getEjbComponentImpl();
if (ejbDescriptor != null) {
final String ejbImplClassName = ejbDescriptor.getEjbImplClassName();
if (ejbImplClassName != null) {
try {
m = (Method) AppservAccessController.doPrivileged(new PrivilegedExceptionAction() {
@Override
public Object run() throws Exception {
ClassLoader loader =
Thread.currentThread().getContextClassLoader();
Class clazz =
Class.forName(ejbImplClassName, true, loader);
return clazz.getMethod("invoke",
new Class[]{Object.class });
}
});
} catch (PrivilegedActionException pae) {
throw new RuntimeException(pae.getException());
}
}
}
}
if (m != null) {
if (ejbDelegate != null) {
try {
if (!ejbDelegate.authorize(inv, m)) {
throw new Exception(localStrings.getLocalString("enterprise.webservice.methodNotAuth",
"Client not authorized for invocation of {0}",
new Object[]{m}));
}
} catch (UnmarshalException e) {
String errorMsg = localStrings.getLocalString("enterprise.webservice.errorUnMarshalMethod",
"Error unmarshalling method for ejb {0}",
new Object[]{ejbName()});
ie = new UnmarshalException(errorMsg);
ie.initCause(e);
throw ie;
} catch (Exception e) {
ie = new Exception(localStrings.getLocalString("enterprise.webservice.methodNotAuth",
"Client not authorized for invocation of {0}",
new Object[]{m}));
ie.initCause(e);
throw ie;
}
}
}
}
}
public void auditInvocation(Packet request, AuthStatus status) {
if (auditManager.isAuditOn()) {
String uri = null;
if (!isEjbEndpoint && request != null &&
request.supports(MessageContext.SERVLET_REQUEST)) {
HttpServletRequest httpServletRequest =
(HttpServletRequest)request.get(
MessageContext.SERVLET_REQUEST);
uri = httpServletRequest.getRequestURI();
}
String endpointName = null;
if (map != null) {
WebServiceEndpoint endpoint = (WebServiceEndpoint)
map.get(PipeConstants.SERVICE_ENDPOINT);
if (endpoint != null) {
endpointName = endpoint.getEndpointName();
}
}
if (endpointName == null) {
endpointName = "(no endpoint)";
}
if (isEjbEndpoint) {
auditManager.ejbAsWebServiceInvocation(
endpointName, AuthStatus.SUCCESS.equals(status));
} else {
auditManager.webServiceInvocation(
((uri==null) ? "(no uri)" : uri),
endpointName, AuthStatus.SUCCESS.equals(status));
}
}
}
public Object getModelName() {
WSDLPort wsdlModel = (WSDLPort) getProperty(PipeConstants.WSDL_MODEL);
return (wsdlModel == null ? "unknown" : wsdlModel.getName());
}
@Deprecated // should be unused, but left for compilation
public void addModelAndPolicy(Packet request) {
}
// always returns response with embedded fault
//public static Packet makeFaultResponse(Packet response, Throwable t) {
public Packet makeFaultResponse(Packet response, Throwable t) {
// wrap throwable in WebServiceException, if necessary
if (!(t instanceof WebServiceException)) {
t = (Throwable) new WebServiceException(t);
}
if (response == null) {
response = new Packet();
}
// try to create fault in provided response packet, if an exception
// is thrown, create new packet, and create fault in it.
try {
return response.createResponse(Messages.create(t, this.soapVersion));
} catch (Exception e) {
response = new Packet();
}
return response.createResponse(Messages.create(t, this.soapVersion));
}
public boolean isTwoWay(boolean twoWayIsDefault, Packet request) {
boolean twoWay = twoWayIsDefault;
Message m = request.getMessage();
if (m != null) {
WSDLPort wsdlModel =
(WSDLPort) getProperty(PipeConstants.WSDL_MODEL);
if (wsdlModel != null) {
twoWay = (m.isOneWay(wsdlModel) ? false : true);
}
}
return twoWay;
}
// returns empty response if request is determined to be one-way
public Packet getFaultResponse(Packet request, Packet response,
Throwable t) {
boolean twoWay = true;
try {
twoWay = isTwoWay(true,request);
} catch (Exception e) {
// exception is consumed, and twoWay is assumed
}
if (twoWay) {
return makeFaultResponse(response,t);
} else {
return new Packet();
}
}
@Override
public void disable() {
listenerWrapper.disableWithRefCount();
}
@Override
protected HandlerContext getHandlerContext(Map map) {
String realmName = null;
WebServiceEndpoint wSE = (WebServiceEndpoint)
map.get(PipeConstants.SERVICE_ENDPOINT);
if (wSE != null) {
Application app = wSE.getBundleDescriptor().getApplication();
if (app != null) {
realmName = app.getRealm();
}
if (realmName == null) {
realmName = wSE.getRealm();
}
}
final String fRealmName = realmName;
return new HandlerContext() {
@Override
public String getRealmName() {
return fRealmName;
}
};
}
private boolean processSunDeploymentDescriptor() {
if (factory == null) {
return false;
}
MessageSecurityBindingDescriptor binding =
AuthMessagePolicy.getMessageSecurityBinding
(PipeConstants.SOAP_LAYER,map);
if (binding != null) {
if (!hasExactMatchAuthProvider()) {
String jmacProviderRegisID = factory.registerConfigProvider(
new GFServerConfigProvider(null, null),
layer, appCtxt,
"GF AuthConfigProvider bound by Sun Specific Descriptor");
this.setJmacProviderRegisID(jmacProviderRegisID);
}
}
WebServiceEndpoint e = (WebServiceEndpoint)
map.get(PipeConstants.SERVICE_ENDPOINT);
return (e == null ? false : e.implementedByEjbComponent());
}
private static String getAppCtxt(Map map) {
String rvalue;
WebServiceEndpoint wse =
(WebServiceEndpoint) map.get(PipeConstants.SERVICE_ENDPOINT);
// endpoint
if (wse != null) {
rvalue = getServerName(wse) + " " + getEndpointURI(wse);
// client reference
} else {
ServiceReferenceDescriptor srd = (ServiceReferenceDescriptor)
map.get(PipeConstants.SERVICE_REF);
rvalue = getClientModuleID(srd) + " " + getRefName(srd,map);
}
return rvalue;
}
private static String getServerName(WebServiceEndpoint wse) {
//XXX FIX ME: need to lookup real hostname
String hostname = "localhost";
return hostname;
}
private static String getRefName(ServiceReferenceDescriptor srd, Map map) {
String name = null;
if (srd != null) {
name = srd.getName();
}
if (name == null) {
EndpointAddress ea =
(EndpointAddress) map.get(PipeConstants.ENDPOINT_ADDRESS);
if (ea != null) {
URL url = ea.getURL();
if (url != null) {
name = url.toString();
}
}
}
if (name == null) {
name = "#default-ref-name#";
}
return name;
}
private static String getEndpointURI(WebServiceEndpoint wse) {
String uri = "#default-endpoint-context#";
if (wse != null) {
uri = wse.getEndpointAddressUri();
if (uri != null && (!uri.startsWith("/"))) {
uri = "/" + uri;
}
if (wse.implementedByWebComponent()) {
WebBundleDescriptor wbd = (WebBundleDescriptor)
wse.getBundleDescriptor();
if (wbd != null) {
String contextRoot = wbd.getContextRoot();
if (contextRoot != null) {
if (!contextRoot.startsWith("/")) {
contextRoot = "/" + contextRoot;
}
uri = contextRoot + uri;
}
}
}
}
return uri;
}
private static String getClientModuleID(ServiceReferenceDescriptor srd) {
String rvalue = "#default-client-context#";
if (srd != null) {
ModuleDescriptor md = null;
BundleDescriptor bd = (BundleDescriptor) srd.getBundleDescriptor();
if (bd != null) {
md = bd.getModuleDescriptor();
}
Application a = (bd == null) ? null : bd.getApplication();
if (a != null) {
if (a.isVirtual()) {
rvalue = a.getRegistrationName();
} else if (md != null) {
rvalue = FileUtils.makeFriendlyFilename(md.getArchiveUri());
}
} else if (md != null) {
rvalue = FileUtils.makeFriendlyFilename(md.getArchiveUri());
}
}
return rvalue;
}
private static void addModel(MessageInfo info, Map map) {
Object model = map.get(PipeConstants.WSDL_MODEL);
if (model != null) {
info.getMap().put(PipeConstants.WSDL_MODEL,model);
}
}
private static void addPolicy(MessageInfo info, Map map) {
Object pol = map.get(PipeConstants.POLICY);
if (pol != null) {
info.getMap().put(PipeConstants.POLICY,pol);
}
}
private String ejbName() {
WebServiceEndpoint wSE = (WebServiceEndpoint)
getProperty(PipeConstants.SERVICE_ENDPOINT);
return (wSE == null ? "unknown" : wSE.getEjbComponentImpl().getName());
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy