/** * Delegates to {@link #queryForAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken, LdapContextFactory)}, * wrapping any {@link NamingException}s in a Shiro {@link AuthenticationException} to satisfy the parent method * signature. * * @param token the authentication token containing the user's principal and credentials. * @return the {@link AuthenticationInfo} acquired after a successful authentication attempt * @throws AuthenticationException if the authentication attempt fails or if a * {@link NamingException} occurs. */ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { AuthenticationInfo info; try { info = queryForAuthenticationInfo(token, getContextFactory()); } catch (AuthenticationNotSupportedException e) { String msg = "Unsupported configured authentication mechanism"; throw new UnsupportedAuthenticationMechanismException(msg, e); } catch (javax.naming.AuthenticationException e) { throw new AuthenticationException("LDAP authentication failed.", e); } catch (NamingException e) { String msg = "LDAP naming error while attempting to authenticate user."; throw new AuthenticationException(msg, e); } return info; }
/** * Returns the User Distinguished Name (DN) template to use when creating User DNs at runtime - see the * {@link #setUserDnTemplate(String) setUserDnTemplate} JavaDoc for a full explanation. * * @return the User Distinguished Name (DN) template to use when creating User DNs at runtime. */ public String getUserDnTemplate() { return getUserDn(USERDN_SUBSTITUTION_TOKEN); }
protected DefaultLdapRealm getNewRealmUnderTest() { return new DefaultLdapRealm(); }
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { AuthorizationInfo info; try { info = queryForAuthorizationInfo(principals, getContextFactory()); } catch (NamingException e) { String msg = "LDAP naming error while attempting to retrieve authorization for user [" + principals + "]."; throw new AuthorizationException(msg, e); } return info; }
principal = getLdapPrincipal(token); ctx = ldapContextFactory.getLdapContext(principal, credentials); return createAuthenticationInfo(token, principal, credentials, ctx); } finally { LdapUtils.closeContext(ctx);
@Test public void testUserDnTemplateSubstitution() throws NamingException { realm.setUserDnTemplate("uid={0},ou=users,dc=mycompany,dc=com"); LdapContextFactory factory = createMock(LdapContextFactory.class); realm.setContextFactory(factory); Object expectedPrincipal = "uid=jsmith,ou=users,dc=mycompany,dc=com"; expect(factory.getLdapContext(eq(expectedPrincipal), isA(Object.class))).andReturn(createNiceMock(LdapContext.class)); replay(factory); realm.getAuthenticationInfo(new UsernamePasswordToken("jsmith", "secret") ); verify(factory); }
@Test public void testDefaultInstance() { assertTrue(realm.getCredentialsMatcher() instanceof AllowAllCredentialsMatcher); assertEquals(AuthenticationToken.class, realm.getAuthenticationTokenClass()); assertTrue(realm.getContextFactory() instanceof JndiLdapContextFactory); }
@Test public void testGetUserDnWithOutPrefixAndSuffix() { realm = new DefaultLdapRealm() { @Override protected String getUserDnPrefix() { return null; } @Override protected String getUserDnSuffix() { return null; } }; String principal = "foo"; String userDn = realm.getUserDn(principal); assertEquals(principal, userDn); } }
: super.queryForAuthenticationInfo( token, ldapContextFactory ); securityLog.debug( withRealm( "Authenticated user '%s' against %s", token.getPrincipal(), serverString ) );
@Override //KNOX-534 overriding this method to be able to audit authentication exceptions protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws org.apache.shiro.authc.AuthenticationException { try { return super.doGetAuthenticationInfo(token); } catch ( org.apache.shiro.authc.AuthenticationException e ) { auditor.audit( Action.AUTHENTICATION , token.getPrincipal().toString(), ResourceType.PRINCIPAL, ActionOutcome.FAILURE, e.getMessage() ); ShiroLog.failedLoginInfo(token); ShiroLog.failedLoginStackTrace(e); ShiroLog.failedLoginAttempt(e.getCause()); throw e; } }
@Override protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals ) { try { AuthorizationInfo info = super.doGetAuthorizationInfo( principals ); securityLog.debug( withRealm( "Queried for authorization info for user '%s'", principals.getPrimaryPrincipal() ) ); return info; } catch ( AuthorizationException e ) { securityLog.warn( withRealm( "Failed to get authorization info: '%s' caused by '%s'", e.getMessage(), e.getCause().getMessage() ) ); return null; } }
@Test(expected= AuthenticationException.class) public void testGetAuthenticationInfoNamingException() throws NamingException { realm.setUserDnTemplate("uid={0},ou=users,dc=mycompany,dc=com"); LdapContextFactory factory = createMock(LdapContextFactory.class); realm.setContextFactory(factory); expect(factory.getLdapContext(isA(Object.class), isA(Object.class))) .andThrow(new NamingException("Communication error.")); replay(factory); realm.getAuthenticationInfo(new UsernamePasswordToken("jsmith", "secret") ); }
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { AuthorizationInfo info; try { info = queryForAuthorizationInfo(principals, getContextFactory()); } catch (NamingException e) { String msg = "LDAP naming error while attempting to retrieve authorization for user [" + principals + "]."; throw new AuthorizationException(msg, e); } return info; }
principal = getLdapPrincipal(token); ctx = ldapContextFactory.getLdapContext(principal, credentials); return createAuthenticationInfo(token, principal, credentials, ctx); } finally { LdapUtils.closeContext(ctx);
@Test(expected= AuthenticationException.class) public void testGetAuthenticationInfoNamingAuthenticationException() throws NamingException { realm.setUserDnTemplate("uid={0},ou=users,dc=mycompany,dc=com"); LdapContextFactory factory = createMock(LdapContextFactory.class); realm.setContextFactory(factory); expect(factory.getLdapContext(isA(Object.class), isA(Object.class))) .andThrow(new javax.naming.AuthenticationException("LDAP Authentication failed.")); replay(factory); realm.getAuthenticationInfo(new UsernamePasswordToken("jsmith", "secret") ); }
/** * Delegates to {@link #queryForAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken, LdapContextFactory)}, * wrapping any {@link NamingException}s in a Shiro {@link AuthenticationException} to satisfy the parent method * signature. * * @param token the authentication token containing the user's principal and credentials. * @return the {@link AuthenticationInfo} acquired after a successful authentication attempt * @throws AuthenticationException if the authentication attempt fails or if a * {@link NamingException} occurs. */ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { AuthenticationInfo info; try { info = queryForAuthenticationInfo(token, getContextFactory()); } catch (AuthenticationNotSupportedException e) { String msg = "Unsupported configured authentication mechanism"; throw new UnsupportedAuthenticationMechanismException(msg, e); } catch (javax.naming.AuthenticationException e) { throw new AuthenticationException("LDAP authentication failed.", e); } catch (NamingException e) { String msg = "LDAP naming error while attempting to authenticate user."; throw new AuthenticationException(msg, e); } return info; }
/** * Returns the principal to use when creating the LDAP connection for an authentication attempt. * <p/> * This implementation uses a heuristic: it checks to see if the specified token's * {@link AuthenticationToken#getPrincipal() principal} is a {@code String}, and if so, * {@link #getUserDn(String) converts it} from what is * assumed to be a raw uid or username {@code String} into a User DN {@code String}. Almost all LDAP directories * expect the authentication connection to present a User DN and not an unqualified username or uid. * <p/> * If the token's {@code principal} is not a String, it is assumed to already be in the format supported by the * underlying {@link LdapContextFactory} implementation and the raw principal is returned directly. * * @param token the {@link AuthenticationToken} submitted during the authentication process * @return the User DN or raw principal to use to acquire the LdapContext. * @see LdapContextFactory#getLdapContext(Object, Object) */ protected Object getLdapPrincipal(AuthenticationToken token) { Object principal = token.getPrincipal(); if (principal instanceof String) { String sPrincipal = (String) principal; return getUserDn(sPrincipal); } return principal; }
/** * This test simulates that if a non-String principal (i.e. not a username) is passed as the LDAP principal, that * it is not altered into a User DN and is passed as-is. This will allow principals to be things like X.509 * certificates as well instead of only strings. * * @throws NamingException not thrown */ @Test public void testGetAuthenticationInfoNonSimpleToken() throws NamingException { realm.setUserDnTemplate("uid={0},ou=users,dc=mycompany,dc=com"); LdapContextFactory factory = createMock(LdapContextFactory.class); realm.setContextFactory(factory); final UUID userId = UUID.randomUUID(); //ensure the userId is passed as-is: expect(factory.getLdapContext(eq(userId), isA(Object.class))).andReturn(createNiceMock(LdapContext.class)); replay(factory); realm.getAuthenticationInfo(new AuthenticationToken() { public Object getPrincipal() { return userId; } public Object getCredentials() { return "secret"; } }); verify(factory); }
@Test(expected=IllegalArgumentException.class) public void testGetUserDnNullArgument() { realm.getUserDn(null); }
/** * Returns the User Distinguished Name (DN) template to use when creating User DNs at runtime - see the * {@link #setUserDnTemplate(String) setUserDnTemplate} JavaDoc for a full explanation. * * @return the User Distinguished Name (DN) template to use when creating User DNs at runtime. */ public String getUserDnTemplate() { return getUserDn(USERDN_SUBSTITUTION_TOKEN); }