
com.github.kaizen4j.shiro.realm.SimpleJdbcRealm Maven / Gradle / Ivy
The newest version!
package com.github.kaizen4j.shiro.realm;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.config.ConfigurationException;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.JdbcUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author liuguowen
*/
public class SimpleJdbcRealm extends JdbcRealm {
private static final Logger logger = LoggerFactory.getLogger(SimpleJdbcRealm.class);
/**
* 账户已锁定
*/
private static final String ACCOUNT_LOCKED = "1";
/**
* The default query used to retrieve account data for the user.
*/
private static final String CUSTOM_AUTHENTICATION_QUERY = "select password, locked from sys_user where username = ?";
/**
* The default query used to retrieve account data for the user when {@link #saltStyle} is COLUMN.
*/
private static final String CUSTOM_SALTED_AUTHENTICATION_QUERY = "select password, salt, locked from sys_user where username = ?";
/**
* The default query used to retrieve the roles that apply to a user.
*/
private static final String CUSTOM_USER_ROLES_QUERY = "select sys_role.name from sys_user "
+ "join sys_user_roles on sys_user.id = sys_user_roles.user_id join sys_role on sys_user_roles.role_id = sys_role.id "
+ "where sys_user.username = ? and sys_role.available = 1";
/**
* The default query used to retrieve permissions that apply to a particular role.
*/
private static final String CUSTOM_PERMISSIONS_QUERY = "select sys_resource.permission from sys_role_resources "
+ "join sys_resource on sys_role_resources.resource_id = sys_resource.id join sys_role on sys_role.id = sys_role_resources.role_id "
+ "where sys_role.name = ? and sys_resource.available = 1 and sys_resource.type = 'REST'";
public SimpleJdbcRealm() {
this.authenticationQuery = CUSTOM_AUTHENTICATION_QUERY;
this.userRolesQuery = CUSTOM_USER_ROLES_QUERY;
this.permissionsQuery = CUSTOM_PERMISSIONS_QUERY;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// Null username are invalid
if (principals == null) {
throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
}
String username = (String) getAvailablePrincipal(principals);
Connection conn = null;
Set roleNames = null;
Set permissions = null;
try {
conn = dataSource.getConnection();
// Retrieve roles and permissions from database
roleNames = getRoleNamesForUser(conn, username);
if (permissionsLookupEnabled) {
permissions = getPermissions(conn, username, roleNames);
}
} catch (SQLException e) {
final String message = "There was a SQL error while authorizing user [" + username + "]";
if (logger.isErrorEnabled()) {
logger.error(message, e);
}
// Rethrow any SQL errors as an authorization exception
throw new AuthorizationException(message, e);
} finally {
JdbcUtils.closeConnection(conn);
}
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
info.setStringPermissions(permissions);
return info;
}
@Override
public void setSaltStyle(SaltStyle saltStyle) {
this.saltStyle = saltStyle;
if (saltStyle == SaltStyle.COLUMN && authenticationQuery.equals(CUSTOM_AUTHENTICATION_QUERY)) {
authenticationQuery = CUSTOM_SALTED_AUTHENTICATION_QUERY;
}
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String username = upToken.getUsername();
// Null username is invalid
if (StringUtils.isBlank(username)) {
throw new AccountException("Null username are not allowed by this realm.");
}
Connection conn = null;
SimpleAuthenticationInfo info;
try {
conn = dataSource.getConnection();
String[] queryResults = getPasswordFromUser(conn, username);
String password = null;
String salt = null;
String locked = null;
switch (saltStyle) {
case NO_SALT:
password = queryResults[0];
locked = queryResults[1];
break;
case CRYPT:
throw new ConfigurationException("Not implemented yet");
case COLUMN:
password = queryResults[0];
salt = queryResults[1];
locked = queryResults[2];
break;
case EXTERNAL:
password = queryResults[0];
locked = queryResults[1];
salt = getSaltForUser(username);
break;
default:
throw new ConfigurationException("Not salt implemented pass yet");
}
if (StringUtils.isBlank(password)) {
throw new UnknownAccountException("No account found for user [" + username + "]");
}
if (ACCOUNT_LOCKED.equals(locked)) {
throw new LockedAccountException("Locked account for user [" + username + "]");
}
info = new SimpleAuthenticationInfo(username, password.toCharArray(), getName());
if (salt != null) {
if (saltStyle == SaltStyle.COLUMN && saltIsBase64Encoded) {
info.setCredentialsSalt(new SimpleByteSource(Base64.decode(salt)));
} else {
info.setCredentialsSalt(new SimpleByteSource(salt));
}
}
} catch (SQLException e) {
final String message = "There was a SQL error while authenticating user [" + username + "]";
if (logger.isErrorEnabled()) {
logger.error(message, e);
}
// Rethrow any SQL errors as an authentication exception
throw new AuthenticationException(message, e);
} finally {
JdbcUtils.closeConnection(conn);
}
return info;
}
private String[] getPasswordFromUser(Connection conn, String username) throws SQLException {
String[] result;
boolean returningSeparatedSalt = false;
switch (saltStyle) {
case NO_SALT:
case CRYPT:
case EXTERNAL:
result = new String[2];
break;
default:
result = new String[3];
returningSeparatedSalt = true;
}
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(authenticationQuery);
ps.setString(1, username);
// Execute query
rs = ps.executeQuery();
// Loop over results - although we are only expecting one result, since usernames should be unique
boolean foundResult = false;
while (rs.next()) {
// Check to ensure only one row is processed
if (foundResult) {
throw new AuthenticationException(
"More than one user row found for user [" + username + "]. Usernames must be unique.");
}
// password
result[0] = rs.getString(1);
if (returningSeparatedSalt) {
// salt
result[1] = rs.getString(2);
// locked
result[2] = rs.getString(3);
} else {
// locked
result[1] = rs.getString(2);
}
foundResult = true;
}
} finally {
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(ps);
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy