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;
  }

}

Reply via email to