Hi Sunil.
You easily can build your own Custom JDBC Realm, taking care of the
particular connection settings.
I found that much easier then to fidle with the generic JDBC realm.
For reference, see my own realm attached, you will need to implement at
least the highlighted parts:
/**
* This implementation of the interface expects the principals
collection to return a String
* username keyed off of this realm's {@link #getName() name}
*
* @see
#getAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection)
*/
@Override
protected AuthorizationInfo
doGetAuthorizationInfo(PrincipalCollection principals) {
// null usernames are invalid
if (principals == null) {
throw new AuthorizationException("PrincipalCollection method
argument cannot be null.");
}
String username = (String) getAvailablePrincipal(principals);
Connection conn = null;
Set<String> roleNames = null;
Set<String> permissions = null;
try {
conn = COMMONReader.etlConnection.getConnection();
// Retrieve roles and permissions from database
roleNames = getRoleNamesForUser(conn, username);
if (permissionsLookupEnabled) {
permissions = getPermissions(conn, username, roleNames);
}
} catch (Exception e) {
throw new AuthorizationException(
"There was a SQL error while authorizing user [" + username +
"]", e);
} finally {
COMMONReader.etlConnection.release(conn);
}
SimpleAuthorizationInfo info = new
SimpleAuthorizationInfo(roleNames);
info.setStringPermissions(permissions);
return info;
}
Best regards
Andreas
On Thu, 2019-01-24 at 21:00 -0700, Sunil kumar wrote:
> org.apache.shiro.config.ConfigurationException: Property 'serverName'
> doesnot exist for object of
> typecom.orientechnologies.orient.jdbc.OrientJdbcDriver.atorg.apache.s
> hiro.config.ReflectionBuilder.isTypedProperty(ReflectionBuilder.java:
> 413)
>
>
> This is the error I'm getting when I use this configuration.I don't
> have a clear understanding of how to connect to orientdb using
> jdbcrealm
>
>
> --Sent from: http://shiro-user.582556.n2.nabble.com/
/*
* To change this license header, choose License Headers in Project Properties. To change this
* template file, choose Tools | Templates and open the template in the editor.
*/
package com.manticore.common.auth;
import com.manticore.database.COMMONReader;
import com.manticore.license.Base64;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.util.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.realm.jdbc.JdbcRealm;
/**
* Realm that allows authentication and authorization via JDBC calls. The default queries suggest a
* potential schema for retrieving the user's password for authentication, and querying for a user's
* roles and permissions. The default queries can be overridden by setting the query properties of
* the realm.
* <p/>
* If the default implementation of authentication and authorization cannot handle your schema, this
* class can be subclassed and the appropriate methods overridden. (usually
* {@link #doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)},
* {@link #getRoleNamesForUser(java.sql.Connection,String)}, and/or
* {@link #getPermissions(java.sql.Connection,String,java.util.Collection)}
* <p/>
* This realm supports caching by extending from {@link org.apache.shiro.realm.AuthorizingRealm}.
*
* @since 0.2
*/
public class MJdbcRealm extends JdbcRealm {
public MJdbcRealm() {
super();
setUserRolesQuery("SELECT concat(concat(upper(c.description)\n" +
" , '_')\n" +
" , upper(d.description)) role\n" +
"FROM common.ORGANIZATION_UNIT_USER_ROLE a\n" +
" INNER JOIN common.\"user\" b\n" +
" ON a.id_user = b.id_user\n" +
" INNER JOIN common.\"ORGANIZATION_UNIT\" c\n" +
" ON a.id_organization_unit = c.id_organization_unit\n" +
" INNER JOIN common.role d\n" +
" ON a.id_role = d.id_role\n" +
"WHERE lower(b.username) = lower(?) ");
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException {
setCredentialsMatcher(new HashedCredentialsMatcher(Sha256Hash.ALGORITHM_NAME) {
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
SimpleAuthenticationInfo simpleAuthenticationInfo = (SimpleAuthenticationInfo) info;
byte[] infoBytes = toBytes(simpleAuthenticationInfo.getCredentials());
byte[] saltBytes = toBytes(simpleAuthenticationInfo.getCredentialsSalt());
SecretKeyFactory f;
try {
f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
SecretKey key = f.generateSecret(
new PBEKeySpec((char[]) token.getCredentials(), saltBytes, 10 * 1024, 256));
return Arrays.equals(key.getEncoded(), infoBytes);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(MJdbcRealm.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvalidKeySpecException ex) {
Logger.getLogger(MJdbcRealm.class.getName()).log(Level.SEVERE, null, ex);
}
return false;
}
});
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String username = upToken.getUsername();
// Null username is invalid
if (username == null) {
throw new AccountException("Null usernames are not allowed by this realm.");
}
SimpleAuthenticationInfo info = null;
String[] crypt;
try {
crypt = COMMONReader.getSaltedUserPasswordHash(username).split("\\$");
String salt = crypt[0];
String password = crypt[1];
info = new SimpleAuthenticationInfo(username, Base64.decode(password),
ByteSource.Util.bytes(Base64.decode(salt)), getName());
} catch (Exception ex) {
throw new AuthenticationException("Failed to authenticate " + username, ex);
}
return info;
}
/**
* This implementation of the interface expects the principals collection to return a String
* username keyed off of this realm's {@link #getName() name}
*
* @see #getAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection)
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// null usernames are invalid
if (principals == null) {
throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
}
String username = (String) getAvailablePrincipal(principals);
Connection conn = null;
Set<String> roleNames = null;
Set<String> permissions = null;
try {
conn = COMMONReader.etlConnection.getConnection();
// Retrieve roles and permissions from database
roleNames = getRoleNamesForUser(conn, username);
if (permissionsLookupEnabled) {
permissions = getPermissions(conn, username, roleNames);
}
} catch (Exception e) {
throw new AuthorizationException(
"There was a SQL error while authorizing user [" + username + "]", e);
} finally {
COMMONReader.etlConnection.release(conn);
}
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
info.setStringPermissions(permissions);
return info;
}
@Override
protected Set<String> getRoleNamesForUser(Connection conn, String username) throws SQLException {
PreparedStatement ps = null;
ResultSet rs = null;
Set<String> roleNames = new LinkedHashSet<>();
try {
ps = conn.prepareStatement(userRolesQuery);
ps.setString(1, username);
// Execute query
rs = ps.executeQuery();
// Loop over results and add each returned role to a set
while (rs.next()) {
String roleName = rs.getString(1);
// Add the role to the list of names if it isn't null
if (roleName != null) {
roleNames.add(roleName);
}
}
} finally {
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(ps);
}
return roleNames;
}
@Override
protected Set<String> getPermissions(Connection conn, String username,
Collection<String> roleNames) throws SQLException {
PreparedStatement ps = null;
Set<String> permissions = new LinkedHashSet<>();
try {
ps = conn.prepareStatement(permissionsQuery);
for (String roleName : roleNames) {
ps.setString(1, roleName);
ResultSet rs = null;
try {
// Execute query
rs = ps.executeQuery();
// Loop over results and add each returned role to a set
while (rs.next()) {
String permissionString = rs.getString(1);
// Add the permission to the set of permissions
permissions.add(permissionString);
}
} finally {
JdbcUtils.closeResultSet(rs);
}
}
} finally {
JdbcUtils.closeStatement(ps);
}
return permissions;
}
@Override
protected String getSaltForUser(String username) {
return username;
}
}