...
Code Block |
---|
package dk.portalprotect.nodb.plugins;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import dk.itp.security.authentication.sms.SMSAuthenticationPlugin;
import dk.itp.security.passticket.PTException;
import dk.itp.security.passticket.User;
import dk.itp.security.passticket.server.AuthErrorCodes;
/**
* Examplle authentication plugin, used to demonstrate authenticating using SMS.
*
* @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 SMSAuthenticationExample extends SMSAuthenticationPlugin {
static Logger log = LoggerFactory.getLogger(SMSAuthenticationExample.class.getName());
static final int DEFAULT_AUTHLEVEL = 10;
/**
* @see dk.itp.security.authentication.IAuthenticationPlugin#getAuthenticationLevel()
*/
public int getAuthenticationLevel() {
return DEFAULT_AUTHLEVEL;
}
/**
* @see dk.itp.security.authentication.IAuthenticationPlugin#login(User, String, Object, Object)
*/
public void login(User user, String userid, Object credentials) throws PTException {
if (credentials instanceof String) {
user.removeStateObject("SMS_OTP");
user.removeStateObject("SMS_USERID");
// Lookup userid in user repository, verify password
// In this NON-PRODUCTION example, we assume the userid is the phone number, and the password is "password"
if (!credentials.equals("password")) {
throw new PTException("Invalid password", AuthErrorCodes.ERROR_INVALIDCREDENTIALS, "Invalid credentials");
}
// If we get here, the password is ok
// For now, use the userid as phone number - in a real authentication plugin, look it up somewhere else.
String mobile = userid;
mobile = mobile == null ? "" : mobile.trim();
if (mobile.startsWith("+"))
mobile = mobile.substring(1);
int ofs = mobile.indexOf(' ');
while(ofs >= 0) {
mobile = mobile.substring(0,ofs) + mobile.substring(ofs+1);
ofs = mobile.indexOf(' ');
}
if (mobile == null || mobile.length() == 0)
throw new PTException("No mobile number on record, cannot send PIN via SMS", AuthErrorCodes.ERROR_NOMOBILEPHONE, "No mobile number, cannot send SMS");
// If 8 chars, assume danish and add country code 45 for Denmark
if (mobile.length() == 8)
mobile = "45"+mobile;
// Generate an OTP, store it in the session, and throw an exception telling the application we need the OTP.
String otp = generateOTP();
user.setStateObject("SMS_OTP", otp);
user.setStateObject("SMS_USERID", userid);
try {
if (!sendSMS(mobile, "PIN:\n"+otp))
throw new PTException("Unable to send SMS to " + mobile, AuthErrorCodes.ERROR_NOMOBILEPHONE, "Problem with mobile, cannot send SMS");
} catch (MalformedURLException e) {
throw new PTException("Unable to send SMS to " + mobile, AuthErrorCodes.ERROR_NOMOBILEPHONE, "Configuration problem - invalid SMS configuration", e);
} catch (IOException e) {
throw new PTException("Unable to send SMS to " + mobile, AuthErrorCodes.ERROR_NOMOBILEPHONE, "Problem contacting SMS Gateway", e);
}
log.info("Logon with userid/password OK - SMS sent to " + mobile + ", need relogin with pincode");
throw new PTException("Need OTP pincode", AuthErrorCodes.ERROR_NEED_OTP, "Need OTP code");
} else if (credentials instanceof String[]) {
// String[] means we are called with the one-time password.
userid = (String) user.getStateObject("SMS_USERID");
String otp = (String)user.getStateObject("SMS_OTP");
if (userid == null || otp == null) {
throw new PTException("Problem logging in, no userid present or timeout", AuthErrorCodes.ERROR_GENERALERROR, "No previous userid/password login or timeout");
}
// Remove allows only one try - keep it to allow multiple attempts at entering the correct PIN
user.removeStateObject("SMS_OTP");
user.removeStateObject("SMS_USERID");
if (!((String[])credentials)[0].equalsIgnoreCase(otp)) {
throw new PTException("Invalid OTP PIN", AuthErrorCodes.ERROR_INVALIDCREDENTIALS, "Invalid PIN code");
}
user.userid = userid;
user.isLoggedOn = true;
// Fill remaining information onto session
}
else {
log.error("Cannot login, unsupported type of credentials");
throw new PTException("Unsupported type of credentials - cannot login", AuthErrorCodes.ERROR_GENERALERROR, "Unsupported type of credentials");
}
}
/**
* @see dk.itp.security.authentication.IAuthenticationPlugin#setConfiguration(Properties)
*/
public void setConfiguration(Properties props) {
super.setConfiguration(props);
log.error("Using Example SMS Plugin with hardcoded credentials - NOT FOR PRODUCTION");
}
} |
...