2011-08-19 34 views
5

Chúng tôi đang sử dụng bảo mật mùa xuân để xác thực người dùng từ LDAP trong ứng dụng của chúng tôi. Phần xác thực đang hoạt động đúng nhưng phần ủy quyền không hoạt động.Cách điền chính quyền LDAP từ Active Directory LDAP bằng bảo mật mùa xuân?

Chúng tôi không thể truy xuất vai trò của người dùng từ LDAP.

Từ cuốn sách "Xuân An 3" bởi Peter Mularien

"Điều này là do kích hoạt các cửa hàng thư mục nhóm thành viên như là thuộc tính trên các mục LDAP của người sử dụng tự. Ra khỏi hộp (tính thời gian xuất bản), Bảo mật mùa xuân không cung cấp LdapAuthoritiesPopulator có thể được định cấu hình để hỗ trợ cấu trúc của cây LDAP Active Directory điển hình. "

Dưới đây là tệp cấu hình bảo mật mùa xuân của tôi.

<?xml version="1.0" encoding="UTF-8"?> 

<beans:beans xmlns="http://www.springframework.org/schema/security" 
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
          http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"> 

     <http use-expressions="true" > 
     <intercept-url pattern="/resources/**" filters="none" /> 
     <intercept-url pattern="/login" access="permitAll"/> 
     <intercept-url pattern="/**" access="isAuthenticated()" /> 
     <form-login login-page="/login" 
        default-target-url="/home" 
        always-use-default-target="true" 
        authentication-failure-url="/login?login_error=1" /> 
     <logout invalidate-session="true" 
       logout-success-url="/" 
       logout-url="/logout"/> 
    </http> 

    <authentication-manager alias="ldapAuthenticationManager"> 
     <authentication-provider ref="ldapAuthenticationProvider"/> 
    </authentication-manager> 

    <beans:bean id="ldapAuthenticationProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider"> 
     <beans:constructor-arg ref="ldapBindAuthenticator"/> 
     <beans:constructor-arg ref="ldapAuthoritiesPopulator"/> 
     <beans:property name="userDetailsContextMapper" ref="ldapUserDetailsContextMapper"/> 
    </beans:bean> 

    <beans:bean id="ldapServer" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource"> 
     <!-- MS Active Directory --> 
     <beans:constructor-arg value="ldap://localhost:389/dc=myOrg,dc=net"/> 
     <beans:property name="userDn" value="admin"/> 
     <beans:property name="password" value="admin"/> 
     <beans:property name="baseEnvironmentProperties"> 
      <beans:map> 
       <beans:entry key="java.naming.referral" value="follow" /> 
      </beans:map> 
     </beans:property> 
    </beans:bean> 

    <beans:bean id="ldapBindAuthenticator" class="org.springframework.security.ldap.authentication.BindAuthenticator"> 
     <beans:constructor-arg ref="ldapServer"/> 
     <beans:property name="userSearch" ref="ldapSearchBean"/> 
    </beans:bean> 

    <beans:bean id="ldapSearchBean" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch"> 
     <!-- MS Active Directory --> 
     <!-- user-search-base; relative to base of configured context source --> 
     <beans:constructor-arg value="ou=Software OU"/> 
     <!-- user-search-filter --> 
     <beans:constructor-arg value="(sAMAccountName={0})"/> 
     <beans:constructor-arg ref="ldapServer"/> 
    </beans:bean> 

    <beans:bean id="ldapAuthoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator"> 
     <beans:constructor-arg ref="ldapServer" /> 
     <beans:constructor-arg value="" /> 
     <beans:property name="groupSearchFilter" value="(sAMAccountName={0})"/> 
     <beans:property name="groupRoleAttribute" value="memberOf" /> 
     <beans:property name="rolePrefix" value=""/> 
     <beans:property name="searchSubtree" value="true"/> 
     <beans:property name="convertToUpperCase" value="false"/> 
     <beans:property name="ignorePartialResultException" value="true"/> 
    </beans:bean> 

    <beans:bean class="org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper" id="ldapUserDetailsContextMapper"/> 

</beans:beans> 

Xin vui lòng trợ giúp.

+0

Điều gì bị thiếu trong mã của bạn? Việc chấp nhận giải pháp/siêu liên kết được cung cấp là một điều, nhưng chỉ ra phần còn thiếu sẽ là tuyệt vời để giúp những người khác (như tôi) có cùng một vấn đề chính xác. Cảm ơn bạn đã chia sẻ giải pháp chi tiết của bạn. –

+1

@CharlesMorin Tôi nhận ra câu trả lời của tôi là phụ cận, xin lỗi. Thêm cấu hình Spring của chúng tôi cho AD. –

+0

@ MarcelStör Cảm ơn bạn. Bạn đang sử dụng máy chủ ứng dụng nào? Tôi đang cố gắng để có những điều tương tự làm việc trên JBoss AS 7.2, mà không có bất kỳ thành công. Sẽ xem xét cấu hình của bạn. –

Trả lời

2

Bạn có thể muốn xem tại đây: https://jira.springsource.org/browse/SEC-876. Mặc dù sự đóng góp mã này đã bị từ chối, với một câu trả lời hợp lý, nó có thể cung cấp cho bạn gợi ý.

Chúng tôi sử dụng các cấu hình sau:

Xuân XML

<bean id="ldapUserService" class="MyUserDetailService"> 
    <constructor-arg ref="ldapUserSearch"/> 
    <constructor-arg ref="ldapAuthoritiesPopulator"/> 
</bean> 
<bean id="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch"> 
    <constructor-arg value="OU=FOO-Accounts,OU=FOO,OU=OU-GLOBAL"/> <!-- user search base, RELATIVE TO SERVER CONTEXT (URL & base of configured LDAP server)! --> 
    <constructor-arg value="(sAMAccountName={0})"/> <!-- user search filter --> 
    <constructor-arg ref="ldapServer"/> 
</bean> 
<bean id="ldapAuthoritiesPopulator" class="MyLdapAuthoritiesPopulator"> 
    <constructor-arg ref="ldapServer" /> 
    <constructor-arg value="=OU=SomeFooBar,OU=FOO-Global-Security,OU=FOO-Groups,OU=FOO,OU=OU-GLOBAL" /> <!-- group search base, RELATIVE TO SERVER CONTEXT (URL & base of configured LDAP server)! --> 
    <constructor-arg ref="roleMappings"/> 
    <property name="groupRoleAttribute" value="cn" /> 
    <property name="groupSearchFilter" value="(member={0})" /> 
</bean> 

Populator

Có rất nhiều mã độc quyền tôi không thể chia sẻ vì khách hàng của chúng tôi có thông tin bổ sung trong AD chúng ta cần trích xuất. Tôi đã loại bỏ điều đó vì không quan tâm đến câu hỏi này. Do đó, mã này sẽ không biên dịch.

public class MyLdapAuthoritiesPopulator extends DefaultLdapAuthoritiesPopulator { 

    /** 
    * Prefix assigned by Spring Security to each group/role from LDAP. 
    */ 
    public static final String AUTHORITY_ROLE_PREFIX = "ROLE_"; 

    private Properties roleMappings; 
    private Properties invertedRoleMappings; 

    /** 
    * 
    * @param contextSource supplies the contexts used to search for user roles. 
    * @param groupSearchBase if this is an empty string the search will be performed from the root DN 
    * of the context factory. If null, no search will be performed. 
    * @param roleMappings maps logical (internal) role names to names as delivered by LDAP 
    */ 
    @SuppressWarnings("deprecation") 
    public MyLdapAuthoritiesPopulator(final ContextSource contextSource, 
     final String groupSearchBase, 
     final Properties roleMappings) { 
    super(contextSource, groupSearchBase); 
    setConvertToUpperCase(false); 
    setRolePrefix(""); 
    this.roleMappings = roleMappings; 
    this.invertedRoleMappings = invertRoleMappings(); 
    logger.info("Processing LDAP roles based on the following mapping: {}.", roleMappings); 
    } 

    ..... 

    @Override 
    public Set<GrantedAuthority> getGroupMembershipRoles(final String userDn, final String username) { 
    final Set<GrantedAuthority> effectiveGroupMembershipRoles = super.getGroupMembershipRoles(
     userDn, username); 
    return mapEffectiveRolesToApplicationRoles(effectiveGroupMembershipRoles); 
    } 

    /** 
    * Maps effective LDAP roles such as 'foo_boston_dispatcher' or 'foo_boston_readonly' to 
    * FOO internal roles. The internal role (i.e. the {@link GrantedAuthority}) is a combination 
    * of the 'ROLE_' prefix and a {@link Role} enum value. ......... 
    */ 
    Set<GrantedAuthority> mapEffectiveRolesToApplicationRoles(final Set<GrantedAuthority> effectiveGroupMembershipRoles) { 
    logger.info("Processing effective roles from LDAP: {}.", effectiveGroupMembershipRoles); 
    final Set<GrantedAuthority> internalRoles = new HashSet<GrantedAuthority>(); 
    final List<String> effectiveRoleNames = extractRoleNamesFrom(effectiveGroupMembershipRoles); 
    final List<String> unmappedGroupMembershipRoles = new ArrayList<String>(); 
    ...... 
    // in a method invoked here we do something like internalRoles.add(new GrantedAuthority(AUTHORITY_ROLE_PREFIX + role)); 
    ...... 
    logger.info("Created internal roles {}.", internalRoles); 
    logger.trace(
     "The following group membership roles were not mapped to an internal equivalent: {}", 
     unmappedGroupMembershipRoles); 
    return internalRoles; 
    } 

    ...... 

    private List<String> extractRoleNamesFrom(final Collection<GrantedAuthority> authorities) { 
    final List<String> authorityNames = new ArrayList<String>(authorities.size()); 
    for (GrantedAuthority authority : authorities) { 
     authorityNames.add(authority.getAuthority()); 
    } 
    return authorityNames; 
    } 
} 
+0

Bạn có muốn chia sẻ lớp MyLdapAuthoritiesPopulator của mình không? Cảm ơn bạn. –

Các vấn đề liên quan