1 19 20 package com.sslexplorer.security; 21 22 import javax.servlet.http.HttpServletRequest ; 23 import javax.servlet.http.HttpServletResponse ; 24 25 import org.apache.commons.logging.Log; 26 import org.apache.commons.logging.LogFactory; 27 import org.apache.struts.action.Action; 28 import org.apache.struts.action.ActionForward; 29 import org.apache.struts.action.ActionMapping; 30 import org.apache.struts.action.ActionMessage; 31 32 import com.maverick.crypto.security.SecureRandom; 33 import com.sslexplorer.boot.PropertyClassManager; 34 import com.sslexplorer.boot.Util; 35 import com.sslexplorer.core.CoreUtil; 36 import com.sslexplorer.core.PageInterceptException; 37 import com.sslexplorer.core.PageInterceptListener; 38 import com.sslexplorer.core.RequestParameterMap; 39 import com.sslexplorer.properties.Property; 40 import com.sslexplorer.properties.attributes.AttributeDefinition; 41 import com.sslexplorer.properties.impl.userattributes.UserAttributeKey; 42 import com.sslexplorer.properties.impl.userattributes.UserAttributes; 43 import com.sslexplorer.security.actions.SetPersonalAnswersAction; 44 import com.sslexplorer.security.actions.ShowSetPersonalAnswersAction; 45 46 49 public class PersonalQuestionsAuthenticationModule implements AuthenticationModule { 50 51 final static Log log = LogFactory.getLog(PersonalQuestionsAuthenticationModule.class); 52 53 private AuthenticationScheme session; 54 private PasswordCredentials credentials; 55 private boolean required; 56 57 public final static String [] SECURITY_QUESTIONS = new String [] {"fathersFirstName", "placeOfBirth", "favoriteBook", "mothersMaidenName", "favoriteTVShow" }; 58 private int currentQuestion; 59 private String currentQuestionLabel; 60 61 public static final String MODULE_NAME = "PersonalQuestions"; 62 63 66 PersonalQuestionsAuthenticationModule() { 67 super(); 68 } 69 70 public String getCurrentQuestion() { 71 return currentQuestionLabel; 72 } 73 74 public String getName() { 75 return MODULE_NAME; 76 } 77 78 81 public Credentials authenticate(HttpServletRequest request, RequestParameterMap parameters) 82 throws InvalidLoginCredentialsException, SecurityErrorException, AccountLockedException { 83 84 85 if (session.getUser() == null) { 86 throw new SecurityErrorException(SecurityErrorException.INTERNAL_ERROR, "Personal Question authentication module " 87 + "requires that a previous authentication module has already loaded the User."); 88 } 89 90 String answer = request.getParameter("answer"); 91 if(answer == null || "".equals(answer)) { 92 throw new InvalidLoginCredentialsException("No answer has been provided."); 93 } 94 95 answer = normalizeAnswer(answer.trim()); 96 97 String actualAnswer = normalizeAnswer(Property.getProperty(new UserAttributeKey(session.getUser(), SECURITY_QUESTIONS[currentQuestion]))); 98 if(actualAnswer == null) 99 throw new InvalidLoginCredentialsException("Sorry but you do not have an answer configured. Contact your administrator"); 100 101 if(actualAnswer.equals(answer)) { 102 return new PersonalQuestionsCredentials(session.getUsername(), currentQuestion, answer); 103 } 104 105 throw new InvalidLoginCredentialsException("Your answer was incorrect."); 106 } 107 108 static String normalizeAnswer(String answer) { 109 StringBuffer buf = new StringBuffer (); 110 answer = Util.trimBoth(answer.toLowerCase()); 111 char ch; 112 for(int i = 0 ; i < answer.length() ; i++) { 113 ch = answer.charAt(i); 114 if(ch != ' ') { 115 buf.append(ch); 116 } 117 } 118 return buf.toString(); 119 120 } 121 122 public String getInclude() { 123 return "/WEB-INF/jsp/auth/personalQuestionsAuth.jspf"; 124 } 125 126 public void init(AuthenticationScheme session) { 127 this.session = session; 128 129 } 130 131 public void authenticationComplete() throws SecurityErrorException { 132 } 133 134 public ActionForward startAuthentication(ActionMapping mapping, HttpServletRequest request, HttpServletResponse response) 135 throws SecurityErrorException { 136 required = true; 137 138 try { 139 140 if(session==null) 141 throw new SecurityErrorException(SecurityErrorException.INTERNAL_ERROR, "Invalid use of personal questions module"); 142 143 String answer; 144 boolean canAuth = true; 145 for(int i=0; i< SECURITY_QUESTIONS.length;i++) { 146 answer = Property.getProperty(new UserAttributeKey(session.getUser(), SECURITY_QUESTIONS[i])); 147 if(answer == null || "".equals(answer)) { 148 canAuth = false; 149 break; 150 } 151 } 152 153 154 if(canAuth) { 155 159 if(request.getSession().getAttribute(Constants.PERSONAL_QUESTION)==null) { 160 currentQuestion = SecureRandom.getInstance().nextInt(5); 161 request.getSession().setAttribute(Constants.PERSONAL_QUESTION, new Integer (currentQuestion)); 162 } else { 163 currentQuestion = ((Integer )request.getSession().getAttribute(Constants.PERSONAL_QUESTION)).intValue(); 164 165 } 166 167 currentQuestionLabel = ((AttributeDefinition)PropertyClassManager.getInstance().getPropertyClass(UserAttributes.NAME).getDefinition(SECURITY_QUESTIONS[currentQuestion])).getLabel(); 168 required = true; 169 } else { 170 CoreUtil.addPageInterceptListener(session.getServletSession(), new PersonalAnswersChangeInterceptListener()); 171 request.getSession().setAttribute(Constants.REQ_ATTR_PERSONAL_ANSWERS_CHANGE_REASON_MESSAGE, 172 new ActionMessage("setPersonalAnswers.message.personalAnswersNotSet")); 173 required = false; 174 } 175 176 177 } catch(SecurityErrorException ie) { 178 throw ie; 179 } catch (Exception e) { 180 log.error(e); 181 throw new SecurityErrorException(SecurityErrorException.INTERNAL_ERROR, e, "Failed to get personal questions."); 182 } 183 return mapping.findForward("display"); 184 } 185 186 191 public boolean isRequired() { 192 return required; 193 } 194 195 217 218 219 class PersonalAnswersChangeInterceptListener implements PageInterceptListener { 220 221 public String getId() { 222 return "changePersonalAnswers"; 223 } 224 225 public ActionForward checkForForward(Action action, ActionMapping mapping, HttpServletRequest request, 226 HttpServletResponse response) throws PageInterceptException { 227 if (!(action instanceof ShowSetPersonalAnswersAction) && !(action instanceof SetPersonalAnswersAction)) { 228 return new ActionForward("/showSetPersonalAnswers.do", true); 229 } 230 return null; 231 } 232 233 public boolean isRedirect() { 234 return false; 235 } 236 } 237 238 } | Popular Tags |