...
Code Block |
---|
package dk.portalprotect.nodb.plugins;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import dk.itp.security.authentication.googleauth.GoogleAuthAuthenticationPlugin;
import dk.itp.security.passticket.PTException;
import dk.itp.security.passticket.User;
import dk.itp.security.passticket.server.AuthErrorCodes;
import dk.itp.security.utils.Base64;
/**
* Demonstration on how to create your own TOTP Authentication plugin
*
* @author Kim Rasmussen
*
* <pre>
* Ceptor - http://ceptor.io
* Copyright(c) 2018, Asseco Denmark A/S, All rights reserved.
*
* This source code is confidential.
* </pre>
*/
public class TOTPAuthenticationExample extends GoogleAuthAuthenticationPlugin {
static Logger cat = LoggerFactory.getLogger(TOTPAuthenticationExample.class.getName());
static final int DEFAULT_AUTHLEVEL = 10;
public int getAuthenticationLevel() {
return DEFAULT_AUTHLEVEL;
}
/**
* Generate new secret, or return PNG using QR code
*/
public String newToken(User user, String inputToken) throws PTException {
String secret = "";
try {
if (!user.isLoggedOn) {
// TODO: Here you can change the logic for registration / signing up new users
throw new PTException("Not authenticated, cannot register new TOTP device", AuthErrorCodes.ERROR_NOTAUTHENTICATED, "Cannot register new OTP device until authenticated");
}
secret = (String)user.getStateObject("saved_totp_secret");
if (secret == null) {
// Create a new
secret = super.generateSecretSharedKey();
user.setStateObject("saved_totp_secret", secret);
}
if (inputToken.equals("PNG"))
return new String(Base64.encode(getQRPNG(secret, user.userid)), "UTF-8");
else if (inputToken.equals("secret"))
return secret;
else
throw new PTException("Invalid token");
} catch(PTException e) {
throw e;
} catch(Exception e) {
cat.error("Got exception trying to create new token for user " + user.userid, e);
throw new PTException("Error trying to create new security token for user", AuthErrorCodes.ERROR_GENERALERROR, "Unknown error trying to create new token");
}
}
public void login(User user, String userid, Object credentials) throws PTException {
if (credentials instanceof String) {
// TODO: Verify userid and password and lookup the shared secret, store the secret for use on next call
//user.setStateObject("saved_totp_secret", secret_found_in_userstore);
user.setStateObject("totp_password_verified", Boolean.TRUE);
throw new PTException("Need OTP", AuthErrorCodes.ERROR_NEED_OTP, "Need OTP code");
}
if (credentials instanceof String[]) {
String[] creds = (String[])credentials;
String secret = (String)user.getStateObject("saved_totp_secret");
long code = 0;
try {
if (creds.length == 2) {
// Assume we are called with password and OTP - supporting login using userid + password + OTP all in one dialog
// TODO: Verify password, lookup secret
//String password = creds[0];
// secret = secret_found_in_userstore;
code = Long.parseLong(creds[1]);
} else {
// Assume we are just called with the OTP, supporting 2nd step login using authenticator code
// Verify that we we called first
if (!Boolean.TRUE.equals(user.getStateObject("totp_password_verified"))) {
throw new PTException("Called with OTP without verifying first using userid+password");
}
code = Long.parseLong(creds[0]);
}
} catch(NumberFormatException e) {
throw new PTException("Password does not match", AuthErrorCodes.ERROR_INVALIDCREDENTIALS, "Invalid credentials", e);
}
// Check the google authenticator code
try {
if (!verifyCode(secret, code)) {
throw new PTException("OTP does not match", AuthErrorCodes.ERROR_INVALIDCREDENTIALS, "Invalid credentials");
}
} catch (InvalidKeyException | NoSuchAlgorithmException e) {
throw new PTException("OTP does not match", AuthErrorCodes.ERROR_INVALIDCREDENTIALS, "Invalid credentials", e);
}
user.userid = userid;
user.isLoggedOn = true;
} else {
cat.error("Cannot login, unsupported type of credentials");
throw new PTException("Unsupported type of credentials - cannot login", AuthErrorCodes.ERROR_GENERALERROR, "Unsupported type of credentials");
}
}
} |
...