Apereo CAS 5.0.X 默认提供的数据库认证的四种方式

Apereo CAS 5.0.X中为我们提供了四种基于JDBC的AuthenticationHandler的实现,在cas-server-support-jdbc子模块中,下面一一对他们进行介绍。

Query

配置一个SQL语句,该SQL可以通过传入的用户名查询返回该用户的密码,然后与用户输入的密码进行比较,进行比较之前,可以配置加密过程。匹配结果将作为认证结果,如果对应的用户名不存在也将返回false。

@Override
    protected HandlerResult authenticateUsernamePasswordInternal(final UsernamePasswordCredential credential, final String originalPassword)
            throws GeneralSecurityException, PreventedException {

        if (StringUtils.isBlank(this.sql) || getJdbcTemplate() == null) {
            throw new GeneralSecurityException("Authentication handler is not configured correctly. "  
                + "No SQL statement or JDBC template is found.");
        }

        final String username = credential.getUsername();
        final String password = credential.getPassword();

        try {
            final String dbPassword = getJdbcTemplate().queryForObject(this.sql, String.class, username);

            if ((StringUtils.isNotBlank(originalPassword) && !this.matches(originalPassword, dbPassword))
                  || (StringUtils.isBlank(originalPassword) && !StringUtils.equals(password, dbPassword))) {
                throw new FailedLoginException("Password does not match value on record.");
            }
        } catch (final IncorrectResultSizeDataAccessException e) {
            if (e.getActualSize() == 0) {
                throw new AccountNotFoundException(username + " not found with SQL query");
            } 
            throw new FailedLoginException("Multiple records found for " + username);
        } catch (final DataAccessException e) {
            throw new PreventedException("SQL exception while executing query for " + username, e);
        }

        return createHandlerResult(credential, this.principalFactory.createPrincipal(username), null);
    }

QueryAndEncode

跟上边一样的模式,不过密码再加密的时候可以配置加盐处理。

@Override
    protected HandlerResult authenticateUsernamePasswordInternal(final UsernamePasswordCredential transformedCredential)
            throws GeneralSecurityException, PreventedException {

        if (StringUtils.isBlank(this.sql) || StringUtils.isBlank(this.algorithmName) || getJdbcTemplate() == null) {
            throw new GeneralSecurityException("Authentication handler is not configured correctly");
        }

        final String username = transformedCredential.getUsername();
        try {
            final Map<String, Object> values = getJdbcTemplate().queryForMap(this.sql, username);
            final String digestedPassword = digestEncodedPassword(transformedCredential.getPassword(), values);

            if (!values.get(this.passwordFieldName).equals(digestedPassword)) {
                throw new FailedLoginException("Password does not match value on record.");
            }
            return createHandlerResult(transformedCredential,
                    this.principalFactory.createPrincipal(username), null);

        } catch (final IncorrectResultSizeDataAccessException e) {
            if (e.getActualSize() == 0) {
                throw new AccountNotFoundException(username + " not found with SQL query");
            } else {
                throw new FailedLoginException("Multiple records found for " + username);
            }
        } catch (final DataAccessException e) {
            throw new PreventedException("SQL exception while executing query for " + username, e);
        }

    }

SearchModeSearch

通过查询指定的表的指定的用户名和指定的密码的记录是否存在来判断是否验证通过。

@Override
    protected HandlerResult authenticateUsernamePasswordInternal(final UsernamePasswordCredential credential)
            throws GeneralSecurityException, PreventedException {

        String sql = null;
        if (StringUtils.isNotBlank(tableUsers) || StringUtils.isNotBlank(fieldUser) || StringUtils.isNotBlank(fieldPassword)) {
            sql = "SELECT COUNT('x') FROM ".concat(this.tableUsers).concat(" WHERE ").concat(this.fieldUser)
                    .concat(" = ? AND ").concat(this.fieldPassword).concat("= ?");
        }

        if (StringUtils.isBlank(sql) || getJdbcTemplate() == null) {
            throw new GeneralSecurityException("Authentication handler is not configured correctly. "
                    + "No SQL statement or JDBC template found");
        }

        final String username = credential.getUsername();
        try {
            logger.debug("Executing SQL query {}", sql);

            final int count = getJdbcTemplate().queryForObject(sql, Integer.class, username, credential.getPassword());
            if (count == 0) {
                throw new FailedLoginException(username + " not found with SQL query.");
            }
            return createHandlerResult(credential, this.principalFactory.createPrincipal(username), null);
        } catch (final DataAccessException e) {
            throw new PreventedException("SQL exception while executing query for " + username, e);
        }
    }

BindModeSearch

将试图以传入的用户名和密码从配置的DataSource中建立一个连接,如果连接成功,则表示认证成功,否则就是认证失败。

protected HandlerResult authenticateUsernamePasswordInternal(final UsernamePasswordCredential credential)
            throws GeneralSecurityException, PreventedException {

        if (getDataSource() == null) {
            throw new GeneralSecurityException("Authentication handler is not configured correctly");
        }

        Connection connection = null;
        try {
            final String username = credential.getUsername();
            final String password = credential.getPassword();
            connection = this.getDataSource().getConnection(username, password);
            return createHandlerResult(credential, this.principalFactory.createPrincipal(username), null);
        } catch (final SQLException e) {
            throw new FailedLoginException(e.getMessage());
        } catch (final Exception e) {
            throw new PreventedException("Unexpected SQL connection error", e);
        } finally {
            if (connection != null) {
                DataSourceUtils.releaseConnection(connection, this.getDataSource());
            }
        }
    }
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈振阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值