1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package com.allanbank.mongodb.client.connection.auth;
22
23 import java.util.Collection;
24 import java.util.Iterator;
25 import java.util.Map;
26 import java.util.concurrent.ConcurrentHashMap;
27
28 import com.allanbank.mongodb.Credential;
29 import com.allanbank.mongodb.MongoClientConfiguration;
30 import com.allanbank.mongodb.MongoDbException;
31 import com.allanbank.mongodb.client.Message;
32 import com.allanbank.mongodb.client.callback.ReplyCallback;
33 import com.allanbank.mongodb.client.connection.Connection;
34 import com.allanbank.mongodb.client.connection.proxy.AbstractProxyConnection;
35 import com.allanbank.mongodb.error.MongoDbAuthenticationException;
36 import com.allanbank.mongodb.util.log.Log;
37 import com.allanbank.mongodb.util.log.LogFactory;
38
39
40
41
42
43
44
45
46
47 public class AuthenticatingConnection extends AbstractProxyConnection {
48
49
50 public static final String ADMIN_DB_NAME = MongoClientConfiguration.ADMIN_DB_NAME;
51
52
53 public static final Log LOG = LogFactory
54 .getLog(AuthenticatingConnection.class);
55
56
57 private final Map<String, Authenticator> myAuthenticators;
58
59
60 private final Map<String, MongoDbException> myFailures;
61
62
63
64
65
66
67
68
69
70 public AuthenticatingConnection(final Connection connection,
71 final MongoClientConfiguration config) {
72 super(connection);
73
74 myAuthenticators = new ConcurrentHashMap<String, Authenticator>();
75 myFailures = new ConcurrentHashMap<String, MongoDbException>();
76
77
78
79 final Collection<Credential> credentials = config.getCredentials();
80 for (final Credential credential : credentials) {
81 final Authenticator authenticator = credential.authenticator();
82
83 authenticator.startAuthentication(credential, connection);
84
85
86
87 if (credentials.size() > 1) {
88 try {
89 if (!authenticator.result()) {
90 myFailures.put(credential.getDatabase(),
91 new MongoDbAuthenticationException(
92 "Authentication failed for the "
93 + credential.getDatabase()
94 + " database."));
95 }
96 }
97 catch (final MongoDbException error) {
98 myFailures.put(credential.getDatabase(), error);
99 }
100 }
101 else {
102 myAuthenticators.put(credential.getDatabase(), authenticator);
103 }
104 }
105 }
106
107
108
109
110
111
112
113
114 @Override
115 public void send(final Message message1, final Message message2,
116 final ReplyCallback replyCallback) throws MongoDbException {
117 ensureAuthenticated(message1);
118 ensureAuthenticated(message2);
119
120 super.send(message1, message2, replyCallback);
121 }
122
123
124
125
126
127
128
129
130 @Override
131 public void send(final Message message, final ReplyCallback replyCallback)
132 throws MongoDbException {
133 ensureAuthenticated(message);
134
135 super.send(message, replyCallback);
136 }
137
138
139
140
141
142
143
144 @Override
145 public String toString() {
146 return "Auth(" + getProxiedConnection() + ")";
147 }
148
149
150
151
152
153
154
155 @Override
156 protected Connection getProxiedConnection() {
157 final Connection proxied = super.getProxiedConnection();
158
159 return proxied;
160 }
161
162
163
164
165
166
167
168
169
170
171 private void ensureAuthenticated(final Message message)
172 throws MongoDbAuthenticationException {
173
174 if (!myAuthenticators.isEmpty()) {
175 final Iterator<Map.Entry<String, Authenticator>> iter = myAuthenticators
176 .entrySet().iterator();
177 while (iter.hasNext()) {
178 final Map.Entry<String, Authenticator> authenticator = iter
179 .next();
180 try {
181 if (!authenticator.getValue().result()) {
182 myFailures.put(authenticator.getKey(),
183 new MongoDbAuthenticationException(
184 "Authentication failed for the "
185 + authenticator.getKey()
186 + " database."));
187 }
188 }
189 catch (final MongoDbException error) {
190
191 LOG.warn(error, "Authentication failed: []",
192 error.getMessage());
193
194 myFailures.put(authenticator.getKey(), error);
195 }
196 finally {
197 iter.remove();
198 }
199 }
200 }
201
202 if (myFailures.containsKey(message.getDatabaseName())) {
203 throw new MongoDbAuthenticationException(myFailures.get(message
204 .getDatabaseName()));
205 }
206 }
207 }