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 018package org.apache.activemq.jaas; 019 020import java.io.IOException; 021import java.security.Principal; 022import java.util.HashSet; 023import java.util.Map; 024import java.util.Set; 025import javax.security.auth.Subject; 026import javax.security.auth.callback.Callback; 027import javax.security.auth.callback.CallbackHandler; 028import javax.security.auth.callback.PasswordCallback; 029import javax.security.auth.callback.UnsupportedCallbackException; 030import javax.security.auth.login.LoginException; 031import javax.security.auth.spi.LoginModule; 032import org.slf4j.Logger; 033import org.slf4j.LoggerFactory; 034 035/** 036 * Always login the user with a default 'guest' identity. 037 * 038 * Useful for unauthenticated communication channels being used in the 039 * same broker as authenticated ones. 040 * 041 */ 042public class GuestLoginModule implements LoginModule { 043 044 private static final String GUEST_USER = "org.apache.activemq.jaas.guest.user"; 045 private static final String GUEST_GROUP = "org.apache.activemq.jaas.guest.group"; 046 047 private static final Logger LOG = LoggerFactory.getLogger(GuestLoginModule.class); 048 049 050 private String userName = "guest"; 051 private String groupName = "guests"; 052 private Subject subject; 053 private boolean debug; 054 private boolean credentialsInvalidate; 055 private Set<Principal> principals = new HashSet<Principal>(); 056 private CallbackHandler callbackHandler; 057 058 /** the authentication status*/ 059 private boolean succeeded = false; 060 private boolean commitSucceeded = false; 061 062 @Override 063 public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { 064 this.subject = subject; 065 this.callbackHandler = callbackHandler; 066 debug = "true".equalsIgnoreCase((String)options.get("debug")); 067 credentialsInvalidate = "true".equalsIgnoreCase((String)options.get("credentialsInvalidate")); 068 if (options.get(GUEST_USER) != null) { 069 userName = (String)options.get(GUEST_USER); 070 } 071 if (options.get(GUEST_GROUP) != null) { 072 groupName = (String)options.get(GUEST_GROUP); 073 } 074 principals.add(new UserPrincipal(userName)); 075 principals.add(new GroupPrincipal(groupName)); 076 077 if (debug) { 078 LOG.debug("Initialized debug=" + debug + " guestUser=" + userName + " guestGroup=" + groupName); 079 } 080 081 } 082 083 @Override 084 public boolean login() throws LoginException { 085 succeeded = true; 086 if (credentialsInvalidate) { 087 PasswordCallback passwordCallback = new PasswordCallback("Password: ", false); 088 try { 089 callbackHandler.handle(new Callback[]{passwordCallback}); 090 if (passwordCallback.getPassword() != null) { 091 if (debug) { 092 LOG.debug("Guest login failing (credentialsInvalidate=true) on presence of a password"); 093 } 094 succeeded = false; 095 passwordCallback.clearPassword(); 096 }; 097 } catch (IOException ioe) { 098 } catch (UnsupportedCallbackException uce) { 099 } 100 } 101 if (debug) { 102 LOG.debug("Guest login " + succeeded); 103 } 104 return succeeded; 105 } 106 107 @Override 108 public boolean commit() throws LoginException { 109 if (debug) { 110 LOG.debug("commit"); 111 } 112 113 if (!succeeded) { 114 return false; 115 } 116 117 subject.getPrincipals().addAll(principals); 118 commitSucceeded = true; 119 return true; 120 } 121 122 @Override 123 public boolean abort() throws LoginException { 124 125 if (debug) { 126 LOG.debug("abort"); 127 } 128 if (!succeeded) { 129 return false; 130 } else if (succeeded && commitSucceeded) { 131 // we succeeded, but another required module failed 132 logout(); 133 } else { 134 // our commit failed 135 succeeded = false; 136 } 137 return true; 138 } 139 140 @Override 141 public boolean logout() throws LoginException { 142 subject.getPrincipals().removeAll(principals); 143 144 if (debug) { 145 LOG.debug("logout"); 146 } 147 148 succeeded = false; 149 commitSucceeded = false; 150 return true; 151 } 152}