001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *  http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    
020    
021    package org.apache.geronimo.security.jaas;
022    
023    import java.security.Principal;
024    import java.util.HashSet;
025    import java.util.Map;
026    import java.util.Set;
027    
028    import javax.security.auth.Subject;
029    import javax.security.auth.callback.CallbackHandler;
030    import javax.security.auth.login.LoginException;
031    import javax.security.auth.spi.LoginModule;
032    
033    import org.apache.geronimo.security.DomainPrincipal;
034    import org.apache.geronimo.security.RealmPrincipal;
035    
036    /**
037     * @version $Revision: 554977 $ $Date: 2007-07-10 11:32:56 -0400 (Tue, 10 Jul 2007) $
038     */
039    public class WrappingLoginModule implements LoginModule {
040        public static final String CLASS_OPTION = WrappingLoginModule.class.getName() + ".LoginModuleClass";
041        public static final String DOMAIN_OPTION = WrappingLoginModule.class.getName() + ".DomainName";
042        public static final String REALM_OPTION = WrappingLoginModule.class.getName() + ".RealmName";
043        private String loginDomainName;
044        private String realmName;
045        private final Subject localSubject = new Subject();
046        private Subject subject;
047        private LoginModule delegate;
048    
049        public WrappingLoginModule() {
050        }
051    
052        public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
053            this.subject = subject;
054            Class lmClass = (Class) options.get(CLASS_OPTION);
055            try {
056                delegate = (LoginModule) lmClass.newInstance();
057            } catch (Exception e) {
058                throw new RuntimeException("Could not create login module instance", e);
059            }
060            delegate.initialize(localSubject, callbackHandler, sharedState, options);
061            loginDomainName = (String) options.get(DOMAIN_OPTION);
062            realmName = (String) options.get(REALM_OPTION);
063        }
064    
065        public boolean login() throws LoginException {
066            return delegate.login();
067        }
068    
069        public boolean abort() throws LoginException {
070            return delegate.abort();
071        }
072    
073        public boolean commit() throws LoginException {
074            boolean result = delegate.commit();
075    
076            Set<Principal> wrapped = new HashSet<Principal>();
077            for (Principal principal: localSubject.getPrincipals()) {
078                wrapped.add(new DomainPrincipal(loginDomainName, principal));
079                wrapped.add(new RealmPrincipal(realmName, loginDomainName, principal));
080            }
081            localSubject.getPrincipals().addAll(wrapped);
082            subject.getPrincipals().addAll(localSubject.getPrincipals());
083            subject.getPrivateCredentials().addAll(localSubject.getPrivateCredentials());
084            subject.getPublicCredentials().addAll(localSubject.getPublicCredentials());
085            return result;
086        }
087    
088        public boolean logout() throws LoginException {
089            boolean result = delegate.logout();
090    
091            subject.getPrincipals().removeAll(localSubject.getPrincipals());
092            localSubject.getPrincipals().clear();
093    
094            return result;
095        }
096    }