1 7 package org.jboss.security.auth.spi; 8 9 import java.security.acl.Group ; 10 import java.security.Principal ; 11 import java.util.Iterator ; 12 import java.util.Map.Entry; 13 import java.util.Properties ; 14 import javax.naming.Context ; 15 import javax.naming.NamingEnumeration ; 16 import javax.naming.NamingException ; 17 import javax.naming.directory.Attribute ; 18 import javax.naming.directory.Attributes ; 19 import javax.naming.directory.BasicAttributes ; 20 import javax.naming.directory.SearchResult ; 21 import javax.naming.ldap.InitialLdapContext ; 22 import javax.security.auth.login.LoginException ; 23 24 import org.jboss.security.SimpleGroup; 25 import org.jboss.security.SimplePrincipal; 26 import org.jboss.security.auth.spi.UsernamePasswordLoginModule; 27 28 135 public class LdapLoginModule extends UsernamePasswordLoginModule 136 { 137 private static final String USE_OBJECT_CREDENTIAL_OPT = "useObjectCredential"; 138 private static final String PRINCIPAL_DN_PREFIX_OPT = "principalDNPrefix"; 139 private static final String PRINCIPAL_DN_SUFFIX_OPT = "principalDNSuffix"; 140 private static final String ROLES_CTX_DN_OPT = "rolesCtxDN"; 141 private static final String USER_ROLES_CTX_DN_ATTRIBUTE_ID_OPT = 142 "userRolesCtxDNAttributeName"; 143 private static final String UID_ATTRIBUTE_ID_OPT = "uidAttributeID"; 144 private static final String ROLE_ATTRIBUTE_ID_OPT = "roleAttributeID"; 145 private static final String MATCH_ON_USER_DN_OPT = "matchOnUserDN"; 146 private static final String ROLE_ATTRIBUTE_IS_DN_OPT = "roleAttributeIsDN"; 147 private static final String ROLE_NAME_ATTRIBUTE_ID_OPT = "roleNameAttributeID"; 148 149 public LdapLoginModule() 150 { 151 } 152 153 private transient SimpleGroup userRoles = new SimpleGroup("Roles"); 154 155 160 protected String getUsersPassword() throws LoginException 161 { 162 return ""; 163 } 164 165 172 protected Group [] getRoleSets() throws LoginException 173 { 174 Group [] roleSets = {userRoles}; 175 return roleSets; 176 } 177 178 184 protected boolean validatePassword(String inputPassword, String expectedPassword) 185 { 186 boolean isValid = false; 187 if (inputPassword != null) 188 { 189 if (inputPassword.length() == 0) 191 { 192 boolean allowEmptyPasswords = true; 194 String flag = (String ) options.get("allowEmptyPasswords"); 195 if (flag != null) 196 allowEmptyPasswords = Boolean.valueOf(flag).booleanValue(); 197 if (allowEmptyPasswords == false) 198 { 199 super.log.trace("Rejecting empty password due to allowEmptyPasswords"); 200 return false; 201 } 202 } 203 204 try 205 { 206 String username = getUsername(); 208 createLdapInitContext(username, inputPassword); 209 isValid = true; 210 } 211 catch (NamingException e) 212 { 213 super.log.debug("Failed to validate password", e); 214 } 215 } 216 return isValid; 217 } 218 219 private void createLdapInitContext(String username, Object credential) throws NamingException 220 { 221 Properties env = new Properties (); 222 Iterator iter = options.entrySet().iterator(); 224 while (iter.hasNext()) 225 { 226 Entry entry = (Entry) iter.next(); 227 env.put(entry.getKey(), entry.getValue()); 228 } 229 230 String factoryName = env.getProperty(Context.INITIAL_CONTEXT_FACTORY); 232 if (factoryName == null) 233 { 234 factoryName = "com.sun.jndi.ldap.LdapCtxFactory"; 235 env.setProperty(Context.INITIAL_CONTEXT_FACTORY, factoryName); 236 } 237 String authType = env.getProperty(Context.SECURITY_AUTHENTICATION); 238 if (authType == null) 239 env.setProperty(Context.SECURITY_AUTHENTICATION, "simple"); 240 String protocol = env.getProperty(Context.SECURITY_PROTOCOL); 241 String providerURL = (String ) options.get(Context.PROVIDER_URL); 242 if (providerURL == null) 243 providerURL = "ldap://localhost:" + ((protocol != null && protocol.equals("ssl")) ? "636" : "389"); 244 245 String principalDNPrefix = (String ) options.get(PRINCIPAL_DN_PREFIX_OPT); 246 if (principalDNPrefix == null) 247 principalDNPrefix = ""; 248 String principalDNSuffix = (String ) options.get(PRINCIPAL_DN_SUFFIX_OPT); 249 if (principalDNSuffix == null) 250 principalDNSuffix = ""; 251 String matchType = (String ) options.get(MATCH_ON_USER_DN_OPT); 252 boolean matchOnUserDN = Boolean.valueOf(matchType).booleanValue(); 253 String userDN = principalDNPrefix + username + principalDNSuffix; 254 env.setProperty(Context.PROVIDER_URL, providerURL); 255 env.setProperty(Context.SECURITY_PRINCIPAL, userDN); 256 env.put(Context.SECURITY_CREDENTIALS, credential); 257 super.log.trace("Logging into LDAP server, env=" + env); 258 InitialLdapContext ctx = new InitialLdapContext (env, null); 259 super.log.trace("Logged into LDAP server, " + ctx); 260 264 String rolesCtxDN = (String ) options.get(ROLES_CTX_DN_OPT); 265 String userRolesCtxDNAttributeName = (String ) options.get(USER_ROLES_CTX_DN_ATTRIBUTE_ID_OPT); 266 if (userRolesCtxDNAttributeName != null) 267 { 268 String [] returnAttribute = {userRolesCtxDNAttributeName}; 270 try 271 { 272 Attributes result = ctx.getAttributes(userDN, returnAttribute); 273 if (result.get(userRolesCtxDNAttributeName) != null) 274 { 275 rolesCtxDN = result.get(userRolesCtxDNAttributeName).get().toString(); 276 super.log.trace("Found user roles context DN: " + rolesCtxDN); 277 } 278 } 279 catch (NamingException e) 280 { 281 super.log.debug("Failed to query userRolesCtxDNAttributeName", e); 282 } 283 } 284 285 if (rolesCtxDN != null) 287 { 288 String uidAttrName = (String ) options.get(UID_ATTRIBUTE_ID_OPT); 289 if (uidAttrName == null) 290 uidAttrName = "uid"; 291 String roleAttrName = (String ) options.get(ROLE_ATTRIBUTE_ID_OPT); 292 if (roleAttrName == null) 293 roleAttrName = "roles"; 294 BasicAttributes matchAttrs = new BasicAttributes (true); 295 if (matchOnUserDN == true) 296 matchAttrs.put(uidAttrName, userDN); 297 else 298 matchAttrs.put(uidAttrName, username); 299 String [] roleAttr = {roleAttrName}; 300 String roleAttributeIsDNOption = (String ) options.get(ROLE_ATTRIBUTE_IS_DN_OPT); 302 boolean roleAttributeIsDN = Boolean.valueOf(roleAttributeIsDNOption).booleanValue(); 303 304 String roleNameAttributeID = (String ) options.get(ROLE_NAME_ATTRIBUTE_ID_OPT); 307 if (roleNameAttributeID == null) 308 roleNameAttributeID = "name"; 309 310 try 311 { 312 NamingEnumeration answer = ctx.search(rolesCtxDN, matchAttrs, roleAttr); 313 while (answer.hasMore()) 314 { 315 SearchResult sr = (SearchResult ) answer.next(); 316 Attributes attrs = sr.getAttributes(); 317 Attribute roles = attrs.get(roleAttrName); 318 for (int r = 0; r < roles.size(); r++) 319 { 320 Object value = roles.get(r); 321 String roleName = null; 322 if (roleAttributeIsDN == true) 323 { 324 String roleDN = value.toString(); 326 String [] returnAttribute = {roleNameAttributeID}; 327 super.log.trace("Using roleDN: " + roleDN); 328 try 329 { 330 Attributes result = ctx.getAttributes(roleDN, returnAttribute); 331 if (result.get(roleNameAttributeID) != null) 332 { 333 roleName = result.get(roleNameAttributeID).get().toString(); 334 } 335 } 336 catch (NamingException e) 337 { 338 log.trace("Failed to query roleNameAttrName", e); 339 } 340 } 341 else 342 { 343 roleName = value.toString(); 345 } 346 347 if (roleName != null) 348 { 349 try 350 { 351 Principal p = super.createIdentity(roleName); 352 log.trace("Assign user to role " + roleName); 353 userRoles.addMember(p); 354 } 355 catch (Exception e) 356 { 357 log.debug("Failed to create principal: " + roleName, e); 358 } 359 } 360 } 361 } 362 } 363 catch (NamingException e) 364 { 365 log.trace("Failed to locate roles", e); 366 } 367 } 368 ctx.close(); 370 } 371 } 372 | Popular Tags |