001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.servicemix.cxfbc.interceptors;
018    
019    import java.security.GeneralSecurityException;
020    import java.util.Iterator;
021    import java.util.List;
022    import java.util.Vector;
023    
024    import javax.security.auth.Subject;
025    
026    import org.apache.cxf.binding.soap.SoapMessage;
027    import org.apache.cxf.interceptor.Fault;
028    import org.apache.cxf.phase.Phase;
029    import org.apache.cxf.ws.security.wss4j.AbstractWSS4JInterceptor;
030    import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
031    import org.apache.servicemix.jbi.security.auth.AuthenticationService;
032    import org.apache.ws.security.WSSecurityEngineResult;
033    import org.apache.ws.security.WSUsernameTokenPrincipal;
034    import org.apache.ws.security.handler.WSHandlerConstants;
035    import org.apache.ws.security.handler.WSHandlerResult;
036    
037    public class JbiJAASInterceptor extends AbstractWSS4JInterceptor {
038    
039        private String domain = "servicemix-domain";
040        private AuthenticationService authenticationService;
041        private ThreadLocal<Subject> currentSubject = new ThreadLocal<Subject>();
042        
043        
044        public JbiJAASInterceptor(AuthenticationService authenticationService) {
045            super();
046            setPhase(Phase.PRE_PROTOCOL);
047            getAfter().add(WSS4JInInterceptor.class.getName());
048            this.authenticationService = authenticationService;
049        }
050        
051        
052        public void handleMessage(SoapMessage message) throws Fault {
053         
054            try {
055                
056                Subject subject = (Subject) currentSubject.get();
057                
058                if (subject == null) {
059                    subject = new Subject();
060                    currentSubject.set(subject);
061                }
062                List<Object> results = (Vector<Object>)message.get(WSHandlerConstants.RECV_RESULTS);
063                if (results == null) {
064                    return;
065                }
066                for (Iterator iter = results.iterator(); iter.hasNext();) {
067                    WSHandlerResult hr = (WSHandlerResult) iter.next();
068                    if (hr == null || hr.getResults() == null) {
069                        return;
070                    }
071                    for (Iterator it = hr.getResults().iterator(); it.hasNext();) {
072                        WSSecurityEngineResult er = (WSSecurityEngineResult) it.next();
073                            
074                        if (er != null && er.getPrincipal() instanceof WSUsernameTokenPrincipal) {
075                            WSUsernameTokenPrincipal p = (WSUsernameTokenPrincipal)er.getPrincipal();
076                            subject.getPrincipals().add(p);
077                            this.authenticationService.authenticate(subject, domain, p.getName(), p.getPassword());
078                        }
079                    }
080                }
081                
082                message.put(Subject.class, subject);
083            } catch (GeneralSecurityException e) {
084                throw new Fault(e);
085            } finally {
086                currentSubject.set(null);
087            }
088        }
089    
090    }