从FacesContext获取LDAPContext的最简单方法是什么?

时间:2015-04-06 19:48:22

标签: jsf ldap httpsession jboss-eap-6 facescontext

我从JSF页面调用了一个Java doLogin()方法,该方法从用户获取id(String netId)和密码(String password)。 doLogin()使用netId作为Active Directory登录中的主体来启动身份验证。之后,我想从保护我的应用程序的目录中获取除主体名称之外的其他属性。

我的安全性是在容器和配置中配置的。它有效,

HttpSession ses = FacesContext.getCurrentInstance().getExternalContext().getSession (false);
HttpServletRequest req = FacesContext.getCurrentInstance().getExternalContext().getRequest();

req.login(netID, password);

成功并且

req.getUserPrincipal().getName();

返回用户netID。但是,我的应用仅使用netId进行身份验证。访问另一个数据库的应用程序的其他部分需要其他属性(例如commonName)。我想做像

这样的事情
usefulLDAPobj = *getLDAPSession from "somewhere" in the HTTP Session, the FacesContext or some other available object*

String cn = usefulLDAPobj.getAttributeFromProfile ("cn");

ses.setAttribute("username", cn);

从此开始使用用户名,存储在会话中,在我的Hibernate ORM中。

我知道简单的usefulLDAPobj.getAttributeFromProfile ("cn")会更复杂,但如果能找到一个让我访问LDAP目录的起点,我可以填写。

由于容器设置了明显的LDAP连接,我觉得必须是我使用它的一种方式,而无需以编程方式手动构建LdapContext;这将要求代码知道Web服务器(JBoss EAP 6.2)已经知道的所有LDAP server / bind-DN / bind-password configuration(来自<login-module>中定义的standalone.xml)。例如,getUserPrincipal()isUserInRole()等方法需要访问我想要访问的同一个目录配置文件。

所以我的问题是:有没有办法从FacesContext或HTTPServletRequest获取LDAP连接或上下文,或者从HTTPServlet可以访问任何对象?

2 个答案:

答案 0 :(得分:0)

  

从FacesConext获取LdapConext的最简单方法是什么?

根本没有办法,更不用说一个简单的方法了。 JSF不假设存在LDAP服务器,也不提供任何与LDAP相关的API。

  

由于容器设置了明显的LDAP连接

登录时。不是永久性的。如果有LDAP服务器的话。并且JSF不知道容器如何登录你。

  

我觉得必须有办法...

没有。

答案 1 :(得分:0)

我认为这个问题的一个有用的答案是没有办法直接从LDAPContext获取FacesContext,而是通过编写特定于容器的登录模块和{ {1}}类,您可以通过Principal 获得的HttpServletRequest传递其他数据。

我会在此处提供我的解决方案的详细信息,因为即使它与FacesContext没有直接关系,它也能解释我在问题正文中要求的内容,即从LDAP配置文件获取其他用户数据的方法,同时避免创建一个完整的单独FacesContext

我特别想要的是LDAPContext,我可以解析CN而无需进行额外搜索。如果我需要任何其他数据,我认为我可以使用下面DN中的ctx来获取该数据。

我想我的应用依赖于findUserDN()这个解决方案,如果这是不可取的,我会搜索一个JBoss - 独立的登录模块类来扩展(不知道是否会这样)简单,困难或不可能)。

这是我的解决方案:

  1. 在AdvancedADLoginModule中覆盖findUserDN(LdapContext ctx)

    JBoss
  2. extend Principal以提供displayName属性

    package ca.mycompany.myapp.jboss;
    
    import java.security.Principal;
    
    import javax.naming.ldap.LdapContext;
    import javax.security.auth.login.LoginException;
    
    import org.jboss.security.negotiation.AdvancedADLoginModule;
    
    public class NameFetchingADLoginModule extends AdvancedADLoginModule
    
        @Override
        protected String findUserDN(LdapContext ctx) throws LoginException
        {
            String lclUserDN = super.findUserDN(ctx);
    
            Principal principal = getIdentity();
    
            if (principal instanceof PrincipalWithDisplayName)
            {
                String displayName = lclUserDN.substring(3, lclUserDN.indexOf(','));
                ((PrincipalWithDisplayName) principal).setDisplayName (displayName);
            }
    
            return lclUserDN;
        }
    }
    
  3. 在doLogin()方法中使用新的登录模块和Principal

  4. 片段:

    package ca.mycompany.myapp.jboss;
    
    import java.io.Serializable;
    import java.security.Principal;
    
    public class PrincipalWithDisplayName implements Serializable, Principal
    {
        private static final long serialVersionUID = 1L;
        private final String name;
    
        // additional attribute provided by this subclass
        private String displayName;
    
        public PrincipalWithDisplayName(final String name) {
            this.name = name;
        }
    
        // new and overriding getters and setters, equals() and hashCode() removed for brevity
    }
    
    1. String displayName = ""; HttpSession ses = FacesContext.getCurrentInstance().getExternalContext().getSession (false); HttpServletRequest req = FacesContext.getCurrentInstance().getExternalContext().getRequest(); try { req.login(userName, password); // this throws an exception if authentication fails Principal lclUser = req.getUserPrincipal(); if (lclUser instanceof PrincipalWithDisplayName) { displayName = ((PrincipalWithDisplayName) lclUser).getDisplayName (); } // get Http Session and store username // HttpSession session = HttpUtil.getSession(); sess.setAttribute("username", displayName); ... 中配置JBoss EAP 6.2以使用新类
    2. 片段:

      standalone.xml