我试图通过普通用户输入来创建用户,然后将该信息保存在数据库中以便登录。因此,现在用于登录会话,我正在使用 JAAS(Java身份验证和授权服务)。我通过使用“ SHA-256” 哈希算法将密码转换为哈希码来提高此过程的安全性,该算法可生成64位十六进制值。 问题:当我尝试使用注册会话中使用的信息登录时,它无法比较用于登录会话的用户输入值和从数据库接收的数据。 文件:在'AppContext.java','AppLoginModule.java','AppCallbackHandler.java','AppPrincipal.java 和'application_config.config',我正在AppContext.java中注册,登录过程在AppLoginModule.java中完成。
P.S。 :问题出在AppLoginModule.java
代码
AppContext.java
package authentication;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.PrivilegedAction;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import org.apache.commons.codec.digest.DigestUtils;
public class AppContext {
private enum afterLoginActions {action1, action2, logout};
public static void main(String[] args) {
AppContext appContext = new AppContext();
appContext.createUser();
System.setProperty("java.security.auth.login.config", "application_config.config");
LoginContext loginContext = null;
while(true) {
try {
loginContext = new LoginContext("app_config", new AppCallbackHandler());
loginContext.login();
boolean flag = true;
while(flag) {
flag = appContext.performAfterLogin(loginContext);
}
} catch (LoginException | IOException e) {
System.out.println(e.getMessage());
}
}
}
private boolean performAfterLogin(LoginContext loginContext) throws IOException, LoginException {
boolean flag = true;
System.out.println("Please specify any action: { usage: action1, action2, logout }");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
switch (afterLoginActions.valueOf(br.readLine())) {
case action1:
PrivilegedAction<Object> privilegedAction1 = () -> {
System.out.println("action1 was performed..");
return null;
};
Subject.doAs(loginContext.getSubject(), privilegedAction1);
System.out.println("by " + loginContext.getSubject().getPrincipals().iterator().next().getName());
break;
case action2:
PrivilegedAction<Object> privilegedAction2 = () -> {
System.out.println("action2 was performed..");
return null;
};
Subject.doAs(loginContext.getSubject(), privilegedAction2);
System.out.println("by " + loginContext.getSubject().getPrincipals().iterator().next().getName());
break;
case logout:
loginContext.logout();
System.out.println("You are now logged out...");
flag = false;
break;
}
} catch (IllegalArgumentException e) {
System.out.println("Invalid entry...");
}
return flag;
}
private String encryption(String password) {
new DigestUtils("SHA-256");
String encryptedData = DigestUtils.sha256Hex(password);
return encryptedData;
}
private void createUser() {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jaas_db?useSSL=false&user=root&password=puneet");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Your Name: ");
String name = br.readLine() + "\n";
System.out.print("Your email: ");
String email = br.readLine() + "\n";
System.out.print("Your password: ");
String e_password = encryption(br.readLine());
System.out.println("Encrypted password: (createUser): " + e_password);
PreparedStatement ps = con.prepareStatement("INSERT INTO users VALUES(?, ?, ?)");
ps.setString(1, name);
ps.setString(2, e_password);
ps.setString(3, email);
ps.execute();
ps.close();
con.close();
} catch (Exception e) {
System.err.println("mysql error: " + e.getMessage());
}
}
}
AppLoginModule.java
package authentication;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.TextInputCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import org.apache.commons.codec.digest.DigestUtils;
public class AppLoginModule implements LoginModule {
private Subject subject;
private CallbackHandler callbackHandler;
private AppPrincipal appPrincipal;
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
Map<String, ?> options) {
this.subject = subject;
this.callbackHandler = callbackHandler;
}
private String encryption(String password) {
new DigestUtils("SHA-256");
String encryptedData = DigestUtils.sha256Hex(password);
return encryptedData;
}
@Override
public boolean login() throws LoginException {
boolean flag = false;
Callback[] callbacks = new Callback[2];
callbacks[0] = new TextInputCallback("Your email: ");
callbacks[1] = new PasswordCallback("Your password: ", false);
try {
callbackHandler.handle(callbacks);
String email = ((TextInputCallback) callbacks[0]).getText();
// Encrypting password
String encryptPassword = encryption(new String(((PasswordCallback) callbacks[1]).getPassword()));
System.out.println("Encrypted Password: " + password);
// Verifying with SQL data
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jaas_db?user=root&password=puneet&useSSL=false");
Statement s = con.createStatement();
s.executeQuery("SELECT * FROM users");
ResultSet rs = s.getResultSet();
int i = 0;
if(rs != null)
while(rs.next()) {
System.out.println(rs.getString(1) + "\n" + rs.getString(2) + "\n" + rs.getString(3));
if(email.equalsIgnoreCase(rs.getString(3)) && encryptPassword.equalsIgnoreCase(rs.getString(2))) {
System.out.println("authentication successfull...");
flag = true;
break;
}
i = i + 1;
}
} catch (Exception e) {
System.err.println("MySql error: " + e.getMessage());
}
if(flag == false)
throw new FailedLoginException("authentication failure...");
} catch (IOException | UnsupportedCallbackException e) {
e.printStackTrace();
}
return flag;
}
@Override
public boolean commit() throws LoginException {
boolean flag = false;
if(subject != null && !subject.getPrincipals().contains(appPrincipal)) {
subject.getPrincipals().add(appPrincipal);
flag = true;
}
return flag;
}
@Override
public boolean abort() throws LoginException {
if(subject != null && appPrincipal != null && subject.getPrincipals().contains(appPrincipal))
subject.getPrincipals().remove(appPrincipal);
subject = null;
appPrincipal = null;
return true;
}
@Override
public boolean logout() throws LoginException {
subject.getPrincipals().remove(appPrincipal);
subject = null;
return true;
}
}
AppCallbackHandler.java
package authentication;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.TextInputCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
public class AppCallbackHandler implements CallbackHandler {
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
TextInputCallback textInputCallback = (TextInputCallback) callbacks[0];
System.out.println(textInputCallback.getPrompt());
textInputCallback.setText(new BufferedReader(new InputStreamReader(System.in)).readLine());
PasswordCallback passwordCallback = (PasswordCallback) callbacks[1];
System.out.println(passwordCallback.getPrompt());
passwordCallback.setPassword(new BufferedReader(new InputStreamReader(System.in)).readLine().toCharArray());
}
}
/* AppPrincipal */
package authentication;
import java.io.Serializable;
import java.security.Principal;
public class AppPrincipal implements Principal, Serializable {
private static final long serialVersionUID = 1L;
private String name;
public AppPrincipal(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public boolean equals(Object object) {
boolean flag = false;
if(object instanceof AppPrincipal)
flag = name.equals(((AppPrincipal) object).getName());
return flag;
}
}
/* application_config.config */
app_config {
authentication.AppLoginModule required debug=true;
};