使用Spring Security JAAS的LDAP密码 [英] Use JAAS for LDAP password with Spring security

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

问题描述

我有一个使用LDAP身份验证的Java EE Web应用程序。我使用Spring Security与以下code连接到我的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>

其实,我的豆 WebsphereCredentials 使用的WebSphere私有类 WSMappingCallbackHandlerFactory 在此回应:<一href=\"http://stackoverflow.com/questions/4663534/how-to-access-authentication-alias-from-ejb-deployed-to-websphere-6-1\">How从EJB部署到WebSphere 6.1 访问认证别名

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文档中:<一href=\"http://pic.dhe.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=%2Fcom.ibm.websphere.ex$p$pss.doc%2Finfo%2Fexp%2Fae%2Frsec_pluginj2c.html\" rel=\"nofollow\">http://pic.dhe.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=%2Fcom.ibm.websphere.ex$p$pss.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)的定义=>编译速度较慢,不在我的企业关系present

  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());

有只使用弹簧安全和消除这种依赖的方式?

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.html和的http://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 s到验证,而不是使用基于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 <密码/ A>。

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 豆可能是这样的:

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());

您的配置,然后会是这个样子:

Your configuration would then look something like this:

<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运行实例的运行依赖。这可以通过组合两个建议,并使用<一做href=\"http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/new-in-3.1.html#new-in-3.1-bean-definition-profiles\"相对=nofollow>的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.

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

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