xmpp with openfire之四 扩展的AuthProvider
2011-07-05 23:14
375 查看
上一篇中提到jdbcAuthProvider.passwordType提供了三种方式
如果你的密码加密规则不是这三种方式,可以自己进行扩充
首先,下载openfire的源码
http://www.igniterealtime.org/downloads/source.jsp
打开org.jivesoftware.openfire.auth.JDBCAuthProvider
Java代码
package org.jivesoftware.openfire.auth;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.user.UserAlreadyExistsException;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils;
import java.sql.*;
/**
* The JDBC auth provider allows you to authenticate users against any database
* that you can connect to with JDBC. It can be used along with the
* {@link HybridAuthProvider hybrid} auth provider, so that you can also have
* XMPP-only users that won't pollute your external data.<p>
*
* To enable this provider, set the following in the system properties:
* <ul>
* <li><tt>provider.auth.className = org.jivesoftware.openfire.auth.JDBCAuthProvider</tt></li>
* </ul>
*
* You'll also need to set your JDBC driver, connection string, and SQL statements:
*
* <ul>
* <li><tt>jdbcProvider.driver = com.mysql.jdbc.Driver</tt></li>
* <li><tt>jdbcProvider.connectionString = jdbc:mysql://localhost/dbname?user=username&password=secret</tt></li>
* <li><tt>jdbcAuthProvider.passwordSQL = SELECT password FROM user_account WHERE username=?</tt></li>
* <li><tt>jdbcAuthProvider.passwordType = plain</tt></li>
* <li><tt>jdbcAuthProvider.allowUpdate = true</tt></li>
* <li><tt>jdbcAuthProvider.setPasswordSQL = UPDATE user_account SET password=? WHERE username=?</tt></li>
* </ul>
*
* The passwordType setting tells Openfire how the password is stored. Setting the value
* is optional (when not set, it defaults to "plain"). The valid values are:<ul>
* <li>{@link PasswordType#plain plain}
* <li>{@link PasswordType#md5 md5}
* <li>{@link PasswordType#sha1 sha1}
* </ul>
*
* @author David Snopek
*/
public class JDBCAuthProvider implements AuthProvider {
private String connectionString;
private String passwordSQL;
private String setPasswordSQL;
private PasswordType passwordType;
private boolean allowUpdate;
/**
* Constructs a new JDBC authentication provider.
*/
public JDBCAuthProvider() {
// Convert XML based provider setup to Database based
JiveGlobals.migrateProperty("jdbcProvider.driver");
JiveGlobals.migrateProperty("jdbcProvider.connectionString");
JiveGlobals.migrateProperty("jdbcAuthProvider.passwordSQL");
JiveGlobals.migrateProperty("jdbcAuthProvider.passwordType");
JiveGlobals.migrateProperty("jdbcAuthProvider.setPasswordSQL");
JiveGlobals.migrateProperty("jdbcAuthProvider.allowUpdate");
// Load the JDBC driver and connection string.
String jdbcDriver = JiveGlobals.getProperty("jdbcProvider.driver");
try {
Class.forName(jdbcDriver).newInstance();
}
catch (Exception e) {
Log.error("Unable to load JDBC driver: " + jdbcDriver, e);
return;
}
connectionString = JiveGlobals.getProperty("jdbcProvider.connectionString");
// Load SQL statements.
passwordSQL = JiveGlobals.getProperty("jdbcAuthProvider.passwordSQL");
setPasswordSQL = JiveGlobals.getProperty("jdbcAuthProvider.setPasswordSQL");
allowUpdate = JiveGlobals.getBooleanProperty("jdbcAuthProvider.allowUpdate",false);
passwordType = PasswordType.plain;
try {
passwordType = PasswordType.valueOf(
JiveGlobals.getProperty("jdbcAuthProvider.passwordType", "plain"));
}
catch (IllegalArgumentException iae) {
Log.error(iae);
}
}
public void authenticate(String username, String password) throws UnauthorizedException {
if (username == null || password == null) {
throw new UnauthorizedException();
}
username = username.trim().toLowerCase();
if (username.contains("@")) {
// Check that the specified domain matches the server's domain
int index = username.indexOf("@");
String domain = username.substring(index + 1);
if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
username = username.substring(0, index);
} else {
// Unknown domain. Return authentication failed.
throw new UnauthorizedException();
}
}
String userPassword;
try {
userPassword = getPasswordValue(username);
}
catch (UserNotFoundException unfe) {
throw new UnauthorizedException();
}
// If the user's password doesn't match the password passed in, authentication
// should fail.
if (passwordType == PasswordType.md5) {
password = StringUtils.hash(password, "MD5");
}
else if (passwordType == PasswordType.sha1) {
password = StringUtils.hash(password, "SHA-1");
}
if (!password.equals(userPassword)) {
throw new UnauthorizedException();
}
// Got this far, so the user must be authorized.
createUser(username);
}
public void authenticate(String username, String token, String digest)
throws UnauthorizedException
{
if (passwordType != PasswordType.plain) {
throw new UnsupportedOperationException("Digest authentication not supported for "
+ "password type " + passwordType);
}
if (username == null || token == null || digest == null) {
throw new UnauthorizedException();
}
username = username.trim().toLowerCase();
if (username.contains("@")) {
// Check that the specified domain matches the server's domain
int index = username.indexOf("@");
String domain = username.substring(index + 1);
if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
username = username.substring(0, index);
} else {
// Unknown domain. Return authentication failed.
throw new UnauthorizedException();
}
}
String password;
try {
password = getPasswordValue(username);
}
catch (UserNotFoundException unfe) {
throw new UnauthorizedException();
}
String anticipatedDigest = AuthFactory.createDigest(token, password);
if (!digest.equalsIgnoreCase(anticipatedDigest)) {
throw new UnauthorizedException();
}
// Got this far, so the user must be authorized.
createUser(username);
}
public boolean isPlainSupported() {
// If the auth SQL is defined, plain text authentication is supported.
return (passwordSQL != null);
}
public boolean isDigestSupported() {
// The auth SQL must be defined and the password type is supported.
return (passwordSQL != null && passwordType == PasswordType.plain);
}
public String getPassword(String username) throws UserNotFoundException,
UnsupportedOperationException
{
if (!supportsPasswordRetrieval()) {
throw new UnsupportedOperationException();
}
if (username.contains("@")) {
// Check that the specified domain matches the server's domain
int index = username.indexOf("@");
String domain = username.substring(index + 1);
if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
username = username.substring(0, index);
} else {
// Unknown domain.
throw new UserNotFoundException();
}
}
return getPasswordValue(username);
}
public void setPassword(String username, String password)
throws UserNotFoundException, UnsupportedOperationException
{
if (allowUpdate && setPasswordSQL != null) {
setPasswordValue(username, password);
} else {
throw new UnsupportedOperationException();
}
}
public boolean supportsPasswordRetrieval() {
return (passwordSQL != null && passwordType == PasswordType.plain);
}
/**
* Returns the value of the password field. It will be in plain text or hashed
* format, depending on the password type.
*
* @param username user to retrieve the password field for
* @return the password value.
* @throws UserNotFoundException if the given user could not be loaded.
*/
private String getPasswordValue(String username) throws UserNotFoundException {
String password = null;
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
if (username.contains("@")) {
// Check that the specified domain matches the server's domain
int index = username.indexOf("@");
String domain = username.substring(index + 1);
if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
username = username.substring(0, index);
} else {
// Unknown domain.
throw new UserNotFoundException();
}
}
try {
con = DriverManager.getConnection(connectionString);
pstmt = con.prepareStatement(passwordSQL);
pstmt.setString(1, username);
rs = pstmt.executeQuery();
// If the query had no results, the username and password
// did not match a user record. Therefore, throw an exception.
if (!rs.next()) {
throw new UserNotFoundException();
}
password = rs.getString(1);
}
catch (SQLException e) {
Log.error("Exception in JDBCAuthProvider", e);
throw new UserNotFoundException();
}
finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
return password;
}
private void setPasswordValue(String username, String password) throws UserNotFoundException {
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
if (username.contains("@")) {
// Check that the specified domain matches the server's domain
int index = username.indexOf("@");
String domain = username.substring(index + 1);
if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
username = username.substring(0, index);
} else {
// Unknown domain.
throw new UserNotFoundException();
}
}
try {
con = DriverManager.getConnection(connectionString);
pstmt = con.prepareStatement(setPasswordSQL);
pstmt.setString(1, username);
if (passwordType == PasswordType.md5) {
password = StringUtils.hash(password, "MD5");
}
else if (passwordType == PasswordType.sha1) {
password = StringUtils.hash(password, "SHA-1");
}
pstmt.setString(2, password);
rs = pstmt.executeQuery();
}
catch (SQLException e) {
Log.error("Exception in JDBCAuthProvider", e);
throw new UserNotFoundException();
}
finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
}
/**
* Indicates how the password is stored.
*/
@SuppressWarnings({"UnnecessarySemicolon"}) // Support for QDox Parser
public enum PasswordType {
/**
* The password is stored as plain text.
*/
plain,
/**
* The password is stored as a hex-encoded MD5 hash.
*/
md5,
/**
* The password is stored as a hex-encoded SHA-1 hash.
*/
sha1;
}
/**
* Checks to see if the user exists; if not, a new user is created.
*
* @param username the username.
*/
private static void createUser(String username) {
// See if the user exists in the database. If not, automatically create them.
UserManager userManager = UserManager.getInstance();
try {
userManager.getUser(username);
}
catch (UserNotFoundException unfe) {
try {
Log.debug("JDBCAuthProvider: Automatically creating new user account for " + username);
UserManager.getUserProvider().createUser(username, StringUtils.randomString(8),
null, null);
}
catch (UserAlreadyExistsException uaee) {
// Ignore.
}
}
}
}
看以看到通过读取PASSWORDTYPE配置
Java代码
JiveGlobals.migrateProperty("jdbcAuthProvider.passwordType"); 。。。。。 。。。。。 。。。。。 passwordType = PasswordType.plain; try { passwordType = PasswordType.valueOf( JiveGlobals.getProperty("jdbcAuthProvider.passwordType", "plain")); } catch (IllegalArgumentException iae) { Log.error(iae); }
进行密码的验证
Java代码
if (passwordType == PasswordType.md5) {
password = StringUtils.hash(password, "MD5");
}
else if (passwordType == PasswordType.sha1) {
password = StringUtils.hash(password, "SHA-1");
}
if (!password.equals(userPassword)) {
throw new UnauthorizedException();
}
这样完全可以仿照JDBCAuthProvider重新构造
Java代码
package org.yxsoft.openfire.plugin; import org.jivesoftware.openfire.user.UserNotFoundException; import org.jivesoftware.openfire.auth.*; import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.Log; import org.jivesoftware.util.StringUtils; import org.jivesoftware.database.DbConnectionManager; import java.sql.*; import java.security.MessageDigest; /** * Created by cl * Date: 2008-9-4 * Time: 9:18:26 * 仿照JDBCAuthProvider * 在数据库连接上 支持user/password * 密码验证 使用bfmp的机制 */ public class BfmpAuthProvider implements AuthProvider { private String connectionString; private String user; private String password; private String passwordSQL; private String setPasswordSQL; private PasswordType passwordType; private boolean allowUpdate; /** * 初始化 * 比JDBCAuthProvider多支持 * JiveGlobals.migrateProperty("jdbcProvider.url"); JiveGlobals.migrateProperty("jdbcProvider.user"); JiveGlobals.migrateProperty("jdbcProvider.password"); */ public BfmpAuthProvider() { // Convert XML based provider setup to Database based JiveGlobals.migrateProperty("jdbcProvider.driver"); JiveGlobals.migrateProperty("jdbcProvider.url"); JiveGlobals.migrateProperty("jdbcProvider.user"); JiveGlobals.migrateProperty("jdbcProvider.password"); JiveGlobals.migrateProperty("jdbcAuthProvider.passwordSQL"); JiveGlobals.migrateProperty("jdbcAuthProvider.passwordType"); JiveGlobals.migrateProperty("jdbcAuthProvider.setPasswordSQL"); JiveGlobals.migrateProperty("jdbcAuthProvider.allowUpdate"); JiveGlobals.migrateProperty("jdbcAuthProvider.passwordType"); // Load the JDBC driver and connection string. String jdbcDriver = JiveGlobals.getProperty("jdbcProvider.driver"); try { Class.forName(jdbcDriver).newInstance(); } catch (Exception e) { Log.error("Unable to load JDBC driver: " + jdbcDriver, e); return; } connectionString = JiveGlobals.getProperty("jdbcProvider.url"); user = JiveGlobals.getProperty("jdbcProvider.user"); password = JiveGlobals.getProperty("jdbcProvider.password"); // Load SQL statements. passwordSQL = JiveGlobals.getProperty("jdbcAuthProvider.passwordSQL"); setPasswordSQL = JiveGlobals.getProperty("jdbcAuthProvider.setPasswordSQL"); allowUpdate = JiveGlobals.getBooleanProperty("jdbcAuthProvider.allowUpdate",false); passwordType = PasswordType.plain; try { passwordType = PasswordType.valueOf( JiveGlobals.getProperty("jdbcAuthProvider.passwordType", "plain")); Log.error("PasswordType:"+ passwordType); } catch (IllegalArgumentException iae) { Log.error(iae); } } public boolean isPlainSupported() { //default return true; } public boolean isDigestSupported() { //default return true; } public void authenticate(String username, String password) throws UnauthorizedException, ConnectionException, InternalUnauthenticatedException { if (username == null || password == null) { throw new UnauthorizedException(); } Log.error(username+":"+password); username = username.trim().toLowerCase(); if (username.contains("@")) { Log.error(username+":"+XMPPServer.getInstance().getServerInfo().getXMPPDomain()); // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. Return authentication failed. throw new UnauthorizedException(); } } else { Log.error("user name not contains "); } String userPassword; try { userPassword = getPasswordValue(username); } catch (UserNotFoundException unfe) { throw new UnauthorizedException(); } // If the user's password doesn't match the password passed in, authentication // should fail. if (passwordType == PasswordType.bfmp) { //这里BfmpMD5 就是自己的密码规则 password = BfmpMD5(password); } if (!password.equals(userPassword)) { throw new UnauthorizedException(); } // Got this far, so the user must be authorized. //createUser(username); } public void authenticate(String username, String token, String digest) throws UnauthorizedException, ConnectionException, InternalUnauthenticatedException { if (passwordType != PasswordType.plain) { throw new UnsupportedOperationException("Digest authentication not supported for " + "password type " + passwordType); } if (username == null || token == null || digest == null) { throw new UnauthorizedException(); } username = username.trim().toLowerCase(); if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. Return authentication failed. throw new UnauthorizedException(); } } String password; try { password = getPasswordValue(username); } catch (UserNotFoundException unfe) { throw new UnauthorizedException(); } String anticipatedDigest = AuthFactory.createDigest(token, password); if (!digest.equalsIgnoreCase(anticipatedDigest)) { throw new UnauthorizedException(); } // Got this far, so the user must be authorized. //createUser(username); } public String getPassword(String username) throws UserNotFoundException, UnsupportedOperationException { if (!supportsPasswordRetrieval()) { throw new UnsupportedOperationException(); } if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. throw new UserNotFoundException(); } } return getPasswordValue(username); } private String getPasswordValue(String username) throws UserNotFoundException { String password = null; Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. throw new UserNotFoundException(); } } try { con = DriverManager.getConnection(connectionString, user, this.password); pstmt = con.prepareStatement(passwordSQL); pstmt.setString(1, username); rs = pstmt.executeQuery(); // If the query had no results, the username and password // did not match a user record. Therefore, throw an exception. if (!rs.next()) { throw new UserNotFoundException(); } password = rs.getString(1); } catch (SQLException e) { Log.error("Exception in JDBCAuthProvider", e); throw new UserNotFoundException(); } finally { DbConnectionManager.closeConnection(rs, pstmt, con); } return password; } public void setPassword(String username, String password) throws UserNotFoundException, UnsupportedOperationException { // unsupport } public boolean supportsPasswordRetrieval() { return true; } /** * Indicates how the password is stored. */ @SuppressWarnings({"UnnecessarySemicolon"}) // Support for QDox Parser public enum PasswordType { /** * The password is stored as plain text. */ plain, /** * The password is stored as a bfmp passwrod. */ bfmp; } private String BfmpMD5 (String source) { //在这里实现你的加密机制,返回生成的密码 return ""; } }
编译后将此class加入到lib/openfire.jar中即可
当然不要忘记 将系统属性中
provider.auth.className,改成你自已的Provider
*上述代码例子中是org.yxsoft.openfire.plugin.BFMPAuthProvider
jdbcAuthProvider.passwordType,改成你自己定义的枚举值
*上述代码例子中是bfmp
如果你的密码加密规则不是这三种方式,可以自己进行扩充
首先,下载openfire的源码
http://www.igniterealtime.org/downloads/source.jsp
打开org.jivesoftware.openfire.auth.JDBCAuthProvider
Java代码
package org.jivesoftware.openfire.auth;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.user.UserAlreadyExistsException;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils;
import java.sql.*;
/**
* The JDBC auth provider allows you to authenticate users against any database
* that you can connect to with JDBC. It can be used along with the
* {@link HybridAuthProvider hybrid} auth provider, so that you can also have
* XMPP-only users that won't pollute your external data.<p>
*
* To enable this provider, set the following in the system properties:
* <ul>
* <li><tt>provider.auth.className = org.jivesoftware.openfire.auth.JDBCAuthProvider</tt></li>
* </ul>
*
* You'll also need to set your JDBC driver, connection string, and SQL statements:
*
* <ul>
* <li><tt>jdbcProvider.driver = com.mysql.jdbc.Driver</tt></li>
* <li><tt>jdbcProvider.connectionString = jdbc:mysql://localhost/dbname?user=username&password=secret</tt></li>
* <li><tt>jdbcAuthProvider.passwordSQL = SELECT password FROM user_account WHERE username=?</tt></li>
* <li><tt>jdbcAuthProvider.passwordType = plain</tt></li>
* <li><tt>jdbcAuthProvider.allowUpdate = true</tt></li>
* <li><tt>jdbcAuthProvider.setPasswordSQL = UPDATE user_account SET password=? WHERE username=?</tt></li>
* </ul>
*
* The passwordType setting tells Openfire how the password is stored. Setting the value
* is optional (when not set, it defaults to "plain"). The valid values are:<ul>
* <li>{@link PasswordType#plain plain}
* <li>{@link PasswordType#md5 md5}
* <li>{@link PasswordType#sha1 sha1}
* </ul>
*
* @author David Snopek
*/
public class JDBCAuthProvider implements AuthProvider {
private String connectionString;
private String passwordSQL;
private String setPasswordSQL;
private PasswordType passwordType;
private boolean allowUpdate;
/**
* Constructs a new JDBC authentication provider.
*/
public JDBCAuthProvider() {
// Convert XML based provider setup to Database based
JiveGlobals.migrateProperty("jdbcProvider.driver");
JiveGlobals.migrateProperty("jdbcProvider.connectionString");
JiveGlobals.migrateProperty("jdbcAuthProvider.passwordSQL");
JiveGlobals.migrateProperty("jdbcAuthProvider.passwordType");
JiveGlobals.migrateProperty("jdbcAuthProvider.setPasswordSQL");
JiveGlobals.migrateProperty("jdbcAuthProvider.allowUpdate");
// Load the JDBC driver and connection string.
String jdbcDriver = JiveGlobals.getProperty("jdbcProvider.driver");
try {
Class.forName(jdbcDriver).newInstance();
}
catch (Exception e) {
Log.error("Unable to load JDBC driver: " + jdbcDriver, e);
return;
}
connectionString = JiveGlobals.getProperty("jdbcProvider.connectionString");
// Load SQL statements.
passwordSQL = JiveGlobals.getProperty("jdbcAuthProvider.passwordSQL");
setPasswordSQL = JiveGlobals.getProperty("jdbcAuthProvider.setPasswordSQL");
allowUpdate = JiveGlobals.getBooleanProperty("jdbcAuthProvider.allowUpdate",false);
passwordType = PasswordType.plain;
try {
passwordType = PasswordType.valueOf(
JiveGlobals.getProperty("jdbcAuthProvider.passwordType", "plain"));
}
catch (IllegalArgumentException iae) {
Log.error(iae);
}
}
public void authenticate(String username, String password) throws UnauthorizedException {
if (username == null || password == null) {
throw new UnauthorizedException();
}
username = username.trim().toLowerCase();
if (username.contains("@")) {
// Check that the specified domain matches the server's domain
int index = username.indexOf("@");
String domain = username.substring(index + 1);
if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
username = username.substring(0, index);
} else {
// Unknown domain. Return authentication failed.
throw new UnauthorizedException();
}
}
String userPassword;
try {
userPassword = getPasswordValue(username);
}
catch (UserNotFoundException unfe) {
throw new UnauthorizedException();
}
// If the user's password doesn't match the password passed in, authentication
// should fail.
if (passwordType == PasswordType.md5) {
password = StringUtils.hash(password, "MD5");
}
else if (passwordType == PasswordType.sha1) {
password = StringUtils.hash(password, "SHA-1");
}
if (!password.equals(userPassword)) {
throw new UnauthorizedException();
}
// Got this far, so the user must be authorized.
createUser(username);
}
public void authenticate(String username, String token, String digest)
throws UnauthorizedException
{
if (passwordType != PasswordType.plain) {
throw new UnsupportedOperationException("Digest authentication not supported for "
+ "password type " + passwordType);
}
if (username == null || token == null || digest == null) {
throw new UnauthorizedException();
}
username = username.trim().toLowerCase();
if (username.contains("@")) {
// Check that the specified domain matches the server's domain
int index = username.indexOf("@");
String domain = username.substring(index + 1);
if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
username = username.substring(0, index);
} else {
// Unknown domain. Return authentication failed.
throw new UnauthorizedException();
}
}
String password;
try {
password = getPasswordValue(username);
}
catch (UserNotFoundException unfe) {
throw new UnauthorizedException();
}
String anticipatedDigest = AuthFactory.createDigest(token, password);
if (!digest.equalsIgnoreCase(anticipatedDigest)) {
throw new UnauthorizedException();
}
// Got this far, so the user must be authorized.
createUser(username);
}
public boolean isPlainSupported() {
// If the auth SQL is defined, plain text authentication is supported.
return (passwordSQL != null);
}
public boolean isDigestSupported() {
// The auth SQL must be defined and the password type is supported.
return (passwordSQL != null && passwordType == PasswordType.plain);
}
public String getPassword(String username) throws UserNotFoundException,
UnsupportedOperationException
{
if (!supportsPasswordRetrieval()) {
throw new UnsupportedOperationException();
}
if (username.contains("@")) {
// Check that the specified domain matches the server's domain
int index = username.indexOf("@");
String domain = username.substring(index + 1);
if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
username = username.substring(0, index);
} else {
// Unknown domain.
throw new UserNotFoundException();
}
}
return getPasswordValue(username);
}
public void setPassword(String username, String password)
throws UserNotFoundException, UnsupportedOperationException
{
if (allowUpdate && setPasswordSQL != null) {
setPasswordValue(username, password);
} else {
throw new UnsupportedOperationException();
}
}
public boolean supportsPasswordRetrieval() {
return (passwordSQL != null && passwordType == PasswordType.plain);
}
/**
* Returns the value of the password field. It will be in plain text or hashed
* format, depending on the password type.
*
* @param username user to retrieve the password field for
* @return the password value.
* @throws UserNotFoundException if the given user could not be loaded.
*/
private String getPasswordValue(String username) throws UserNotFoundException {
String password = null;
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
if (username.contains("@")) {
// Check that the specified domain matches the server's domain
int index = username.indexOf("@");
String domain = username.substring(index + 1);
if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
username = username.substring(0, index);
} else {
// Unknown domain.
throw new UserNotFoundException();
}
}
try {
con = DriverManager.getConnection(connectionString);
pstmt = con.prepareStatement(passwordSQL);
pstmt.setString(1, username);
rs = pstmt.executeQuery();
// If the query had no results, the username and password
// did not match a user record. Therefore, throw an exception.
if (!rs.next()) {
throw new UserNotFoundException();
}
password = rs.getString(1);
}
catch (SQLException e) {
Log.error("Exception in JDBCAuthProvider", e);
throw new UserNotFoundException();
}
finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
return password;
}
private void setPasswordValue(String username, String password) throws UserNotFoundException {
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
if (username.contains("@")) {
// Check that the specified domain matches the server's domain
int index = username.indexOf("@");
String domain = username.substring(index + 1);
if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
username = username.substring(0, index);
} else {
// Unknown domain.
throw new UserNotFoundException();
}
}
try {
con = DriverManager.getConnection(connectionString);
pstmt = con.prepareStatement(setPasswordSQL);
pstmt.setString(1, username);
if (passwordType == PasswordType.md5) {
password = StringUtils.hash(password, "MD5");
}
else if (passwordType == PasswordType.sha1) {
password = StringUtils.hash(password, "SHA-1");
}
pstmt.setString(2, password);
rs = pstmt.executeQuery();
}
catch (SQLException e) {
Log.error("Exception in JDBCAuthProvider", e);
throw new UserNotFoundException();
}
finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
}
/**
* Indicates how the password is stored.
*/
@SuppressWarnings({"UnnecessarySemicolon"}) // Support for QDox Parser
public enum PasswordType {
/**
* The password is stored as plain text.
*/
plain,
/**
* The password is stored as a hex-encoded MD5 hash.
*/
md5,
/**
* The password is stored as a hex-encoded SHA-1 hash.
*/
sha1;
}
/**
* Checks to see if the user exists; if not, a new user is created.
*
* @param username the username.
*/
private static void createUser(String username) {
// See if the user exists in the database. If not, automatically create them.
UserManager userManager = UserManager.getInstance();
try {
userManager.getUser(username);
}
catch (UserNotFoundException unfe) {
try {
Log.debug("JDBCAuthProvider: Automatically creating new user account for " + username);
UserManager.getUserProvider().createUser(username, StringUtils.randomString(8),
null, null);
}
catch (UserAlreadyExistsException uaee) {
// Ignore.
}
}
}
}
package org.jivesoftware.openfire.auth; import org.jivesoftware.database.DbConnectionManager; import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.user.UserAlreadyExistsException; import org.jivesoftware.openfire.user.UserManager; import org.jivesoftware.openfire.user.UserNotFoundException; import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.Log; import org.jivesoftware.util.StringUtils; import java.sql.*; /** * The JDBC auth provider allows you to authenticate users against any database * that you can connect to with JDBC. It can be used along with the * {@link HybridAuthProvider hybrid} auth provider, so that you can also have * XMPP-only users that won't pollute your external data.<p> * * To enable this provider, set the following in the system properties: * <ul> * <li><tt>provider.auth.className = org.jivesoftware.openfire.auth.JDBCAuthProvider</tt></li> * </ul> * * You'll also need to set your JDBC driver, connection string, and SQL statements: * * <ul> * <li><tt>jdbcProvider.driver = com.mysql.jdbc.Driver</tt></li> * <li><tt>jdbcProvider.connectionString = jdbc:mysql://localhost/dbname?user=username&password=secret</tt></li> * <li><tt>jdbcAuthProvider.passwordSQL = SELECT password FROM user_account WHERE username=?</tt></li> * <li><tt>jdbcAuthProvider.passwordType = plain</tt></li> * <li><tt>jdbcAuthProvider.allowUpdate = true</tt></li> * <li><tt>jdbcAuthProvider.setPasswordSQL = UPDATE user_account SET password=? WHERE username=?</tt></li> * </ul> * * The passwordType setting tells Openfire how the password is stored. Setting the value * is optional (when not set, it defaults to "plain"). The valid values are:<ul> * <li>{@link PasswordType#plain plain} * <li>{@link PasswordType#md5 md5} * <li>{@link PasswordType#sha1 sha1} * </ul> * * @author David Snopek */ public class JDBCAuthProvider implements AuthProvider { private String connectionString; private String passwordSQL; private String setPasswordSQL; private PasswordType passwordType; private boolean allowUpdate; /** * Constructs a new JDBC authentication provider. */ public JDBCAuthProvider() { // Convert XML based provider setup to Database based JiveGlobals.migrateProperty("jdbcProvider.driver"); JiveGlobals.migrateProperty("jdbcProvider.connectionString"); JiveGlobals.migrateProperty("jdbcAuthProvider.passwordSQL"); JiveGlobals.migrateProperty("jdbcAuthProvider.passwordType"); JiveGlobals.migrateProperty("jdbcAuthProvider.setPasswordSQL"); JiveGlobals.migrateProperty("jdbcAuthProvider.allowUpdate"); // Load the JDBC driver and connection string. String jdbcDriver = JiveGlobals.getProperty("jdbcProvider.driver"); try { Class.forName(jdbcDriver).newInstance(); } catch (Exception e) { Log.error("Unable to load JDBC driver: " + jdbcDriver, e); return; } connectionString = JiveGlobals.getProperty("jdbcProvider.connectionString"); // Load SQL statements. passwordSQL = JiveGlobals.getProperty("jdbcAuthProvider.passwordSQL"); setPasswordSQL = JiveGlobals.getProperty("jdbcAuthProvider.setPasswordSQL"); allowUpdate = JiveGlobals.getBooleanProperty("jdbcAuthProvider.allowUpdate",false); passwordType = PasswordType.plain; try { passwordType = PasswordType.valueOf( JiveGlobals.getProperty("jdbcAuthProvider.passwordType", "plain")); } catch (IllegalArgumentException iae) { Log.error(iae); } } public void authenticate(String username, String password) throws UnauthorizedException { if (username == null || password == null) { throw new UnauthorizedException(); } username = username.trim().toLowerCase(); if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. Return authentication failed. throw new UnauthorizedException(); } } String userPassword; try { userPassword = getPasswordValue(username); } catch (UserNotFoundException unfe) { throw new UnauthorizedException(); } // If the user's password doesn't match the password passed in, authentication // should fail. if (passwordType == PasswordType.md5) { password = StringUtils.hash(password, "MD5"); } else if (passwordType == PasswordType.sha1) { password = StringUtils.hash(password, "SHA-1"); } if (!password.equals(userPassword)) { throw new UnauthorizedException(); } // Got this far, so the user must be authorized. createUser(username); } public void authenticate(String username, String token, String digest) throws UnauthorizedException { if (passwordType != PasswordType.plain) { throw new UnsupportedOperationException("Digest authentication not supported for " + "password type " + passwordType); } if (username == null || token == null || digest == null) { throw new UnauthorizedException(); } username = username.trim().toLowerCase(); if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. Return authentication failed. throw new UnauthorizedException(); } } String password; try { password = getPasswordValue(username); } catch (UserNotFoundException unfe) { throw new UnauthorizedException(); } String anticipatedDigest = AuthFactory.createDigest(token, password); if (!digest.equalsIgnoreCase(anticipatedDigest)) { throw new UnauthorizedException(); } // Got this far, so the user must be authorized. createUser(username); } public boolean isPlainSupported() { // If the auth SQL is defined, plain text authentication is supported. return (passwordSQL != null); } public boolean isDigestSupported() { // The auth SQL must be defined and the password type is supported. return (passwordSQL != null && passwordType == PasswordType.plain); } public String getPassword(String username) throws UserNotFoundException, UnsupportedOperationException { if (!supportsPasswordRetrieval()) { throw new UnsupportedOperationException(); } if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. throw new UserNotFoundException(); } } return getPasswordValue(username); } public void setPassword(String username, String password) throws UserNotFoundException, UnsupportedOperationException { if (allowUpdate && setPasswordSQL != null) { setPasswordValue(username, password); } else { throw new UnsupportedOperationException(); } } public boolean supportsPasswordRetrieval() { return (passwordSQL != null && passwordType == PasswordType.plain); } /** * Returns the value of the password field. It will be in plain text or hashed * format, depending on the password type. * * @param username user to retrieve the password field for * @return the password value. * @throws UserNotFoundException if the given user could not be loaded. */ private String getPasswordValue(String username) throws UserNotFoundException { String password = null; Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. throw new UserNotFoundException(); } } try { con = DriverManager.getConnection(connectionString); pstmt = con.prepareStatement(passwordSQL); pstmt.setString(1, username); rs = pstmt.executeQuery(); // If the query had no results, the username and password // did not match a user record. Therefore, throw an exception. if (!rs.next()) { throw new UserNotFoundException(); } password = rs.getString(1); } catch (SQLException e) { Log.error("Exception in JDBCAuthProvider", e); throw new UserNotFoundException(); } finally { DbConnectionManager.closeConnection(rs, pstmt, con); } return password; } private void setPasswordValue(String username, String password) throws UserNotFoundException { Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. throw new UserNotFoundException(); } } try { con = DriverManager.getConnection(connectionString); pstmt = con.prepareStatement(setPasswordSQL); pstmt.setString(1, username); if (passwordType == PasswordType.md5) { password = StringUtils.hash(password, "MD5"); } else if (passwordType == PasswordType.sha1) { password = StringUtils.hash(password, "SHA-1"); } pstmt.setString(2, password); rs = pstmt.executeQuery(); } catch (SQLException e) { Log.error("Exception in JDBCAuthProvider", e); throw new UserNotFoundException(); } finally { DbConnectionManager.closeConnection(rs, pstmt, con); } } /** * Indicates how the password is stored. */ @SuppressWarnings({"UnnecessarySemicolon"}) // Support for QDox Parser public enum PasswordType { /** * The password is stored as plain text. */ plain, /** * The password is stored as a hex-encoded MD5 hash. */ md5, /** * The password is stored as a hex-encoded SHA-1 hash. */ sha1; } /** * Checks to see if the user exists; if not, a new user is created. * * @param username the username. */ private static void createUser(String username) { // See if the user exists in the database. If not, automatically create them. UserManager userManager = UserManager.getInstance(); try { userManager.getUser(username); } catch (UserNotFoundException unfe) { try { Log.debug("JDBCAuthProvider: Automatically creating new user account for " + username); UserManager.getUserProvider().createUser(username, StringUtils.randomString(8), null, null); } catch (UserAlreadyExistsException uaee) { // Ignore. } } } }
看以看到通过读取PASSWORDTYPE配置
Java代码
JiveGlobals.migrateProperty("jdbcAuthProvider.passwordType"); 。。。。。 。。。。。 。。。。。 passwordType = PasswordType.plain; try { passwordType = PasswordType.valueOf( JiveGlobals.getProperty("jdbcAuthProvider.passwordType", "plain")); } catch (IllegalArgumentException iae) { Log.error(iae); }
JiveGlobals.migrateProperty("jdbcAuthProvider.passwordType"); 。。。。。 。。。。。 。。。。。 passwordType = PasswordType.plain; try { passwordType = PasswordType.valueOf( JiveGlobals.getProperty("jdbcAuthProvider.passwordType", "plain")); } catch (IllegalArgumentException iae) { Log.error(iae); }
进行密码的验证
Java代码
if (passwordType == PasswordType.md5) {
password = StringUtils.hash(password, "MD5");
}
else if (passwordType == PasswordType.sha1) {
password = StringUtils.hash(password, "SHA-1");
}
if (!password.equals(userPassword)) {
throw new UnauthorizedException();
}
if (passwordType == PasswordType.md5) { password = StringUtils.hash(password, "MD5"); } else if (passwordType == PasswordType.sha1) { password = StringUtils.hash(password, "SHA-1"); } if (!password.equals(userPassword)) { throw new UnauthorizedException(); }
这样完全可以仿照JDBCAuthProvider重新构造
Java代码
package org.yxsoft.openfire.plugin; import org.jivesoftware.openfire.user.UserNotFoundException; import org.jivesoftware.openfire.auth.*; import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.Log; import org.jivesoftware.util.StringUtils; import org.jivesoftware.database.DbConnectionManager; import java.sql.*; import java.security.MessageDigest; /** * Created by cl * Date: 2008-9-4 * Time: 9:18:26 * 仿照JDBCAuthProvider * 在数据库连接上 支持user/password * 密码验证 使用bfmp的机制 */ public class BfmpAuthProvider implements AuthProvider { private String connectionString; private String user; private String password; private String passwordSQL; private String setPasswordSQL; private PasswordType passwordType; private boolean allowUpdate; /** * 初始化 * 比JDBCAuthProvider多支持 * JiveGlobals.migrateProperty("jdbcProvider.url"); JiveGlobals.migrateProperty("jdbcProvider.user"); JiveGlobals.migrateProperty("jdbcProvider.password"); */ public BfmpAuthProvider() { // Convert XML based provider setup to Database based JiveGlobals.migrateProperty("jdbcProvider.driver"); JiveGlobals.migrateProperty("jdbcProvider.url"); JiveGlobals.migrateProperty("jdbcProvider.user"); JiveGlobals.migrateProperty("jdbcProvider.password"); JiveGlobals.migrateProperty("jdbcAuthProvider.passwordSQL"); JiveGlobals.migrateProperty("jdbcAuthProvider.passwordType"); JiveGlobals.migrateProperty("jdbcAuthProvider.setPasswordSQL"); JiveGlobals.migrateProperty("jdbcAuthProvider.allowUpdate"); JiveGlobals.migrateProperty("jdbcAuthProvider.passwordType"); // Load the JDBC driver and connection string. String jdbcDriver = JiveGlobals.getProperty("jdbcProvider.driver"); try { Class.forName(jdbcDriver).newInstance(); } catch (Exception e) { Log.error("Unable to load JDBC driver: " + jdbcDriver, e); return; } connectionString = JiveGlobals.getProperty("jdbcProvider.url"); user = JiveGlobals.getProperty("jdbcProvider.user"); password = JiveGlobals.getProperty("jdbcProvider.password"); // Load SQL statements. passwordSQL = JiveGlobals.getProperty("jdbcAuthProvider.passwordSQL"); setPasswordSQL = JiveGlobals.getProperty("jdbcAuthProvider.setPasswordSQL"); allowUpdate = JiveGlobals.getBooleanProperty("jdbcAuthProvider.allowUpdate",false); passwordType = PasswordType.plain; try { passwordType = PasswordType.valueOf( JiveGlobals.getProperty("jdbcAuthProvider.passwordType", "plain")); Log.error("PasswordType:"+ passwordType); } catch (IllegalArgumentException iae) { Log.error(iae); } } public boolean isPlainSupported() { //default return true; } public boolean isDigestSupported() { //default return true; } public void authenticate(String username, String password) throws UnauthorizedException, ConnectionException, InternalUnauthenticatedException { if (username == null || password == null) { throw new UnauthorizedException(); } Log.error(username+":"+password); username = username.trim().toLowerCase(); if (username.contains("@")) { Log.error(username+":"+XMPPServer.getInstance().getServerInfo().getXMPPDomain()); // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. Return authentication failed. throw new UnauthorizedException(); } } else { Log.error("user name not contains "); } String userPassword; try { userPassword = getPasswordValue(username); } catch (UserNotFoundException unfe) { throw new UnauthorizedException(); } // If the user's password doesn't match the password passed in, authentication // should fail. if (passwordType == PasswordType.bfmp) { //这里BfmpMD5 就是自己的密码规则 password = BfmpMD5(password); } if (!password.equals(userPassword)) { throw new UnauthorizedException(); } // Got this far, so the user must be authorized. //createUser(username); } public void authenticate(String username, String token, String digest) throws UnauthorizedException, ConnectionException, InternalUnauthenticatedException { if (passwordType != PasswordType.plain) { throw new UnsupportedOperationException("Digest authentication not supported for " + "password type " + passwordType); } if (username == null || token == null || digest == null) { throw new UnauthorizedException(); } username = username.trim().toLowerCase(); if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. Return authentication failed. throw new UnauthorizedException(); } } String password; try { password = getPasswordValue(username); } catch (UserNotFoundException unfe) { throw new UnauthorizedException(); } String anticipatedDigest = AuthFactory.createDigest(token, password); if (!digest.equalsIgnoreCase(anticipatedDigest)) { throw new UnauthorizedException(); } // Got this far, so the user must be authorized. //createUser(username); } public String getPassword(String username) throws UserNotFoundException, UnsupportedOperationException { if (!supportsPasswordRetrieval()) { throw new UnsupportedOperationException(); } if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. throw new UserNotFoundException(); } } return getPasswordValue(username); } private String getPasswordValue(String username) throws UserNotFoundException { String password = null; Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. throw new UserNotFoundException(); } } try { con = DriverManager.getConnection(connectionString, user, this.password); pstmt = con.prepareStatement(passwordSQL); pstmt.setString(1, username); rs = pstmt.executeQuery(); // If the query had no results, the username and password // did not match a user record. Therefore, throw an exception. if (!rs.next()) { throw new UserNotFoundException(); } password = rs.getString(1); } catch (SQLException e) { Log.error("Exception in JDBCAuthProvider", e); throw new UserNotFoundException(); } finally { DbConnectionManager.closeConnection(rs, pstmt, con); } return password; } public void setPassword(String username, String password) throws UserNotFoundException, UnsupportedOperationException { // unsupport } public boolean supportsPasswordRetrieval() { return true; } /** * Indicates how the password is stored. */ @SuppressWarnings({"UnnecessarySemicolon"}) // Support for QDox Parser public enum PasswordType { /** * The password is stored as plain text. */ plain, /** * The password is stored as a bfmp passwrod. */ bfmp; } private String BfmpMD5 (String source) { //在这里实现你的加密机制,返回生成的密码 return ""; } }
package org.yxsoft.openfire.plugin; import org.jivesoftware.openfire.user.UserNotFoundException; import org.jivesoftware.openfire.auth.*; import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.Log; import org.jivesoftware.util.StringUtils; import org.jivesoftware.database.DbConnectionManager; import java.sql.*; import java.security.MessageDigest; /** * Created by cl * Date: 2008-9-4 * Time: 9:18:26 * 仿照JDBCAuthProvider * 在数据库连接上 支持user/password * 密码验证 使用bfmp的机制 */ public class BfmpAuthProvider implements AuthProvider { private String connectionString; private String user; private String password; private String passwordSQL; private String setPasswordSQL; private PasswordType passwordType; private boolean allowUpdate; /** * 初始化 * 比JDBCAuthProvider多支持 * JiveGlobals.migrateProperty("jdbcProvider.url"); JiveGlobals.migrateProperty("jdbcProvider.user"); JiveGlobals.migrateProperty("jdbcProvider.password"); */ public BfmpAuthProvider() { // Convert XML based provider setup to Database based JiveGlobals.migrateProperty("jdbcProvider.driver"); JiveGlobals.migrateProperty("jdbcProvider.url"); JiveGlobals.migrateProperty("jdbcProvider.user"); JiveGlobals.migrateProperty("jdbcProvider.password"); JiveGlobals.migrateProperty("jdbcAuthProvider.passwordSQL"); JiveGlobals.migrateProperty("jdbcAuthProvider.passwordType"); JiveGlobals.migrateProperty("jdbcAuthProvider.setPasswordSQL"); JiveGlobals.migrateProperty("jdbcAuthProvider.allowUpdate"); JiveGlobals.migrateProperty("jdbcAuthProvider.passwordType"); // Load the JDBC driver and connection string. String jdbcDriver = JiveGlobals.getProperty("jdbcProvider.driver"); try { Class.forName(jdbcDriver).newInstance(); } catch (Exception e) { Log.error("Unable to load JDBC driver: " + jdbcDriver, e); return; } connectionString = JiveGlobals.getProperty("jdbcProvider.url"); user = JiveGlobals.getProperty("jdbcProvider.user"); password = JiveGlobals.getProperty("jdbcProvider.password"); // Load SQL statements. passwordSQL = JiveGlobals.getProperty("jdbcAuthProvider.passwordSQL"); setPasswordSQL = JiveGlobals.getProperty("jdbcAuthProvider.setPasswordSQL"); allowUpdate = JiveGlobals.getBooleanProperty("jdbcAuthProvider.allowUpdate",false); passwordType = PasswordType.plain; try { passwordType = PasswordType.valueOf( JiveGlobals.getProperty("jdbcAuthProvider.passwordType", "plain")); Log.error("PasswordType:"+ passwordType); } catch (IllegalArgumentException iae) { Log.error(iae); } } public boolean isPlainSupported() { //default return true; } public boolean isDigestSupported() { //default return true; } public void authenticate(String username, String password) throws UnauthorizedException, ConnectionException, InternalUnauthenticatedException { if (username == null || password == null) { throw new UnauthorizedException(); } Log.error(username+":"+password); username = username.trim().toLowerCase(); if (username.contains("@")) { Log.error(username+":"+XMPPServer.getInstance().getServerInfo().getXMPPDomain()); // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. Return authentication failed. throw new UnauthorizedException(); } } else { Log.error("user name not contains "); } String userPassword; try { userPassword = getPasswordValue(username); } catch (UserNotFoundException unfe) { throw new UnauthorizedException(); } // If the user's password doesn't match the password passed in, authentication // should fail. if (passwordType == PasswordType.bfmp) { //这里BfmpMD5 就是自己的密码规则 password = BfmpMD5(password); } if (!password.equals(userPassword)) { throw new UnauthorizedException(); } // Got this far, so the user must be authorized. //createUser(username); } public void authenticate(String username, String token, String digest) throws UnauthorizedException, ConnectionException, InternalUnauthenticatedException { if (passwordType != PasswordType.plain) { throw new UnsupportedOperationException("Digest authentication not supported for " + "password type " + passwordType); } if (username == null || token == null || digest == null) { throw new UnauthorizedException(); } username = username.trim().toLowerCase(); if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. Return authentication failed. throw new UnauthorizedException(); } } String password; try { password = getPasswordValue(username); } catch (UserNotFoundException unfe) { throw new UnauthorizedException(); } String anticipatedDigest = AuthFactory.createDigest(token, password); if (!digest.equalsIgnoreCase(anticipatedDigest)) { throw new UnauthorizedException(); } // Got this far, so the user must be authorized. //createUser(username); } public String getPassword(String username) throws UserNotFoundException, UnsupportedOperationException { if (!supportsPasswordRetrieval()) { throw new UnsupportedOperationException(); } if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. throw new UserNotFoundException(); } } return getPasswordValue(username); } private String getPasswordValue(String username) throws UserNotFoundException { String password = null; Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. throw new UserNotFoundException(); } } try { con = DriverManager.getConnection(connectionString, user, this.password); pstmt = con.prepareStatement(passwordSQL); pstmt.setString(1, username); rs = pstmt.executeQuery(); // If the query had no results, the username and password // did not match a user record. Therefore, throw an exception. if (!rs.next()) { throw new UserNotFoundException(); } password = rs.getString(1); } catch (SQLException e) { Log.error("Exception in JDBCAuthProvider", e); throw new UserNotFoundException(); } finally { DbConnectionManager.closeConnection(rs, pstmt, con); } return password; } public void setPassword(String username, String password) throws UserNotFoundException, UnsupportedOperationException { // unsupport } public boolean supportsPasswordRetrieval() { return true; } /** * Indicates how the password is stored. */ @SuppressWarnings({"UnnecessarySemicolon"}) // Support for QDox Parser public enum PasswordType { /** * The password is stored as plain text. */ plain, /** * The password is stored as a bfmp passwrod. */ bfmp; } private String BfmpMD5 (String source) { //在这里实现你的加密机制,返回生成的密码 return ""; } }
编译后将此class加入到lib/openfire.jar中即可
当然不要忘记 将系统属性中
provider.auth.className,改成你自已的Provider
*上述代码例子中是org.yxsoft.openfire.plugin.BFMPAuthProvider
jdbcAuthProvider.passwordType,改成你自己定义的枚举值
*上述代码例子中是bfmp
相关文章推荐
- xmpp with openfire 之四 扩展AuthProvider
- xmpp with openfire之四 扩展的AuthProvider
- xmpp with openfire之四 扩展的AuthProvider
- xmpp with openfire 之三 openfire扩展小试 整合现有用户
- xmpp with openfire之三 openfire扩展小试 整合现有系统用户
- xmpp with openfire之三 openfire扩展小试 整合现有系统用户
- xmpp with openfire之三 openfire扩展小试 整合现有系统用户
- xmpp with openfire之三 openfire扩展小试 整合现有系统用户
- xmpp with openfire之一 XMPP AND OPENFIRE
- xmpp with openfire 之二 OPENFIRE的安装
- xmpp with openfire 之五 插件之一 利用Broadcast 插件实现简单群
- xmpp with openfire 插件-利用Broadcast实现群
- xmpp with openfire之五 插件-利用Broadcast实现群
- xmpp with openfire之一 xmpp and openfire
- xmpp with openfire插件-利用Broadcast实现群
- xmpp with openfire之二 openfire安装
- xmpp with openfire之五 插件-利用Broadcast实现群
- xmpp with openfire 之五 插件之一 利用Broadcast 插件实现简单群
- xmpp with openfire之五 插件-利用Broadcast实现群
- Android XMPP 例子(Openfire+asmack+spark) 出现登陆连接错误