Java 如何创建自定义JDBCrealm?

Java 如何创建自定义JDBCrealm?,java,security,encryption,glassfish,jdbcrealm,Java,Security,Encryption,Glassfish,Jdbcrealm,我正在尝试保护我的企业web应用程序! 我必须限制资源 由于我已将所有内容存储在我的db(用户和角色)中,因此我不会在(Glassfish)服务器中创建fileRealm或存储任何用户的凭据。此外,我使用jBCrypt来加密用户的密码,所以我不能使用标准的jdbcRealm 如何确保我的资源安全 我在考虑定制jdbcRealm,这是正确的方法吗?如何创建和使用它 一些现有的框架可以帮助我吗 提前谢谢。我建议您使用框架。配置文件如下所示 [main] sha256Matcher = org.ap

我正在尝试保护我的企业web应用程序! 我必须限制资源

由于我已将所有内容存储在我的db(用户和角色)中,因此我不会在(Glassfish)服务器中创建fileRealm或存储任何用户的凭据。此外,我使用jBCrypt来加密用户的密码,所以我不能使用标准的jdbcRealm

如何确保我的资源安全

我在考虑定制jdbcRealm,这是正确的方法吗?如何创建和使用它

一些现有的框架可以帮助我吗


提前谢谢。

我建议您使用框架。配置文件如下所示

[main]

sha256Matcher = org.apache.shiro.authc.credential.HashedCredentialsMatcher
sha256Matcher.hashAlgorithmName = SHA-256
sha256Matcher.hashIterations=1
# base64 encoding
sha256Matcher.storedCredentialsHexEncoded = false

#datasource type
ds = org.apache.shiro.jndi.JndiObjectFactory

#datasourcename
ds.resourceName = cfresource

#datasourcetype
ds.requiredType = javax.sql.DataSource




#configuring jdbc realm
jdbcRealm = com.connectifier.authc.realm.CustomJDBCRealm
jdbcRealm.credentialsMatcher = $sha256Matcher
jdbcRealm.dataSource=$ds
jdbcRealm.userRolesQuery=select name from role where email = ? and isactive=1
jdbcRealm.authenticationQuery=select hash, salt from user where email = ?
jdbcRealm.permissionsLookupEnabled=false
securityManager.realms = $jdbcRealm
#login url
authc.loginUrl = /

#page to redirected to after logout
logout.redirectUrl = /

#page to where to land after login
authc.successUrl = /

#username parameter name in the loginform
authc.usernameParam = username

#password parameter name in the loginform
authc.passwordParam = password

#rememberme parameter name in the loginform
authc.rememberMeParam=rememberme

#cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
#securityManager.cacheManager = $cacheManager
#jdbcRealm.authenticationCachingEnabled = true

[urls]
# The /login.jsp is not restricted to authenticated users (otherwise no one could log in!), but
# the 'authc' filter must still be specified for it so it can process that url's
# login submissions. It is 'smart' enough to allow those requests through as specified by the
# shiro.loginUrl above.

/* = anon
CustomJDBCRealm
覆盖
JDBCRealm
如下所示

package com.connectifier.authc.realm;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

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.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.util.JdbcUtils;
import org.apache.shiro.util.SimpleByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author kiranchowdhary
 * 
 *         Application specific JDBC realm. If required override methods of {@link JdbcRealm} to load users, roles and
 *         permissions from database.
 * 
 *         Do not override configuration in code if it can be done via shiro.ini file.
 */
public class CustomJDBCRealm extends JdbcRealm {

    private static final Logger log = LoggerFactory.getLogger(JdbcRealm.class);

    public CustomJDBCRealm() {
        super();
        setSaltStyle(SaltStyle.COLUMN);
    }

    /**
     * overriding the method which is in JdbcRealm. If SaltStyle is COLUMN, then gets String salt value from database
     * and forms salt byte array of type {@link ByteSource} with decoded string salt value and sets it to salt value of
     * AuthenticationInfo.
     */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        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.");
        }

        Connection conn = null;
        SimpleAuthenticationInfo info = null;
        try {
            conn = dataSource.getConnection();

            String password = null;
            String salt = null;
            switch (saltStyle) {
            case NO_SALT:
            case CRYPT:
            case EXTERNAL:
                return super.doGetAuthenticationInfo(token);
            case COLUMN:
                String[] queryResults = getPasswordForUser(conn, username);
                password = queryResults[0];
                salt = queryResults[1];
                break;
            }

            if (password == null) {
                throw new UnknownAccountException("No account found for user [" + username + "]");
            }

            info = new SimpleAuthenticationInfo(username, password.toCharArray(), getName());

            if (salt != null) {
                info.setCredentialsSalt(new SimpleByteSource(Base64.decode(salt)));
            }

        } catch (SQLException e) {
            final String message = "There was a SQL error while authenticating user [" + username + "]";
            if (log.isErrorEnabled()) {
                log.error(message, e);
            }

            // Rethrow any SQL errors as an authentication exception
            throw new AuthenticationException(message, e);
        } finally {
            JdbcUtils.closeConnection(conn);
        }

        return info;
    }

    private String[] getPasswordForUser(Connection conn, String username) throws SQLException {

        String[] result;
        boolean returningSeparatedSalt = false;
        switch (saltStyle) {
        case NO_SALT:
        case CRYPT:
        case EXTERNAL:
            result = new String[1];
            break;
        default:
            result = new String[2];
            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.");
                }

                result[0] = rs.getString(1);
                if (returningSeparatedSalt) {
                    result[1] = rs.getString(2);
                }

                foundResult = true;
            }
        } finally {
            JdbcUtils.closeResultSet(rs);
            JdbcUtils.closeStatement(ps);
        }

        return result;
    }
}

thx很多,在我发布问题后,我才开始使用shiro。。。现在我有太多的问题,只有0票,我无法发布其他问题:(