@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { // identify account to log to UsernamePasswordToken userPassToken = (UsernamePasswordToken) token; final String username = userPassToken.getUsername(); if (username == null) { return null; } // read password hash and salt from db final User user = UserDAO.getUser(username); if (user == null) { return null; } // return salted credentials SaltedAuthenticationInfo info = new SaltedAuthInfo(username, user.getPassword(), user.getSalt()); return info; }
/** * * @param info the {@code AuthenticationInfo} stored in the data store to be compared against the submitted authentication * token's credentials. * @return Signature = Base64( HMAC-SHA1( YourSecretAccessKeyID, UTF-8-Encoding-Of( StringToSign ) ) ); */ @Override protected Object getCredentials(AuthenticationInfo info) { Object signature = null; byte[] saltBytes = null; if (info instanceof SaltedAuthenticationInfo) { saltBytes = ((SaltedAuthenticationInfo) info).getCredentialsSalt().getBytes(); } try { String stringToSign = (String) info.getCredentials(); byte[] hmacSha1 = HmacSha1.hash(saltBytes, stringToSign); signature = Base64.encodeToString(hmacSha1); } catch (Exception e) { e.printStackTrace(); log.error(e.getMessage()); } return signature; }
@Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { RegToken rtoken = null; if ( token instanceof UsernamePasswordToken ) { UsernamePasswordToken uptoken = (UsernamePasswordToken) token; rtoken = new RegToken(uptoken.getUsername(), new String(uptoken.getPassword())); } else if (token instanceof RegToken) { rtoken = (RegToken)token; } else { throw new IncorrectCredentialsException(); } String id = (String)rtoken.getPrincipal(); SaltedAuthenticationInfo info = getUserStore().checkUser(id); return info; }
@Override public SaltedAuthenticationInfo checkUser(String id) { UserRecord record = getRecord(id); if (record == null) { return null; } if (System.currentTimeMillis() < record.timeout) { return new SimpleAuthenticationInfo( new UserInfo(record.id, record.name), record.getPasword(), record.getSalt(), realm.getName()); } else { return new SimpleAuthenticationInfo( new UserInfo(record.id, record.name), null, realm.getName()); } }
@Override protected SaltedAuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String principal = (String) token.getPrincipal(); return new SimpleAuthenticationInfo(principal, userService.getPassword(principal), new SimpleByteSource(Base64.decode(userService.getPasswordSalt(principal))), "JdbcSaltedRealm"); }
private byte[] getSalt(AuthenticationInfo info) { return ((SaltedAuthenticationInfo) info).getCredentialsSalt().getBytes(); }
/** * Takes the specified <code>info</code> argument and adds its principals and credentials into this instance. * * @param info the <code>AuthenticationInfo</code> to add into this instance. */ @SuppressWarnings("unchecked") public void merge(AuthenticationInfo info) { if (info == null || info.getPrincipals() == null || info.getPrincipals().isEmpty()) { return; } if (this.principals == null) { this.principals = info.getPrincipals(); } else { if (!(this.principals instanceof MutablePrincipalCollection)) { this.principals = new SimplePrincipalCollection(this.principals); } ((MutablePrincipalCollection) this.principals).addAll(info.getPrincipals()); } //only mess with a salt value if we don't have one yet. It doesn't make sense //to merge salt values from different realms because a salt is used only within //the realm's credential matching process. But if the current instance's salt //is null, then it can't hurt to pull in a non-null value if one exists. // //since 1.1: if (this.credentialsSalt == null && info instanceof SaltedAuthenticationInfo) { this.credentialsSalt = ((SaltedAuthenticationInfo) info).getCredentialsSalt(); } Object thisCredentials = getCredentials(); Object otherCredentials = info.getCredentials(); if (otherCredentials == null) { return; } if (thisCredentials == null) { this.credentials = otherCredentials; return; } if (!(thisCredentials instanceof Collection)) { Set newSet = new HashSet(); newSet.add(thisCredentials); setCredentials(newSet); } // At this point, the credentials should be a collection Collection credentialCollection = (Collection) getCredentials(); if (otherCredentials instanceof Collection) { credentialCollection.addAll((Collection) otherCredentials); } else { credentialCollection.add(otherCredentials); } }
/** * Hash the provided {@code token}'s credentials using the salt stored with the account if the * {@code info} instance is an {@code instanceof} {@link SaltedAuthenticationInfo SaltedAuthenticationInfo} (see * the class-level JavaDoc for why this is the preferred approach). * <p/> * If the {@code info} instance is <em>not</em> * an {@code instanceof} {@code SaltedAuthenticationInfo}, the logic will fall back to Shiro 1.0 * backwards-compatible logic: it will first check to see {@link #isHashSalted() isHashSalted} and if so, will try * to acquire the salt from {@link #getSalt(AuthenticationToken) getSalt(AuthenticationToken)}. See the class-level * JavaDoc for why this is not recommended. This 'fallback' logic exists only for backwards-compatibility. * {@code Realm}s should be updated as soon as possible to return {@code SaltedAuthenticationInfo} instances * if account credentials salting is enabled (highly recommended for password-based systems). * * @param token the submitted authentication token from which its credentials will be hashed * @param info the stored account data, potentially used to acquire a salt * @return the token credentials hash * @since 1.1 */ protected Object hashProvidedCredentials(AuthenticationToken token, AuthenticationInfo info) { Object salt = null; if (info instanceof SaltedAuthenticationInfo) { salt = ((SaltedAuthenticationInfo) info).getCredentialsSalt(); } else { //retain 1.0 backwards compatibility: if (isHashSalted()) { salt = getSalt(token); } } return hashProvidedCredentials(token.getCredentials(), salt, getHashIterations()); }
/** * Test if a user is registered. Returns their user information and credentials * if they are or null if not registered. Stored and returned credentials are salt-hashed * to make it easy to allow user defined passwords in the future, redundant for * generated passwords. If the user has no credentials or they have timed out then * the credentials will be null. * * @param id the openid identifier string authenticated by the user */ public SaltedAuthenticationInfo checkUser(String id);