使用 LDAP 身份验证和 JDBC 授权实现 Tomcat 领域 [英] Implement a Tomcat Realm with LDAP authentication and JDBC authorization

查看:23
本文介绍了使用 LDAP 身份验证和 JDBC 授权实现 Tomcat 领域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在旧环境中工作,其中 LDAP 服务器仅用于身份验证并且不包含任何角色,并且针对包含用户角色映射但没有密码的数据库完成授权.

I'm working in a legacy environment where an LDAP server is used only for authentication and contains no roles, and authorization is done against a database which contains the user-role mapping, but no passwords.

我的计划是通过扩展 JNDIRealm 来实现一个新的 Tomcat 领域,并重写角色方法以调用封装的 JDBCRealm.

My plan is to implement a new Tomcat Realm by extending JNDIRealm, and overriding the role methods to call an encapsulated JDBCRealm.

我的领域在 server.xml 中声明:

My realm is declared in server.xml:

<Realm className="com.example.LdapJdbcRealm"
   connectionURL="ldap://ldaphost:389"
   resourceName="LDAP Auth"
   userPattern="uid={0}, ou=Portal, dc=example, dc=com"
   dbConnectionURL="jdbc:oracle:thin:@oracledb:1521:dbname"
   userTable="db_user" userNameCol="user_id"
   userRoleTable="db_user_role_xref" roleNameCol="role_id" />

这是 JNDIRealm & 的标准属性名称的组合.JDBCRealm,稍作改动,因为它们都使用 connectionURL.

This is a combination of the standard property names for JNDIRealm & JDBCRealm, with a little change as they both use connectionURL.

package com.example;

import org.apache.catalina.Realm;
import org.apache.catalina.Context;
import org.apache.catalina.deploy.SecurityConstraint;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.realm.JNDIRealm;
import org.apache.catalina.realm.JDBCRealm;

import java.security.Principal;
import java.io.IOException;

public class LdapJdbcRealm extends JNDIRealm implements Realm
{
    private JDBCRealm jdbcRealm = new JDBCRealm();

    protected static final String info = "com.example.LdapJdbcRealm/1.0";
    protected static final String name = "LdapJdbcRealm";

    public String getDbConnectionURL() {
        return jdbcRealm.getConnectionURL();
    }

    public void setDbConnectionURL(String dbConnectionURL) {
        jdbcRealm.setConnectionURL(dbConnectionURL);
    }

    public String getUserTable() {
        return jdbcRealm.getUserTable();
    }

    public void setUserTable(String userTable) {
        jdbcRealm.setUserTable(userTable);
    }

    public String getUserNameCol() {
        return jdbcRealm.getUserNameCol();
    }

    public void setUserNameCol(String userNameCol) {
        jdbcRealm.setUserNameCol(userNameCol);
    }

    public String getUserRoleTable() {
        return jdbcRealm.getUserRoleTable();
    }

    public void setUserRoleTable(String userRoleTable) {
        jdbcRealm.setUserRoleTable(userRoleTable);
    }

    public String getRoleNameCol() {
        return jdbcRealm.getRoleNameCol();
    }

    public void setRoleNameCol(String roleNameCol) {
        jdbcRealm.setRoleNameCol(roleNameCol);
    }

    public boolean hasResourcePermission(Request request,
                                         Response response,
                                         SecurityConstraint[]constraints,
                                         Context context) throws IOException
    {
        return jdbcRealm.hasResourcePermission(request, response, constraints, context);
    }

    public boolean hasRole(Principal principal, String role) {
        return jdbcRealm.hasRole(principal, role);
    }
}

这似乎很有效,授权从 LDAP 返回一个 Principal,它没有预期的角色.同一个 Principal 进入 hasResourcePermission() 并失败,因为它没有 require 角色.显然我遗漏了一些关键代码.

This mostly seems to work, the authorization returns a Principal from LDAP, which has no roles as expected. That same Principal enters hasResourcePermission() and fails because it doesn't have the require roles in it. Clearly I'm missing some crucial code.

我正在寻找解决方案.我可以尝试扩展 JDBCRealm 并添加 LDAP 身份验证,但这似乎需要更多工作.

I'm looking for solutions. I could try extending JDBCRealm and adding LDAP authentication, but that seems like more work.

我也相信这种 LDAP 身份验证/数据库授权并不是一种不常见的模式.是否已经有替代解决方案可用?

I also believe that this LDAP authentication/DB authorization is not an uncommon pattern. Is there an alternative solution already available?

向 LDAP 添加角色或向数据库添加密码在我的控制范围内,所以这些不是我的解决方案.

It is not within my control to add roles to LDAP or passwords to the DB, so those are not solutions for me.

推荐答案

你没有指定你使用的Tomcat的版本,所以我这里用6.x.

You haven't specified the version of Tomcat you're using, so I'm going with 6.x here.

看起来您将 hasResourcePermission 委托给 JDBC,而将 findSecurityConstraintshasUserDataPermission 都交给了 JNDI.您应该全部委托或不委托.

It looks like you're delegating hasResourcePermission to JDBC while leaving both findSecurityConstraints and hasUserDataPermission in hands of JNDI. You should delegate all of them or none of them.

更新:JNDIRealm 调用protected getRoles(DirContext, User) 作为其authenticate() 方法的一部分.您需要覆盖它并将其转发到 JDBCRealm 的 getRoles().

Update: JNDIRealm calls protected getRoles(DirContext, User) as part of its authenticate() method. You need to override that and forward it to JDBCRealm's getRoles().

这篇关于使用 LDAP 身份验证和 JDBC 授权实现 Tomcat 领域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆