使用 LDAP 身份验证和 JDBC 授权实现 Tomcat 领域 [英] Implement a Tomcat Realm with LDAP authentication and JDBC authorization
问题描述
我在旧环境中工作,其中 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,而将 findSecurityConstraints
和 hasUserDataPermission
都交给了 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屋!