I have developed an application using spring-MVC and hibernate, which is having signup page . When user tries to signup , application sends an OTP to user mail and I have maintained this OTP sent by the application in controller class as global variable. So, here the problem is when two users are accessing at a time latest requested user otp is overriding the old one and because of this first user is unable to signup.
1 > Does spring maintain separate session for each user accessing the application? If no ?how to solve this problem?.
Please find below code.
controller class:
package com.uday;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
import javax.servlet.http.HttpServletRequest;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
#Controller
public class ControllerSignUp_Login {
private final Login_DetailsDao dao;
private Login_Details ld = new Login_Details();
private String OtpMailed = "";
private MailSendTest mailSender;
private int chances = 4;
private String emailAdd;
public ControllerSignUp_Login(Login_DetailsDao login_DetailsDao, MailSendTest mailSender) {
this.dao = login_DetailsDao;
this.mailSender = mailSender;
}
#RequestMapping("/hello")
#Transactional
public String diaplay(#RequestParam("name") String name, #RequestParam("pass") String pass, Model m) {
if (dao.isLogoinSuccessfull(name, pass)) {
m.addAttribute("message", "Hello " + name + " You are successfully logged in");
return "Success";
} else {
m.addAttribute("message", "Cannot validate given details.Please try again");
return "login";
}
}
#RequestMapping("/SignUp")
public String redirect() {
System.out.println("ControllerSignUp_Login.display()");
chances = 4;
return "signup";
}
#RequestMapping("/login")
public String display() {
System.out.println("ControllerSignUp_Login.display()");
return "login";
}
#RequestMapping("/updateDetails")
#Transactional
public String display(HttpServletRequest req, Model M) {
String firstName = req.getParameter("firstName");
String lastName = req.getParameter("lastName");
String mobileNo = req.getParameter("mobileNo");
String address = req.getParameter("address");
String email = req.getParameter("email");
String password = req.getParameter("password");
if (checkLength(firstName) && checkLength(lastName) && checkLength(mobileNo) && checkLength(address)
&& checkLength(email) && checkLength(password)) {
ld.setFirstName(firstName);
ld.setLastName(lastName);
ld.setEmail(email);
ld.setAddress(address);
ld.setMobileNo(mobileNo);
ld.setPassword(password);
if (dao.validateMobileAndEmail(mobileNo, email)) {
doSendEmail(email);
M.addAttribute("cMessage", false);
return "ValidationPage";
} else {
M.addAttribute("message", "MobileNo/Email is already registered");
return "signup";
}
} else {
M.addAttribute("message", "SignUp Failed !! All details are mandatory.");
return "signup";
}
}
#RequestMapping("/Home")
public String displayy() {
return "Home";
}
#RequestMapping("/")
public String display1() {
return "login";
}
public boolean checkLength(String s) {
if (s != null && s.length() > 0) {
return true;
}
return false;
}
#Transactional
#RequestMapping("/submitToDB")
public String submitToDataBase(HttpServletRequest req, Model M) {
String otp = req.getParameter("otp");
System.out.println("ControllerSignUp_Login.submitToDataBase()" + otp);
if (OtpMailed.equals(otp)) {
dao.saveEmployee(ld);
chances = 4;
M.addAttribute("message", "SignUp Successfull !! Thank You");
M.addAttribute("displayLogin", true);
return "Success";
} else {
if (chances != 1) {
chances = chances - 1;
M.addAttribute("message", chances + " Chances Left");
return "ValidationPage";
} else {
chances = 4;
M.addAttribute("message", "Authorization failed");
return "signup";
}
}
}
#RequestMapping("/validate")
public String validateOtp() {
return "Success";
}
public String generateOtp() {
String otp = "";
for (int i = 0; i < 4; i++) {
Double d = Math.ceil(Math.random() * 10);
int value = d.intValue();
if (value == 10) {
otp = otp + 1;
} else {
otp = otp + value;
}
}
return otp;
}
public void doSendEmail(String mail) {
try {
this.emailAdd = mail;
String recipientAddress = mail;
String subject = "One Time Verification <Uday>";
String otpGenerated = generateOtp();
this.OtpMailed = otpGenerated;
String message = "Please use this OTP " + otpGenerated + " to signup. ";
mailSender.Send("xxxxxxxxx#gmail.com", "lxrxnxnhmyclvzxs", recipientAddress, subject, message);
} catch (AddressException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#RequestMapping("/resend")
public String resend(Model m) {
doSendEmail(this.emailAdd);
m.addAttribute("message", chances + " Chances Left");
return "ValidationPage";
}
}
Spring REST Controllers are always scoped as singletons (#Controller annotation implies that). You're NOT supposed to re-use private class level variables/fields on method invocation.
If you have global concerns you need to manage/visit outside the scope of a single request, please be sure to separate them to different classes.
Otherwise, the entire modification scope that takes place inside #RequestMapping annotated methods should be method/function-local.
Related
Total Kerberos and Active Directory newb here trying to get a very small sample working.
Found a Java Active Directory JAAS example onLine and here is the code.
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
public class ActiveDirectoryValidator
{
private static final String USERNAME = "FOO";
private static final String PASSWORD = "BAR";
private ActiveDirectoryValidator()
{
}
public boolean validateUser(String userName, String password)
{
try
{
LoginContext lc = null;
ADCallbackHandler ch = new ADCallbackHandler();
ch.setUserId(userName);
ch.setPassword(password);
lc = new LoginContext("JaasConfig", ch);
lc.login();
return true;
}
catch (LoginException le)
{
System.err.println("Authentication failed:");
System.err.println(" " + le.getMessage());
return false;
}
catch (NullPointerException e)
{
System.err.println("Authentication failed:");
System.err.println(" " + e.getMessage());
return false;
}
}
public static void main(String[] args) throws Exception
{
ActiveDirectoryValidator validateUser = new ActiveDirectoryValidator();
if (validateUser.validateUser(USERNAME, PASSWORD))
{
System.out.print("Authentication Successful");
}
else
{
System.out.print("Authentication Failed");
}
}
}
and
import javax.security.auth.callback.*;
import java.io.IOException;
public class ADCallbackHandler implements CallbackHandler
{
private String ADUserId;
private char[] ADPassword;
public void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException
{
for (int i = 0; i < callbacks.length; i++)
{
if (callbacks[i] instanceof NameCallback)
{
NameCallback cb = (NameCallback)callbacks[i];
cb.setName(ADUserId);
}
else if (callbacks[i] instanceof PasswordCallback)
{
PasswordCallback cb = (PasswordCallback)callbacks[i];
cb.setPassword(ADPassword);
}
else
{
throw new UnsupportedCallbackException(callbacks[i]);
}
}
}
public void setUserId(String userid)
{
ADUserId = userid;
}
public void setPassword(String password)
{
ADPassword = new char[password.length()];
password.getChars(0, ADPassword.length, ADPassword, 0);
}
}
Where does the Active Directory Server name go?
I would not expect it to be in the jaas.conf file as I have seen other programs set it via the UI interface and the jaas.conf file never changes.
What am I missing?
Is this example showing something totally different?
Moved my test to a Linux machine and ultimately found 2 missing components.
1 - when executing, I needed to include the
-Djava.security.auth.login.config=mylocation/jaas.conf
2 - I needed to edit the following file to include my Active Directory information
/etc/krb5.conf
After making the necessary references and entries, it worked.
I have a Java Spring Bean called SessionBean that is being shared by multiple users. When a new user accesses my application, an instance of the SessionBean is created. This bean is meant to hold a user's id and privilege information that determines what they can see on my app. However, if a second user access the application at the same time the first user is using it, the created bean is overridden by the second user's credentials and both users use those overridden credentials. How do I make it so that each users SessionBean is independent of other users?
MainController.java
package com.trac.controller;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.trac.verification.*;
import com.trac.bean.SessionBean;
#Controller
public class MainController {
private CompanyOrgVerification org = new CompanyOrgVerification();
#Autowired
private SessionBean session;
#Autowired
private RacfGroupData racfGroup;
//returns the agent search page
#RequestMapping(URIConstants.WELCOME_PAGE)
public ModelAndView welcome(HttpServletRequest request){
this.session = new SessionBean();
String userId = request.getHeader("x-user");
System.out.println(userId.trim());
session.setUserId(userId.trim());
if( racfGroup.getRacfGroups(session.getUserId()) ){
session.setPermission("INFOA", "U"); //Granting the default permissions to anyone with access to the application.
return new ModelAndView("index");
}else{
ModelAndView error = new ModelAndView();
error.setViewName("error");
return error;
}
}
//returns the agent profile page
#RequestMapping(value = URIConstants.PROFILE_PAGE )
public ModelAndView profile(HttpServletRequest request){
Cookie[] cookies = request.getCookies();
String profileEntityNo = "";
for(int i=0; i<cookies.length; i++){
String cookieName = cookies[i].getName().toUpperCase();
switch(cookieName){
case "ENTITYNO": profileEntityNo = cookies[i].getValue().toString().trim();
break;
case "STATE": cookies[i].getValue().toString().trim();
break;
case "NAME": cookies[i].getValue().replace("%20", " ").replace("%2C", ",").trim();
break;
case "DISTRICT": cookies[i].getValue().toString().trim();
break;
}
}
if( session.hasAccessToApp() ){ //check if user is authorized to access page
int structureNo = 3; //company org structure number
String structureCd = "ORG";
org.setSessionBean(session);
org.setProfilePrivileges(profileEntityNo, structureCd, structureNo);
this.setSessionBean( org.getSessionBean() );
ModelAndView profile = new ModelAndView();
profile.setViewName("profile");
profile.addObject("userId", session.getUserId());
profile.addObject("privileges", session.getProfilePrivileges() );
profile.addObject("accessType", session.getAccessType() );
return profile;
}else{
return new ModelAndView("error");
}
}
public SessionBean getSessionBean(){
return session;
}
public void setSessionBean(SessionBean session){
this.session = session;
}
public RacfGroupData getRacfGroup(){
return racfGroup;
}
public void setRacfGroup(RacfGroupData racfGroup){
this.racfGroup = racfGroup;
}
}
SessionBean.java
package com.trac.bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.context.annotation.ScopedProxyMode;
#Component
#Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS )
public class SessionBean {
private String userId;
private String permission = "";
private final int grant_InfoA = 0;
private final int grant_Trac = 1;
private final int grant_Term = 2;
private final int grant_Conf = 3;
private final int grant_Mark = 4;
private boolean[] profilePrivileges = new boolean [ 5 ]; //holds the user privileges for a profile
private String[] accessType = new String[5];
public void setPermission(String permissionValue, String type){
try{
permission = permissionValue;
setPrivileges(type);
}catch(Exception e){
System.out.println("Exception caught in SessionBean - setPermission. "+e.toString());
}
}
public void setPrivileges(String type){
try{
System.out.println("***Permission String: " + this.permission + "***");
//Default Permission
if(permission.equals("INFOA")){
profilePrivileges[grant_InfoA] = true;
accessType[grant_InfoA] = type;
System.out.println("***Granted access to the application***");
}
//Subsidy Tab Permission
else if(permission.equals("TRAC")){
profilePrivileges[grant_Trac] = true;
accessType[grant_Trac] = type;
System.out.println("***Granted access to Trac subsidy***");
}
//Termination Tab Permission
else if(permission.equals("TERM")){
profilePrivileges[grant_Term] = true;
accessType[grant_Term] = type;
System.out.println("***Granted access to termination info***");
}
//Conference Tab Permission
else if(permission.equals("CONF")){
profilePrivileges[grant_Conf] = true;
accessType[grant_Conf] = type;
System.out.println("***Granted access to conference info***");
}
//Service/Transfer & Term Tabs Permission
else if(permission.equals("MARK")){
profilePrivileges[grant_Mark] = true;
accessType[grant_Mark] = type;
System.out.println("***Granted access to Service/Transfer and Term tabs***");
}
else{
System.out.println("No privileges set. Permission string is: "
+ permission);
}
}catch (Exception e){
System.out.println("^^^^ Exception caught in SessionBean."
+ "setPrivileges ^^^^\n" + e.toString());
}
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId.toUpperCase();
}
public boolean hasAccessToApp(){
if( profilePrivileges[grant_InfoA] == true){
return true;
}else{
return false;
}
}
public boolean[] getProfilePrivileges(){
return profilePrivileges;
}
public String[] getAccessType(){
return accessType;
}
}
Ok, this really isn't the solution I was looking for but it got the job done. What I did was in the profile() function of the MainController class I re-pulled the userId from the Header, like what I did in the welcome() function and reset it in the session. I then created a new function in the SessionBean that reset the privileges and accessType arrays and called it in the profile() function of the MainController. This allowed me to pull the correct privileges for a user without any cross contamination from other user privileges.
If anyone has a better solution I am more than happy to hear them.
When I attempt to compile my Play Framework 2.4 project, I receive this error:
`}' expected but eof found.
In /Users/dylhunn/Documents/workspace/my-project/app/controllers/Application.java
This seems to suggest that I failed to match my braces. However, the braces are in fact correctly matched, and the error persists even when I add extra (arbitrarily many) closing curly braces.
I have already tried "activator clean."
Here is my Application.java:
package controllers;
import model.UserAccountManager;
import play.data.Form;
import play.libs.Json;
import play.mvc.*;
import harmony.core.Harmonizer;
import play.twirl.api.Content;
import views.html.*;
import java.net.URLDecoder;
import java.util.*;
import static play.data.Form.form;
public class Application extends Controller {
public Result index() {
if (validSessionIsActive()) return harmonizepage();
else return landing();
}
public Result about() {
Content html = views.html.auxtemplate.render("title", "content");
return ok(html);
}
public Result contact() {
Content html = views.html.auxtemplate.render("title", "content");
return ok(html);
}
public Result landing() {
return ok(views.html.landing.render(form(Credentials.class)));
}
public Result login(String message) {
if (validSessionIsActive()) return index();
if (message == null) message = "";
return ok(views.html.loginpage.render(Form.form(Credentials.class), message));
}
public Result logout() {
String user = session("user-email");
session().clear();
if (user == null) return login("You were not logged in.");
return login("User " + user + " has been logged out.");
}
public Result harmonizepage() {
if (!validSessionIsActive()) return login("Please sign in to acess this page.");
return ok(views.html.harmonize.render());
}
public Result testRegister() {
return ok(views.html.signuppage.render(Form.form(UserData.class));
}
public static class Credentials {
public String email;
public String password;
}
public static class UserData {
public String email;
public String password;
public String name;
public String location;
public String birthday;
}
public Result loginSubmit() {
Form<Credentials> loginForm = form(Credentials.class).bindFromRequest();
if (UserAccountManager.userRegistered(loginForm.get().email)) {
if (UserAccountManager.authenticate(loginForm.get())) { // success
session("user-email", loginForm.get().email);
return harmonizepage();
} else { // Incorrect password
return login("Incorrect password for that email address.");
}
} else { // New user
session("candidate-email", loginForm.get().email);
session("candidate-password", loginForm.get().password);
session("registration-in-progress", "true");
return login("Sorry -- signups are still closed!");
}
}
public Result signupSubmit() {
if (!session("registration-in-progress").equals("true")) return login("");
session("registration-in-progress", "false");
Form<UserData> suForm = form(UserData.class).bindFromRequest();
UserData data = suForm.get();
data.email = session("candidate-email");
data.password = session("candidate-password");
UserAccountManager.registerUser(data);
return index();
}
/**
* Checks the session cookie to see if a valid username is stored there.
*/
public static boolean validSessionIsActive() {
String email = session("user-email");
return UserAccountManager.userRegistered(email);
}
public Result harmonize(String input) {
if (!validSessionIsActive())
return badRequest("No user is currently signed in. Try closing and reopening the site");
try {
input = URLDecoder.decode(input, "UTF-8");
} catch (Exception e) {
return badRequest("The server received an unsupported URL encoding.");
}
List<String> inputChords = Arrays.asList(input.split(" "));
List<List<String>> result = new ArrayList<>();
String str = "";
for (String s : inputChords) str = str + s + " ";
try {
result = Harmonizer.harmonize(str);
} catch (Exception e) { // Harmonizing failed for some reason
return badRequest(e.getMessage());
}
return ok(Json.toJson(result));
}
}
The error message is confusing, but the problem is in the testRegister method. The render call is not properly closed.
return ok(views.html.signuppage.render(Form.form(UserData.class));
should be
return ok(views.html.signuppage.render(Form.form(UserData.class)));
The error message is probably some kind of Scala thing popping up.
I'm building a custom JAAS module for a JMX instance. The file that is being run is the following:
MBean Interface
package com.this.mbean;
public interface ImplementationMBean {
public void setName(String name);
public String getName();
public void setNumber(int number);
public int getNumber();
public boolean getKilled();
public void setKilled(boolean killed);
}
Implementation Class
package com.test.mbean;
public class Implementation implements ImplementationMBean {
private String name ;
private int number;
private boolean killed = false;
public Implementation(String name, int number) {
this.name = name;
this.number = number;
}
#Override
public void setName(String name) {
this.name = name;
}
#Override
public String getName() {
return name;
}
#Override
public void setNumber(int number) {
this.number = number;
}
#Override
public int getNumber() {
return number;
}
#Override
public boolean getKilled() {
return killed;
}
#Override
public void setKilled(boolean killed) {
this.killed = killed;
}
}
RunningImplementation Class
package com.test.running;
import java.lang.management.ManagementFactory;
import com.test.mbean.*;
import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
public class RunningImplementation {
public static final String name = "defaultName";
public static final int number = 100;
public static void main(String[] args)
throws MalformedObjectNameException, InterruptedException,
InstanceAlreadyExistsException, MBeanRegistrationException,
NotCompliantMBeanException{
//get MBean Server
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
//register MBean
ImplementationMBean mBean = new Implementation(name, number);
ObjectName name = new ObjectName("com.bard.mbean:type=ConcreteImplementation");
mbs.registerMBean(mBean, name);
do{
Thread.sleep(1000);
System.out.println("Name = " + mBean.getName() + ", number = " + mBean.getNumber());
}while(mBean.getKilled() == false);
}
}
This is packaged into a JAR file called MBeanSecure.jar.
I've enabled the jmx agent with:
-Dcom.sun.management.jmxremote
I've set it to run on localhost on port 1234:
-Dcom.sun.management.jmxremote.port=1234
I've configured the JMX agent to use a specified JAAS configuration entry:
-Dcom.sun.management.login.config=Sample
and specified the path to the Jaas configuration file:
-Djava.security.auth.login.config=sample_jaas.config
sample_jaas.config
Sample {
sample.module.SampleLoginModule required debug=true;
authIdentity=monitorRole;
};
monitor role is specified in jmxremote.access
-Dcom.sun.management.jmxremote.access.file=jmxremote.access
and looks like this:
monitorRole readonly
controleRole readwrite
my Loginmodule is simple in that is returns true whatever.
SampleLoginModule
package sample.module;
import java.util.*;
import java.io.IOException;
import javax.security.auth.*;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
import javax.security.auth.spi.*;
import sample.principal.SamplePrincipal;
public class SampleLoginModule implements LoginModule {
// initial state
private Subject subject;
private CallbackHandler callbackHandler;
private Map sharedState;
private Map options;
// configurable option
private boolean debug = false;
// the authentication status
private boolean succeeded = false;
private boolean commitSucceeded = false;
// username and password
private String username;
private char[] password;
// testUser's SamplePrincipal
private SamplePrincipal userPrincipal;
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map sharedState, Map options) {
this.subject = subject;
this.callbackHandler = callbackHandler;
this.sharedState = sharedState;
this.options = options;
// initialize any configured options
debug = "true".equalsIgnoreCase((String)options.get("debug"));
}
public boolean login() throws LoginException {
return true;
}
public boolean commit() throws LoginException {
if (succeeded == false) {
return false;
} else {
// add a Principal (authenticated identity)
// to the Subject
// assume the user we authenticated is the SamplePrincipal
userPrincipal = new SamplePrincipal(username);
if (!subject.getPrincipals().contains(userPrincipal))
subject.getPrincipals().add(userPrincipal);
if (debug) {
System.out.println("\t\t[SampleLoginModule] " +
"added SamplePrincipal to Subject");
}
// in any case, clean out state
username = null;
for (int i = 0; i < password.length; i++)
password[i] = ' ';
password = null;
commitSucceeded = true;
return true;
}
}
public boolean abort() throws LoginException {
if (succeeded == false) {
return false;
} else if (succeeded == true && commitSucceeded == false) {
// login succeeded but overall authentication failed
succeeded = false;
username = null;
if (password != null) {
for (int i = 0; i < password.length; i++)
password[i] = ' ';
password = null;
}
userPrincipal = null;
} else {
// overall authentication succeeded and commit succeeded,
// but someone else's commit failed
logout();
}
return true;
}
public boolean logout() throws LoginException {
subject.getPrincipals().remove(userPrincipal);
succeeded = false;
succeeded = commitSucceeded;
username = null;
if (password != null) {
for (int i = 0; i < password.length; i++)
password[i] = ' ';
password = null;
}
userPrincipal = null;
return true;
}
}
with the principal class:
SamplePrincipal
package sample.principal;
import java.security.Principal;
public class SamplePrincipal implements Principal, java.io.Serializable {
private String name;
public SamplePrincipal(String name) {
if (name == null)
throw new NullPointerException("illegal null input");
this.name = name;
}
public String getName() {
return name;
}
public String toString() {
return("SamplePrincipal: " + name);
}
public boolean equals(Object o) {
if (o == null)
return false;
if (this == o)
return true;
if (!(o instanceof SamplePrincipal))
return false;
SamplePrincipal that = (SamplePrincipal)o;
if (this.getName().equals(that.getName()))
return true;
return false;
}
public int hashCode() {
return name.hashCode();
}
}
When I run the code using:
java -Dcom.sun.management.jmxremote.port=1234 -Dcom.sun.management.jmxremote.login.config=Sample -Dcom.java.security.auth.login.config=sample_jaas.config -Djava.security.policy==sampleazn.policy -Dcom.sun.management.jmxremote.access.file=jmxremote.access -jar MBeanSecure.jar
The code runs, regularly outputting
Name = defaultName, number = 100
I then try to access the JMX agent via JConsole
jconsole
and this will open the Jconsole window showing the process running.
However when I try to connect to it as a remote process, I get a Connection Failed error. This is difficult to debug as I can't see any log where this is failing. Am I right in thinking that by using
com.sun.management.jmxremote.login.config
I override the default loginbehaviour? In which case it should check my Jaas config, run the loginmodule, which always returns true, and allow the user under the monitorRole specified?
I believe the error lies in the configuration file, but it's difficult to confirm the settings or debug, given the scarce documentation.
Solved:
I could debug the issues by running:
jconsole -debug
which indicated that my config file had a syntax error, and required:
Sample {
sample.module.SampleLoginModule required debug=true
authIdentity=monitorRole;
};
in place of
Sample {
sample.module.SampleLoginModule required debug=true;
authIdentity=monitorRole;
};
note the single semicolon
I would like to fix the bug in this code.
Change in login method only:
System.out.println("Login Module - login called");
if (callbackHandler == null) {
throw new LoginException("Oops, callbackHandler is null");
}
Callback[] callbacks = new Callback[2];
callbacks[0] = new NameCallback("name:");
callbacks[1] = new PasswordCallback("password:", false);
try {
callbackHandler.handle(callbacks);
} catch (IOException e) {
throw new LoginException("Oops, IOException calling handle on callbackHandler");
} catch (UnsupportedCallbackException e) {
throw new LoginException("Oops, UnsupportedCallbackException calling handle on callbackHandler");
}
NameCallback nameCallback = (NameCallback) callbacks[0];
PasswordCallback passwordCallback = (PasswordCallback) callbacks[1];
String name = nameCallback.getName();
String password = new String(passwordCallback.getPassword());
if ("sohanb".equals(name) && "welcome".equals(password)) {
System.out.println("Success! You get to log in!");
user = new JMXPrincipal(name);
succeeded = true;
return succeeded;
} else {
System.out.println("Failure! You don't get to log in");
succeeded = false;
throw new FailedLoginException("Sorry! No login for you.");
}
Added: user = new JMXPrincipal(name);
Also comment all lines of code in commit() function nd just add :
subject.getPrincipals().add(user);
The application's password recovery functionality sends an email with a link to a page where a user sets a new password. This link does not expire if not used, which makes it possible for an attacker to re-use it in order to compromise an account. How to make a reset password link to expire in 24 hours of sending the user an email?
Can someone tell me what is the approach I should take to solve this issue?
package com.www.actions;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import com.lang.EncryptionUtil;
import com.www.crm.CrmUser;
import com.www.customer.dao.CustomerUtils;
import com.www.interceptors.SessionManager;
import com.www.services.AmsCustomerService;
import com.raleys.www.services.IAmsCustomerService;
public class PasswordUpdateAction extends BaseAction {
/** Comment for <code>serialVersionUID</code> */
private static final long serialVersionUID = 1L;
private final Logger logger = Logger.getLogger(PasswordUpdateAction.class);
private String password1 = null;
private String password2 = null;
private final SessionManager sessionManager;
public PasswordUpdateAction(SessionManager sessionManager) {
this.sessionManager = sessionManager;
}
#Override
public String execute() {
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = ServletActionContext.getRequest().getSession();
IAmsCustomerService amsCustomerService = new AmsCustomerService();
CrmUser crmUser = this.sessionManager.getCrmUser(session);
if (crmUser == null) {
request.setAttribute("errorMsg", LOGIN_MSG);
request.setAttribute("sessionErrorMsg", LOGIN_MSG);
return ERROR;
}
if (StringUtils.isBlank(this.sessionManager.getCredentials(session))) {
request.setAttribute("errorMsg", LOGIN_MSG);
request.setAttribute("sessionErrorMsg", LOGIN_MSG);
return ERROR;
}
String errorMsg = null;
try {
errorMsg = validateForm();
if (StringUtils.isBlank(errorMsg)) {
String encryptedPassword = EncryptionUtil.encodePassword(getPassword1(), "MD5");
crmUser.setPassword(encryptedPassword.toUpperCase());
int success = amsCustomerService.updateCrmUserLocally(crmUser);
if (success == 1) {
request.setAttribute("successMsg", "Your Password Has Been Updated Successfully! ");
return SUCCESS;
} else {
this.logger.error("Error Updating crmUser in Local DB. ");
errorMsg = "Unexpected error occur while updating your password, please try again.";
}
}
} catch (Exception ex) {
this.logger.error("Error, " + ex.getMessage());
errorMsg = "Unexpected error occur while updating your password, please try again.";
}
request.setAttribute("errorMsg", errorMsg);
return ERROR;
}
private String validateForm() {
return CustomerUtils.validatePasswords(getPassword1(), getPassword2());
}
public String getPassword1() {
return this.password1;
}
public void setPassword1(String password1) {
this.password1 = password1;
}
public String getPassword2() {
return this.password2;
}
public void setPassword2(String password2) {
this.password2 = password2;
}
}
Save the Date when the link expires along with the link / link key. When the user tries to change his password using that link, check that the expiry date is in the future.