Class JdbcRealm

java.lang.Object
org.apache.shiro.realm.CachingRealm
org.apache.shiro.realm.AuthenticatingRealm
org.apache.shiro.realm.AuthorizingRealm
org.apache.shiro.realm.jdbc.JdbcRealm
de.businesscode.bcdui.subjectsettings.JdbcRealm
All Implemented Interfaces:
org.apache.shiro.authc.LogoutAware, org.apache.shiro.authz.Authorizer, org.apache.shiro.authz.permission.PermissionResolverAware, org.apache.shiro.authz.permission.RolePermissionResolverAware, org.apache.shiro.cache.CacheManagerAware, org.apache.shiro.lang.util.Initializable, org.apache.shiro.lang.util.Nameable, org.apache.shiro.realm.Realm

public class JdbcRealm extends org.apache.shiro.realm.jdbc.JdbcRealm
Used by shiro framework for retrieving authentication and authorization from the database Relies on bcd_sec_user and bcd_sec_user_settings BindingSets providing support for plaintext (backwards compatibility) and salted/hashed passwords using SHA256 hashing. The default hash iteration is 1024 and can be adjusted in shiro ini by setting .hashIterations property. The default mode is hashed/salted, which can be disabled by not having a binding item password_salt in bcd_sec_user in shiro configuration when declaring this realm. When creating new password please use generatePasswordHashSalt(String, int) method of this class. Beside user authenticated here against bcd_sec_user, we attach authorization in form of permissions from bcd_sec_user_settings here to those users as well as to users authenticated with ExternalAuthenticationToken as created by OAut
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static final record 
     

    Nested classes/interfaces inherited from class org.apache.shiro.realm.jdbc.JdbcRealm

    org.apache.shiro.realm.jdbc.JdbcRealm.SaltStyle
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final String
     
    static final String
     
    static final String
     
    static final String
     
    static final int
     
    protected final org.apache.shiro.authc.credential.HashedCredentialsMatcher
     
    static final String
     

    Fields inherited from class org.apache.shiro.realm.jdbc.JdbcRealm

    authenticationQuery, dataSource, DEFAULT_AUTHENTICATION_QUERY, DEFAULT_PERMISSIONS_QUERY, DEFAULT_SALTED_AUTHENTICATION_QUERY, DEFAULT_USER_ROLES_QUERY, permissionsLookupEnabled, permissionsQuery, saltIsBase64Encoded, saltStyle, userRolesQuery
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    protected void
    assertCredentialsMatch(org.apache.shiro.authc.AuthenticationToken token, org.apache.shiro.authc.AuthenticationInfo authInfo)
    Asserts that the submitted AuthenticationToken's credentials match the stored account AuthenticationInfo's credentials, and if not, throws an AuthenticationException.
    protected org.apache.shiro.authc.AuthenticationInfo
    doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken token)
    Retrieve AuthenticationInfo as stored in the system (db) for later comparison with AuthenticationToken
    protected org.apache.shiro.authz.AuthorizationInfo
    doGetAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection arg0)
    the super implementation relies here on dataSource
    static String[]
    generatePasswordHashSalt(String plainTextPassword)
    Convenience method using default number of iterations
    static String[]
    generatePasswordHashSalt(String plainTextPassword, int iterations)
    Generates a password hash + salt with DEFAULT_HASH_ITERATIONS iterations, for use with Sha256CredentialsMatcher The hash and salt are returned as hex-encoded string, compatible with JdbcRealm
    protected String
    getAvailablePrincipal(org.apache.shiro.subject.PrincipalCollection pc)
    In doGetAuthenticationInfo() if possible we set user_id and user_name as principals for AuthenticationInfo Return the user-id to be used with getPermissions(Connection, String, Collection) and getRoleNamesForUser(Connection, String) If available, we return the technical user id here, we know it exists if we find a PrimaryPrincipal.
    static String
     
    static String
     
    org.apache.shiro.authc.credential.CredentialsMatcher
    Shiro will use this to compare the AuthenticationToken from the request with the AuthenticationInfo from our system
    protected String
    Support for type-name=OTHER, cust:type-name=uuid
    protected DataSource
     
    protected String
    getDefineJdbcParameter(String columnExpression, String customType)
    support for custom jdbc type, do any explicit casts here
    static int
     
     
     
    protected Set<String>
    getPermissions(Connection con, String userId, Collection<String> roleNames)
     
    getPrincipalInfo(String userLogin, boolean enforceSalt)
    To support hashed passwords with salt we have to load the password + hash (if salted) from database, so the hash can be recomputed and verified.
    protected Set<String>
    load roles from db
    static void
    main(String[] args)
    main helper to create passwords interactively or by argument
    static void
    setConfigPasswordColumnName(String configPasswordColumnName)
     
    static void
    setConfigPasswordSaltColumnName(String configPasswordSaltColumnName)
     
    void
    setHashIterations(int hashIterations)
     
    void
    setPasswordColumnName(String passwordColumnsName)
    These setters are called from Shiro if realmBcdJdbc.
    void
    setPasswordSaltColumnName(String passwordSaltColumnName)
     
    boolean
    supports(org.apache.shiro.authc.AuthenticationToken token)
    ExternalAuthenticationToken indicates that the authentication has already happened externally We let the user through here.

    Methods inherited from class org.apache.shiro.realm.jdbc.JdbcRealm

    getSaltForUser, setAuthenticationQuery, setDataSource, setPermissionsLookupEnabled, setPermissionsQuery, setSaltIsBase64Encoded, setSaltStyle, setUserRolesQuery

    Methods inherited from class org.apache.shiro.realm.AuthorizingRealm

    afterCacheManagerSet, checkPermission, checkPermission, checkPermission, checkPermissions, checkPermissions, checkPermissions, checkRole, checkRole, checkRoles, checkRoles, checkRoles, clearCachedAuthorizationInfo, doClearCache, getAuthorizationCache, getAuthorizationCacheKey, getAuthorizationCacheName, getAuthorizationInfo, getPermissionResolver, getPermissions, getRolePermissionResolver, hasAllRoles, hasRole, hasRole, hasRoles, hasRoles, isAuthorizationCachingEnabled, isPermitted, isPermitted, isPermitted, isPermitted, isPermitted, isPermitted, isPermittedAll, isPermittedAll, isPermittedAll, onInit, setAuthorizationCache, setAuthorizationCacheName, setAuthorizationCachingEnabled, setName, setPermissionResolver, setRolePermissionResolver

    Methods inherited from class org.apache.shiro.realm.AuthenticatingRealm

    clearCachedAuthenticationInfo, getAuthenticationCache, getAuthenticationCacheKey, getAuthenticationCacheKey, getAuthenticationCacheName, getAuthenticationInfo, getAuthenticationTokenClass, init, isAuthenticationCachingEnabled, isAuthenticationCachingEnabled, setAuthenticationCache, setAuthenticationCacheName, setAuthenticationCachingEnabled, setAuthenticationTokenClass, setCredentialsMatcher

    Methods inherited from class org.apache.shiro.realm.CachingRealm

    clearCache, getCacheManager, getName, isCachingEnabled, onLogout, setCacheManager, setCachingEnabled

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface org.apache.shiro.lang.util.Initializable

    init
  • Field Details

    • BCD_SEC_USER_PASSWORD_BINDINGITEM

      public static final String BCD_SEC_USER_PASSWORD_BINDINGITEM
      See Also:
    • BCD_SEC_USER_PASSWORD_SALT_BINDINGITEM

      public static final String BCD_SEC_USER_PASSWORD_SALT_BINDINGITEM
      See Also:
    • BCD_SEC_USER_PASSWORD_COLUMN_NAME_DEFAULT

      public static final String BCD_SEC_USER_PASSWORD_COLUMN_NAME_DEFAULT
      See Also:
    • BCD_SEC_USER_PASSWORD_SALT_COLUMN_NAME_DEFAULT

      public static final String BCD_SEC_USER_PASSWORD_SALT_COLUMN_NAME_DEFAULT
      See Also:
    • REGEXP_EMAIL

      public static final String REGEXP_EMAIL
      See Also:
    • hashedCredentialsMatcher

      protected final org.apache.shiro.authc.credential.HashedCredentialsMatcher hashedCredentialsMatcher
    • DEFAULT_HASH_ITERATIONS

      public static final int DEFAULT_HASH_ITERATIONS
      See Also:
  • Constructor Details

    • JdbcRealm

      public JdbcRealm()
  • Method Details

    • getCustomJdbcType

      protected String getCustomJdbcType(BindingItem bindingItem)
      Support for type-name=OTHER, cust:type-name=uuid
      Parameters:
      bindingItem -
      Returns:
      cust:type-name , if defined
    • getDefineJdbcParameter

      protected String getDefineJdbcParameter(String columnExpression, String customType)
      support for custom jdbc type, do any explicit casts here
      Parameters:
      columnExpression -
      customType - (may be null)
      Returns:
    • getDataSource

      protected DataSource getDataSource()
      Returns:
      unmanaged datasource, the caller is responsible to close connections
    • getCredentialsMatcher

      public org.apache.shiro.authc.credential.CredentialsMatcher getCredentialsMatcher()
      Shiro will use this to compare the AuthenticationToken from the request with the AuthenticationInfo from our system
      Overrides:
      getCredentialsMatcher in class org.apache.shiro.realm.AuthenticatingRealm
      Returns:
    • getPrincipalInfo

      protected JdbcRealm.PrincipalInfo getPrincipalInfo(String userLogin, boolean enforceSalt) throws SQLException
      To support hashed passwords with salt we have to load the password + hash (if salted) from database, so the hash can be recomputed and verified.
      Parameters:
      userLogin -
      enforceSalt -
      Returns:
      array of: [technical user id, password (string), salt(string)] or null if userLogin is not known; salt can be set to null, if not supported
      Throws:
      SQLException
    • supports

      public boolean supports(org.apache.shiro.authc.AuthenticationToken token)
      ExternalAuthenticationToken indicates that the authentication has already happened externally We let the user through here.
      Specified by:
      supports in interface org.apache.shiro.realm.Realm
      Overrides:
      supports in class org.apache.shiro.realm.AuthenticatingRealm
    • getAvailablePrincipal

      protected String getAvailablePrincipal(org.apache.shiro.subject.PrincipalCollection pc)
      In doGetAuthenticationInfo() if possible we set user_id and user_name as principals for AuthenticationInfo Return the user-id to be used with getPermissions(Connection, String, Collection) and getRoleNamesForUser(Connection, String) If available, we return the technical user id here, we know it exists if we find a PrimaryPrincipal. Otherwise we use the plain user name As Shiro requires (in 2025) String username = (String) getAvailablePrincipal(principals); and does not use toString(), we need this adapter.
      Overrides:
      getAvailablePrincipal in class org.apache.shiro.realm.CachingRealm
    • assertCredentialsMatch

      protected void assertCredentialsMatch(org.apache.shiro.authc.AuthenticationToken token, org.apache.shiro.authc.AuthenticationInfo authInfo) throws org.apache.shiro.authc.AuthenticationException
      Asserts that the submitted AuthenticationToken's credentials match the stored account AuthenticationInfo's credentials, and if not, throws an AuthenticationException. In our case we do not need to verify credentials if it is Windows-SSQ or OAuth, because they are responsible
      Overrides:
      assertCredentialsMatch in class org.apache.shiro.realm.AuthenticatingRealm
      Throws:
      org.apache.shiro.authc.AuthenticationException
    • doGetAuthenticationInfo

      protected org.apache.shiro.authc.AuthenticationInfo doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken token) throws org.apache.shiro.authc.AuthenticationException
      Retrieve AuthenticationInfo as stored in the system (db) for later comparison with AuthenticationToken
      Overrides:
      doGetAuthenticationInfo in class org.apache.shiro.realm.jdbc.JdbcRealm
      Parameters:
      token -
      Returns:
      Throws:
      org.apache.shiro.authc.AuthenticationException
    • getRoleNamesForUser

      protected Set<String> getRoleNamesForUser(Connection con, String userId) throws SQLException
      load roles from db
      Overrides:
      getRoleNamesForUser in class org.apache.shiro.realm.jdbc.JdbcRealm
      Throws:
      SQLException
    • getPermissions

      protected Set<String> getPermissions(Connection con, String userId, Collection<String> roleNames) throws SQLException
      Overrides:
      getPermissions in class org.apache.shiro.realm.jdbc.JdbcRealm
      Throws:
      SQLException
    • doGetAuthorizationInfo

      protected org.apache.shiro.authz.AuthorizationInfo doGetAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection arg0)
      the super implementation relies here on dataSource
      Overrides:
      doGetAuthorizationInfo in class org.apache.shiro.realm.jdbc.JdbcRealm
    • generatePasswordHashSalt

      public static String[] generatePasswordHashSalt(String plainTextPassword, int iterations)
      Generates a password hash + salt with DEFAULT_HASH_ITERATIONS iterations, for use with Sha256CredentialsMatcher The hash and salt are returned as hex-encoded string, compatible with JdbcRealm
      Parameters:
      plainTextPassword -
      Returns:
      [ password hash (hex), password salt (hash) ]
    • generatePasswordHashSalt

      public static String[] generatePasswordHashSalt(String plainTextPassword)
      Convenience method using default number of iterations
      Parameters:
      plainTextPassword -
      Returns:
    • main

      public static void main(String[] args) throws Throwable
      main helper to create passwords interactively or by argument
      Parameters:
      args -
      Throws:
      Throwable
    • setPasswordColumnName

      public void setPasswordColumnName(String passwordColumnsName)
      These setters are called from Shiro if realmBcdJdbc.#propertyname# are set in web.xml
    • getPasswordColumnName

      public String getPasswordColumnName()
    • setPasswordSaltColumnName

      public void setPasswordSaltColumnName(String passwordSaltColumnName)
    • getPasswordSaltColumnName

      public String getPasswordSaltColumnName()
    • setHashIterations

      public void setHashIterations(int hashIterations)
    • getHashIterations

      public static int getHashIterations()
    • getConfigPasswordColumnName

      public static String getConfigPasswordColumnName()
    • setConfigPasswordColumnName

      public static void setConfigPasswordColumnName(String configPasswordColumnName)
    • getConfigPasswordSaltColumnName

      public static String getConfigPasswordSaltColumnName()
    • setConfigPasswordSaltColumnName

      public static void setConfigPasswordSaltColumnName(String configPasswordSaltColumnName)