public void assertCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) throws AuthenticationException { if (PropertyUtil.getBoolean("encrypt")) { super.assertCredentialsMatch(token, info); } else { if (token != null && info != null) { CaptchaUsernamePasswordToken tk = (CaptchaUsernamePasswordToken) token; if (!(String.valueOf(tk.getPassword())).equals((String) info.getCredentials())) { // not successful - throw an exception to indicate this: String msg = "Submitted credentials for token [" + tk + "] did not match the expected credentials."; throw new IncorrectCredentialsException(msg); } } else { throw new AuthenticationException( "A CredentialsMatcher must be configured in order to verify " + "credentials during authentication. If you do not wish for credentials to be examined, you " + "can configure an " + AllowAllCredentialsMatcher.class.getName() + " instance."); } } }
@Test public void testSuccessfulAuthentication() throws Exception { UsernamePasswordToken upToken = new UsernamePasswordToken("brianf", "brianf123"); AuthenticationInfo ai = realm.getAuthenticationInfo(upToken); assertNull(ai.getCredentials()); // String password = new String( (char[]) ai.getCredentials() ); // // // password is plain text // assertEquals( "brianf123", password ); }
/* (non-Javadoc) * @see org.apache.shiro.authc.credential.CredentialsMatcher#doCredentialsMatch(org.apache.shiro.authc.AuthenticationToken, org.apache.shiro.authc.AuthenticationInfo) */ @Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { if (token instanceof AutologinToken) { log.debug("Auto-logging in {}", token.getPrincipal()); return true; } if (token.getCredentials() == null) { log.warn("Rejecting null token credentials for {}", token.getPrincipal()); return false; } if (info.getCredentials() == null) { log.warn("Rejecting null stored credentials for {}", info.getPrincipals()); return false; } final String host = token instanceof HostAuthenticationToken ? ((HostAuthenticationToken) token).getHost() : null; final String passwordToken = String.valueOf((char[]) token.getCredentials()); final String userPassword = info.getCredentials().toString(); final Matcher matcher = passwordPattern.matcher(userPassword); if (matcher.matches()) { final String algorithm = matcher.group(1); final String encodedBase64 = matcher.group(2); switch (algorithm) { case "SSHA": final byte[] encoded = Base64.decodeBase64(encodedBase64); log.trace("Decoded {} into {} bytes", encodedBase64, encoded.length); if (encoded.length < 21) { log.error( "Encoded length must be at least 21 bytes, 20-byte password and at least 1-byte salt, for {}", info.getPrincipals()); return false; } final byte[] digest = Arrays.copyOf(encoded, 20); final byte[] salt = Arrays.copyOfRange(encoded, 20, encoded.length); byte[] digestToken = HashedPasswordUtils.calculateSsha(passwordToken, salt); boolean sshaMatches = Arrays.equals(digestToken, digest); log.debug( "Matching credentials for {} host {} using SSHA: {}", token.getPrincipal(), host, sshaMatches); return sshaMatches; case "PLAIN": boolean plainMatches = encodedBase64.equals(passwordToken); log.debug( "Matching credentials for {} host {} using PLAIN: {}", token.getPrincipal(), host, plainMatches); return plainMatches; default: log.error("Unknown password algorithm {} for {}", algorithm, info.getPrincipals()); return false; } } else if (userPassword.startsWith("$")) { final BCryptPasswordService bCryptPasswordService = new BCryptPasswordService(); return bCryptPasswordService.passwordsMatch(passwordToken, userPassword); } else { log.error("Unknown password syntax for {}", info.getPrincipals()); return false; } }