将 JAAS 用于具有 Spring 安全性的 LDAP 密码 [英] Use JAAS for LDAP password with Spring security

查看:20
本文介绍了将 JAAS 用于具有 Spring 安全性的 LDAP 密码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用 LDAP 身份验证的 Java EE Web 应用程序.我使用 Spring 安全性通过以下代码连接到我的 LDAP:

I have a Java EE web application which uses an LDAP authentication. I use Spring security to connect to my LDAP with the following code:

<bean id="ldapContextSource" class="com.myapp.security.authentication.MySecurityContextSource">
    <constructor-arg index="0" value="${ldap.url}" />
    <constructor-arg index="1" ref="userConnexion" />
</bean>

<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="ldapAuthProvider" />
</security:authentication-manager>

<bean id="userConnexion" class="com.myapp.util.security.WebsphereCredentials">
    <constructor-arg value="${ldap.authJndiAlias}" />
</bean>

<bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
    <constructor-arg>
        <bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
            <constructor-arg ref="ldapContextSource" />
            <property name="userSearch" ref="userSearch" />
        </bean>
    </constructor-arg>
    <constructor-arg>
        <bean class="com.myapp.security.authentication.MyAuthoritiesPopulator" >
            <property name="userService" ref="userService" />
        </bean>
    </constructor-arg>
    <property name="userDetailsContextMapper" ref="myUserDetailsContextMapper"/>
    <property name="hideUserNotFoundExceptions" value="false" />
</bean>

实际上,我的 bean WebsphereCredentials 使用 WebSphere 私有类 WSMappingCallbackHandlerFactory,如此响应:如何从部署到 Websphere 6.1 的 EJB 访问身份验证别名

Actually, my bean WebsphereCredentials uses a WebSphere private class WSMappingCallbackHandlerFactory as in this response : How to access authentication alias from EJB deployed to Websphere 6.1

我们可以在官方 websphere 文档中看到:http://pic.dhe.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=%2Fcom.ibm.websphere.express.doc%2Finfo%2Fexp%2Fae%2Frsec_pluginj2c.html

We can see it in the official websphere documentation: http://pic.dhe.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=%2Fcom.ibm.websphere.express.doc%2Finfo%2Fexp%2Fae%2Frsec_pluginj2c.html

但我不想要它,因为:

  1. 我认为我的应用程序可以访问我的 WebSphere 实例中的所有 JAAS 登录(不确定).
  2. 这个类是在巨大的 IBM 客户端库 com.ibm.ws.admin.client-7.0.0.jar (42 Mo) 中定义的 => 编译速度较慢,在我的企业关系中不存在
  3. 它不是便携的,不是标准的

关于信息,我将 WebsphereCredentials 构造函数定义为:

For information, I define the WebsphereCredentials constructor as this:

Map<String, String> map = new HashMap<String, String>();

map.put(Constants.MAPPING_ALIAS, this.jndiAlias);
Subject subject;
try {
    CallbackHandler callbackHandler = WSMappingCallbackHandlerFactory.getInstance().getCallbackHandler(map, null);
    LoginContext lc = new LoginContext("DefaultPrincipalMapping", callbackHandler);
    lc.login();
    subject = lc.getSubject();
} catch (NotImplementedException e) {
    throw new EfritTechnicalException(EfritTechnicalExceptionEnum.LOGIN_CREDENTIAL_PROBLEM, e);
} catch (LoginException e) {
    throw new EfritTechnicalException(EfritTechnicalExceptionEnum.LOGIN_CREDENTIAL_PROBLEM, e);
}

PasswordCredential cred = (PasswordCredential) subject.getPrivateCredentials().toArray()[0];

this.user = cred.getUserName();
this.password = String.valueOf(cred.getPassword());

有没有办法只使用 Spring 安全性并删除此依赖项?

Is there a way to use just Spring security and remove this dependency?

我不知道如何结合 http://static.springsource.org/spring-security/site/docs/3.1.x/reference/jaas.htmlhttp://static.springsource.org/spring-security/site/docs/3.1.x/reference/ldap.html.

I have no idea how to combine http://static.springsource.org/spring-security/site/docs/3.1.x/reference/jaas.html and http://static.springsource.org/spring-security/site/docs/3.1.x/reference/ldap.html.

也许我必须完全改变我的方法并使用另一种方式?

Maybe I must totally change my approach and use another way?

推荐答案

我假设您的目标是简单地使用您在 WebSphere 中配置的用户名/密码来连接到 LDAP 目录?如果是这种情况,您并没有真正尝试结合 LDAP 和基于 JAAS 的身份验证.JAAS 支持实际上旨在成为一种使用 JAAS LoginModule 来验证用户身份的方式,而不是使用基于 LDAP 的身份验证.

I assume your goal is to simply utilize the username / password that you configure in WebSphere to connect to the LDAP directory? If this is the case, you are not really trying to combine LDAP and JAAS based authentication. The JAAS support is really intended to be a way of using JAAS LoginModules to authenticate a user instead of using the LDAP based authentication.

如果您想获得用户名和密码而不依赖于 WebSphere 的编译时,您有几个选择.

If you are wanting to obtain the username and password without having a compile time dependency on WebSphere, you have a few options.

一种选择是以不同的方式配置密码.这可以像直接在配置文件中直接使用密码一样简单,如 Spring Security LDAP 文档:

One option is to configure the password in a different way. This could be as simple as using the password directly directly in the configuration file as shown in the Spring Security LDAP documentation:

<bean id="ldapContextSource"
        class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
  <constructor-arg value="ldap://monkeymachine:389/dc=springframework,dc=org"/>
  <property name="userDn" value="cn=manager,dc=springframework,dc=org"/>
  <property name="password" value="password"/>
</bean>

您还可以在 JNDI 中配置用户名密码.另一种选择是使用带有属性的 .properties 文件.如果您想确保密码是安全的,那么您可能需要使用类似 Jasypt.

You could also configure the username password in JNDI. Another alternative is to use a .properties file with the Property. If you are wanting to ensure the password is secured, then you will probably want to encrypt the password using something like Jasypt.

如果您需要或想要使用 WebSphere 的 J2C 支持来存储凭证,那么您可以通过注入 CallbackHandler 实例来实现.例如,您的 WebsphereCredentials bean 可能是这样的:

If you need or want to use WebSphere's J2C support for storing the credentials, then you can do by injecting the CallbackHandler instance. For example, your WebsphereCredentials bean could be something like this:

try {
    LoginContext lc = new LoginContext("DefaultPrincipalMapping", this.callbackHandler);
    lc.login();
    subject = lc.getSubject();
} catch (NotImplementedException e) {
    throw new EfritTechnicalException(EfritTechnicalExceptionEnum.LOGIN_CREDENTIAL_PROBLEM, e);
} catch (LoginException e) {
    throw new EfritTechnicalException(EfritTechnicalExceptionEnum.LOGIN_CREDENTIAL_PROBLEM, e);
}

PasswordCredential cred = (PasswordCredential) subject.getPrivateCredentials().toArray()[0];

this.user = cred.getUserName();
this.password = String.valueOf(cred.getPassword());

您的配置将如下所示:

<bean id="userConnexion" class="com.myapp.util.security.WebsphereCredentials">
    <constructor-arg ref="wasCallbackHandler"/>
</bean>

<bean id="wasCallbackHandler"
      factory-bean="wasCallbackFactory"
      factory-method="getCallbackHandler">
    <constructor-arg>
      <map>
        <entry
            value="${ldap.authJndiAlias}">
          <key>
            <util:constant static-field="com.ibm.wsspi.security.auth.callback.Constants.MAPPING_ALIAS"/>
          </key>
        </entry>
      </map>
    </constructor-arg>
    <constructor-arg>
      <null />
    </constructor-arg>
</bean>

<bean id="wasCallbackFactory"
    class="com.ibm.wsspi.security.auth.callback.WSMappingCallbackHandlerFactory"
    factory-method="getInstance" />

免责声明

CallbackHandler 实例不是线程安全的,通常不应多次使用.因此,将 CallbackHandler 实例作为成员变量注入可能有点冒险.您可能需要编写一个检查程序以确保 CallbackHandler 只使用一次.

Disclaimer

CallbackHandler instances are not Thread safe and generally should not be used more than once. Thus it can be a bit risky injecting CallbackHandler instances as member variables. You may want to program in a check to ensure that the CallbackHandler only used one time.

您可以采用一种混合方法,该方法始终删除编译时依赖项,并允许您在可能未在 WebSphere 上运行的实例中删除运行时依赖项.这可以通过结合这两个建议并使用 Spring Bean 定义配置文件 以区分在 WebSphere 和非 WebSphere 机器上运行.

You could do a hybrid approach that always removes the compile time dependency and allows you to remove the runtime dependency in instances where you might not be running on WebSphere. This could be done by combining the two suggestions and using Spring Bean Definition Profiles to differentiate between running on WebSphere and a non-WebSphere machine.

这篇关于将 JAAS 用于具有 Spring 安全性的 LDAP 密码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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