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.activemq.security;
018    
019    import java.security.Principal;
020    import java.util.HashSet;
021    import java.util.Map;
022    import java.util.Set;
023    
024    import org.apache.activemq.broker.Broker;
025    import org.apache.activemq.broker.ConnectionContext;
026    import org.apache.activemq.command.ConnectionInfo;
027    import org.apache.activemq.jaas.GroupPrincipal;
028    
029    /**
030     * Handles authenticating a users against a simple user name/password map.
031     */
032    public class SimpleAuthenticationBroker extends AbstractAuthenticationBroker {
033    
034        private boolean anonymousAccessAllowed = false;
035        private String anonymousUser;
036        private String anonymousGroup;
037        private final Map<String,String> userPasswords;
038        private final Map<String,Set<Principal>> userGroups;
039    
040        public SimpleAuthenticationBroker(Broker next, Map<String,String> userPasswords, Map<String,Set<Principal>> userGroups) {
041            super(next);
042            this.userPasswords = userPasswords;
043            this.userGroups = userGroups;
044        }
045    
046        public void setAnonymousAccessAllowed(boolean anonymousAccessAllowed) {
047            this.anonymousAccessAllowed = anonymousAccessAllowed;
048        }
049    
050        public void setAnonymousUser(String anonymousUser) {
051            this.anonymousUser = anonymousUser;
052        }
053    
054        public void setAnonymousGroup(String anonymousGroup) {
055            this.anonymousGroup = anonymousGroup;
056        }
057    
058        @Override
059        public void addConnection(ConnectionContext context, ConnectionInfo info) throws Exception {
060    
061            SecurityContext s = context.getSecurityContext();
062            if (s == null) {
063                // Check the username and password.
064                if (anonymousAccessAllowed && info.getUserName() == null && info.getPassword() == null) {
065                    info.setUserName(anonymousUser);
066                    s = new SecurityContext(info.getUserName()) {
067                        @Override
068                        public Set<Principal> getPrincipals() {
069                            Set<Principal> groups = new HashSet<Principal>();
070                            groups.add(new GroupPrincipal(anonymousGroup));
071                            return groups;
072                        }
073                    };
074                } else {
075                    String pw = userPasswords.get(info.getUserName());
076                    if (pw == null || !pw.equals(info.getPassword())) {
077                        throw new SecurityException(
078                                "User name [" + info.getUserName() + "] or password is invalid.");
079                    }
080    
081                    final Set<Principal> groups = userGroups.get(info.getUserName());
082                    s = new SecurityContext(info.getUserName()) {
083                        @Override
084                        public Set<Principal> getPrincipals() {
085                            return groups;
086                        }
087                    };
088                }
089    
090                context.setSecurityContext(s);
091                securityContexts.add(s);
092            }
093    
094            try {
095                super.addConnection(context, info);
096            } catch (Exception e) {
097                securityContexts.remove(s);
098                context.setSecurityContext(null);
099                throw e;
100            }
101        }
102    }