Details

    • Type: New Feature
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.1.0.M2
    • Component/s: Security
    • Labels:
      None

      Description

      One key feature for SP 1.1 is LDAP support from the security section.

        Issue Links

          Activity

          Hide
          gregturn Greg Turnquist added a comment -

          Got authentication/authorization working for CPython. However libraries are CPython only. Need to figure alternative mechanism for Jython.

          Show
          gregturn Greg Turnquist added a comment - Got authentication/authorization working for CPython. However libraries are CPython only. Need to figure alternative mechanism for Jython.
          Hide
          gregturn Greg Turnquist added a comment -

          Managed to split up Ldap.py into _Ldap_cpython.py and _Ldap_jython.py, and conditionally import the right one. Also got jars working, so that _Ldap_jython.py is using Spring Security/Spring LDAP under the hood.

          test.py script that exercises everything:
          ===============================================
          from springpython.security.providers import UsernamePasswordAuthenticationToken
          from springpython.security.providers.Ldap import DefaultSpringSecurityContextSource
          from springpython.security.providers.Ldap import BindAuthenticator
          from springpython.security.providers.Ldap import PasswordComparisonAuthenticator
          from springpython.security.providers.Ldap import DefaultLdapAuthoritiesPopulator
          from springpython.security.providers.Ldap import LdapAuthenticationProvider

          context = DefaultSpringSecurityContextSource(url="ldap://localhost:53389/dc=springframework,dc=org")
          bindAuthenticator = BindAuthenticator(context_source=context, user_dn_patterns="uid=

          {0},ou=people")
          populator = DefaultLdapAuthoritiesPopulator(context_source=context, group_search_base="ou=groups")
          authProvider = LdapAuthenticationProvider(ldap_authenticator=bindAuthenticator, ldap_authorities_populator=populator)

          passwordAuthenticator = PasswordComparisonAuthenticator(context_source=context, user_dn_patterns="uid={0}

          ,ou=people")
          authProvider2 = LdapAuthenticationProvider(ldap_authenticator=passwordAuthenticator, ldap_authorities_populator=populator)

          authentication = UsernamePasswordAuthenticationToken(username="bob", password="bobspassword")

          print "Input = %s" % authentication

          auth1 = authProvider.authenticate(authentication)

          print "Bind output = %s" % auth1

          print "Input = %s" % authentication

          auth2 = authProvider2.authenticate(authentication)

          print "PasswordComparison output = %s" % auth2
          ===============================================
          ...is generating this stack trace:
          ===============================================
          jython test.py
          You are in Jython!
          Using Spring Security to do our LDAP dirty work!
          2009/11/16 10:07:57 [ INFO] DefaultSpringSecurityContextSource.<init> - URL 'ldap://localhost:53389/dc=springframework,dc=org', root DN is 'dc=springframework,dc=org'
          2009/11/16 10:07:57 [DEBUG] AbstractContextSource.afterPropertiesSet - AuthenticationSource not set - using default implementation
          2009/11/16 10:07:57 [ INFO] AbstractContextSource.afterPropertiesSet - Property 'userDn' not set - anonymous context will be used for read-write operations
          2009/11/16 10:07:57 [DEBUG] AbstractContextSource.setupAnonymousEnv - Not using LDAP pooling
          2009/11/16 10:07:57 [DEBUG] AbstractContextSource.setupAnonymousEnv - Trying provider Urls: ldap://localhost:53389/dc=springframework,dc=org
          Context class loader [email protected]
          Context class loader [email protected]
          Input = [UsernamePasswordAuthenticationToken] User: [bob] Password: [PROTECTED] GrantedAuthorities: [] Authenticated: False
          Context class loader [email protected]
          2009/11/16 10:07:57 [DEBUG] DefaultSpringSecurityContextSource.getReadWriteContext - Creating context with principal: 'uid=bob,ou=people,dc=springframework,dc=org'
          2009/11/16 10:07:57 [DEBUG] AbstractContextSource.createContext - Got Ldap context on server 'ldap://localhost:53389/dc=springframework,dc=org'
          Context class loader [email protected]
          2009/11/16 10:07:57 [DEBUG] DefaultLdapAuthoritiesPopulator.getGrantedAuthorities - Getting authorities for user uid=bob,ou=people,dc=springframework,dc=org
          2009/11/16 10:07:57 [DEBUG] DefaultLdapAuthoritiesPopulator.getGroupMembershipRoles - Searching for roles for user 'bob', DN = 'uid=bob,ou=people,dc=springframework,dc=org', with filter (member=

          {0}

          ) in search base 'ou=groups'
          2009/11/16 10:07:57 [DEBUG] SpringSecurityLdapTemplate.searchForSingleAttributeValues - Using filter: (member=uid=bob,ou=people,dc=springframework,dc=org)
          2009/11/16 10:07:57 [ INFO] LdapTemplate.assureReturnObjFlagSet - The returnObjFlag of supplied SearchControls is not set but a ContextMapper is used - setting flag to true
          2009/11/16 10:07:57 [DEBUG] AbstractContextSource.createContext - Got Ldap context on server 'ldap://localhost:53389/dc=springframework,dc=org'
          Traceback (most recent call last):
          File "test.py", line 20, in <module>
          auth1 = authProvider.authenticate(authentication)
          File "/home/gregturn/src/se-springpython-py/sandbox/gregturnquist/sespringpythonpy-121/src/springpython/security/providers/_Ldap_jython.py", line 106, in authenticate
          results.granted_auths = self.ldap_authorities_populator.get_granted_auths(user_details, authentication.username)
          File "/home/gregturn/src/se-springpython-py/sandbox/gregturnquist/sespringpythonpy-121/src/springpython/security/providers/_Ldap_jython.py", line 90, in get_granted_auths
          results = self._populator.getGrantedAuthorities(user_details, username)
          at org.springframework.security.ldap.SpringSecurityLdapTemplate$2.mapFromContext(SpringSecurityLdapTemplate.java:154)
          at org.springframework.ldap.core.ContextMapperCallbackHandler.getObjectFromNameClassPair(ContextMapperCallbackHandler.java:67)
          at org.springframework.ldap.core.CollectingNameClassPairCallbackHandler.handleNameClassPair(CollectingNameClassPairCallbackHandler.java:50)
          at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:297)
          at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:259)
          at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:606)
          at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:524)
          at org.springframework.security.ldap.SpringSecurityLdapTemplate.searchForSingleAttributeValues(SpringSecurityLdapTemplate.java:170)
          at org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator.getGroupMembershipRoles(DefaultLdapAuthoritiesPopulator.java:206)
          at org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator.getGrantedAuthorities(DefaultLdapAuthoritiesPopulator.java:179)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
          at java.lang.reflect.Method.invoke(Method.java:597)

          java.lang.ClassCastException: java.lang.ClassCastException: com.sun.jndi.ldap.LdapCtx cannot be cast to org.springframework.ldap.core.DirContextAdapter
          ===============================================
          Found thread that talks about class loader issue involving this exact error at http://forum.springsource.org/showthread.php?p=203132. Not sure how to proceed.

          Show
          gregturn Greg Turnquist added a comment - Managed to split up Ldap.py into _Ldap_cpython.py and _Ldap_jython.py, and conditionally import the right one. Also got jars working, so that _Ldap_jython.py is using Spring Security/Spring LDAP under the hood. test.py script that exercises everything: =============================================== from springpython.security.providers import UsernamePasswordAuthenticationToken from springpython.security.providers.Ldap import DefaultSpringSecurityContextSource from springpython.security.providers.Ldap import BindAuthenticator from springpython.security.providers.Ldap import PasswordComparisonAuthenticator from springpython.security.providers.Ldap import DefaultLdapAuthoritiesPopulator from springpython.security.providers.Ldap import LdapAuthenticationProvider context = DefaultSpringSecurityContextSource(url="ldap://localhost:53389/dc=springframework,dc=org") bindAuthenticator = BindAuthenticator(context_source=context, user_dn_patterns="uid= {0},ou=people") populator = DefaultLdapAuthoritiesPopulator(context_source=context, group_search_base="ou=groups") authProvider = LdapAuthenticationProvider(ldap_authenticator=bindAuthenticator, ldap_authorities_populator=populator) passwordAuthenticator = PasswordComparisonAuthenticator(context_source=context, user_dn_patterns="uid={0} ,ou=people") authProvider2 = LdapAuthenticationProvider(ldap_authenticator=passwordAuthenticator, ldap_authorities_populator=populator) authentication = UsernamePasswordAuthenticationToken(username="bob", password="bobspassword") print "Input = %s" % authentication auth1 = authProvider.authenticate(authentication) print "Bind output = %s" % auth1 print "Input = %s" % authentication auth2 = authProvider2.authenticate(authentication) print "PasswordComparison output = %s" % auth2 =============================================== ...is generating this stack trace: =============================================== jython test.py You are in Jython! Using Spring Security to do our LDAP dirty work! 2009/11/16 10:07:57 [ INFO] DefaultSpringSecurityContextSource.<init> - URL 'ldap://localhost:53389/dc=springframework,dc=org', root DN is 'dc=springframework,dc=org' 2009/11/16 10:07:57 [DEBUG] AbstractContextSource.afterPropertiesSet - AuthenticationSource not set - using default implementation 2009/11/16 10:07:57 [ INFO] AbstractContextSource.afterPropertiesSet - Property 'userDn' not set - anonymous context will be used for read-write operations 2009/11/16 10:07:57 [DEBUG] AbstractContextSource.setupAnonymousEnv - Not using LDAP pooling 2009/11/16 10:07:57 [DEBUG] AbstractContextSource.setupAnonymousEnv - Trying provider Urls: ldap://localhost:53389/dc=springframework,dc=org Context class loader [email protected] Context class loader [email protected] Input = [UsernamePasswordAuthenticationToken] User: [bob] Password: [PROTECTED] GrantedAuthorities: [] Authenticated: False Context class loader [email protected] 2009/11/16 10:07:57 [DEBUG] DefaultSpringSecurityContextSource.getReadWriteContext - Creating context with principal: 'uid=bob,ou=people,dc=springframework,dc=org' 2009/11/16 10:07:57 [DEBUG] AbstractContextSource.createContext - Got Ldap context on server 'ldap://localhost:53389/dc=springframework,dc=org' Context class loader [email protected] 2009/11/16 10:07:57 [DEBUG] DefaultLdapAuthoritiesPopulator.getGrantedAuthorities - Getting authorities for user uid=bob,ou=people,dc=springframework,dc=org 2009/11/16 10:07:57 [DEBUG] DefaultLdapAuthoritiesPopulator.getGroupMembershipRoles - Searching for roles for user 'bob', DN = 'uid=bob,ou=people,dc=springframework,dc=org', with filter (member= {0} ) in search base 'ou=groups' 2009/11/16 10:07:57 [DEBUG] SpringSecurityLdapTemplate.searchForSingleAttributeValues - Using filter: (member=uid=bob,ou=people,dc=springframework,dc=org) 2009/11/16 10:07:57 [ INFO] LdapTemplate.assureReturnObjFlagSet - The returnObjFlag of supplied SearchControls is not set but a ContextMapper is used - setting flag to true 2009/11/16 10:07:57 [DEBUG] AbstractContextSource.createContext - Got Ldap context on server 'ldap://localhost:53389/dc=springframework,dc=org' Traceback (most recent call last): File "test.py", line 20, in <module> auth1 = authProvider.authenticate(authentication) File "/home/gregturn/src/se-springpython-py/sandbox/gregturnquist/sespringpythonpy-121/src/springpython/security/providers/_Ldap_jython.py", line 106, in authenticate results.granted_auths = self.ldap_authorities_populator.get_granted_auths(user_details, authentication.username) File "/home/gregturn/src/se-springpython-py/sandbox/gregturnquist/sespringpythonpy-121/src/springpython/security/providers/_Ldap_jython.py", line 90, in get_granted_auths results = self._populator.getGrantedAuthorities(user_details, username) at org.springframework.security.ldap.SpringSecurityLdapTemplate$2.mapFromContext(SpringSecurityLdapTemplate.java:154) at org.springframework.ldap.core.ContextMapperCallbackHandler.getObjectFromNameClassPair(ContextMapperCallbackHandler.java:67) at org.springframework.ldap.core.CollectingNameClassPairCallbackHandler.handleNameClassPair(CollectingNameClassPairCallbackHandler.java:50) at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:297) at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:259) at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:606) at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:524) at org.springframework.security.ldap.SpringSecurityLdapTemplate.searchForSingleAttributeValues(SpringSecurityLdapTemplate.java:170) at org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator.getGroupMembershipRoles(DefaultLdapAuthoritiesPopulator.java:206) at org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator.getGrantedAuthorities(DefaultLdapAuthoritiesPopulator.java:179) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) java.lang.ClassCastException: java.lang.ClassCastException: com.sun.jndi.ldap.LdapCtx cannot be cast to org.springframework.ldap.core.DirContextAdapter =============================================== Found thread that talks about class loader issue involving this exact error at http://forum.springsource.org/showthread.php?p=203132 . Not sure how to proceed.
          Hide
          luke Luke Taylor added a comment -

          Hi Greg. I'm not sure exactly why this would be happening, but under normal use of Spring LDAP, it internally sets the javax.naming.spi.DirObjectFactory used by the Java LDAP context lookup to be a Spring LDAP DefaultDirObjectFactory. This is done by setting the property "java.naming.factory.object" in the JNDI environment to the factory classname (which takes place in Spring LDAP's AbstractContextSource class). This factory implementation creates Spring LDAP DirContextAdapter instances, which should then be returned from the JNDI lookup/search calls. This seems to be going awry somewhere, hence the cast problem.

          Show
          luke Luke Taylor added a comment - Hi Greg. I'm not sure exactly why this would be happening, but under normal use of Spring LDAP, it internally sets the javax.naming.spi.DirObjectFactory used by the Java LDAP context lookup to be a Spring LDAP DefaultDirObjectFactory. This is done by setting the property "java.naming.factory.object" in the JNDI environment to the factory classname (which takes place in Spring LDAP's AbstractContextSource class). This factory implementation creates Spring LDAP DirContextAdapter instances, which should then be returned from the JNDI lookup/search calls. This seems to be going awry somewhere, hence the cast problem.
          Hide
          gregturn Greg Turnquist added a comment -

          Found jython bug report involving class loaders: http://bugs.jython.org/issue1489

          When I plugged in java.lang.Thread.currentThread().setContextClassLoader(), and attempted to point it at the Spring Security classes, I started getting infinite recursions. This bug report is pretty up-to-date, and reported against 2.5.1. It speaks about tomcat, but web containers typically run multiple class loaders, and that is what they are reporting.

          Show
          gregturn Greg Turnquist added a comment - Found jython bug report involving class loaders: http://bugs.jython.org/issue1489 When I plugged in java.lang.Thread.currentThread().setContextClassLoader(), and attempted to point it at the Spring Security classes, I started getting infinite recursions. This bug report is pretty up-to-date, and reported against 2.5.1. It speaks about tomcat, but web containers typically run multiple class loaders, and that is what they are reporting.
          Hide
          gregturn Greg Turnquist added a comment - - edited

          Spring Python implementation of security, utilizing spring security/spring ldap jar files:
          ==========================================================================================
          """
          Copyright 2006-2008 SpringSource (http://springsource.com), All Rights Reserved

          Licensed under the Apache License, Version 2.0 (the "License");
          you may not use this file except in compliance with the License.
          You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

          Unless required by applicable law or agreed to in writing, software
          distributed under the License is distributed on an "AS IS" BASIS,
          WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
          See the License for the specific language governing permissions and
          limitations under the License.
          """
          import logging
          import re
          import sys
          from springpython.security import AuthenticationException
          from springpython.security import AuthenticationServiceException
          from springpython.security import BadCredentialsException
          from springpython.security import DisabledException
          from springpython.security import UsernameNotFoundException
          from springpython.security.providers import AuthenticationProvider
          from springpython.security.providers import UsernamePasswordAuthenticationToken
          from springpython.security.providers.dao import AbstractUserDetailsAuthenticationProvider
          from springpython.security.providers.encoding import LdapShaPasswordEncoder

          print "You are in Jython!"
          import java
          import org.springframework.security.ldap.DefaultSpringSecurityContextSource
          import org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator
          import org.springframework.security.providers.ldap.authenticator.BindAuthenticator
          import org.springframework.security.providers.ldap.authenticator.PasswordComparisonAuthenticator
          import org.springframework.security.providers.UsernamePasswordAuthenticationToken
          from jarray import array
          print "Using Spring Security to do our LDAP dirty work!"

          print "Current thread's class loader %s" % java.lang.Thread.currentThread().getContextClassLoader()

          class DefaultSpringSecurityContextSource(object):
          def _init_(self, url):
          self._context = org.springframework.security.ldap.DefaultSpringSecurityContextSource(url)
          java.lang.Thread.currentThread().setContextClassLoader(self._context.getClass().getClassLoader())
          self._context.afterPropertiesSet()

          class BindAuthenticator(object):
          def _init_(self, context_source=None, user_dn_patterns="uid=

          {0},ou=people"):
          self.context_source = context_source
          self.user_dn_patterns = user_dn_patterns
          self.logger = logging.getLogger("springpython.security.providers.Ldap.BindAuthenticator")
          self._authenticator = None

          def authenticate(self, authentication):
          if self._authenticator is None:
          self._authenticator = org.springframework.security.providers.ldap.authenticator.BindAuthenticator(self.context_source._context)
          self._authenticator.setUserDnPatterns(array([self.user_dn_patterns], java.lang.String))
          self._authenticator.afterPropertiesSet()
          #java.lang.Thread.currentThread().setContextClassLoader(self._authenticator.getClass().getClassLoader())
          #print "BindAuthenticator class loader %s" % self._authenticator.getClass().getClassLoader()
          token = org.springframework.security.providers.UsernamePasswordAuthenticationToken(authentication.username, authentication.password)
          return self._authenticator.authenticate(token)

          class PasswordComparisonAuthenticator(object):
          def _init_(self, context_source=None, user_dn_patterns="uid={0}

          ,ou=people", password_attr_name="userPassword"):
          self.context_source = context_source
          self.user_dn_patterns = user_dn_patterns
          self.password_attr_name = password_attr_name
          self.encoder = LdapShaPasswordEncoder()
          self.logger = logging.getLogger("springpython.security.providers.Ldap.PasswordComparisonAuthenticator")

          def authenticate(self, authentication):
          if jython:
          raise Exception("This code doesn't work inside Jython.")

          class DefaultLdapAuthoritiesPopulator(object):
          def _init_(self, context_source=None, group_search_base="ou=groups", group_search_filter="(member=

          {0}

          )", group_role_attr="cn", role_prefix="ROLE_", conv
          ert_to_upper=True):
          self.logger = logging.getLogger("springpython.security.providers.Ldap.DefaultLdapAuthoritiesPopulator")
          self.context_source = context_source
          self.group_search_base = group_search_base
          self.group_search_filter = group_search_filter
          self.group_role_attr = group_role_attr
          self.role_prefix = role_prefix
          self.convert_to_upper = convert_to_upper
          self._populator = org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator(self.context_source._context, self.group_search_base)
          #java.lang.Thread.currentThread().setContextClassLoader(self._populator.getClass().getClassLoader())
          self._populator.setGroupSearchFilter(self.group_search_filter)
          self._populator.setGroupRoleAttribute(self.group_role_attr)
          self._populator.setRolePrefix(self.role_prefix)
          self._populator.setConvertToUpperCase(self.convert_to_upper)
          print "LdapAuthoritiesPopulator class loader %s" % self._populator.getClass().getClassLoader()

          def get_granted_auths(self, user_details, username):
          results = self._populator.getGrantedAuthorities(user_details, username)
          print results
          return results

          class LdapAuthenticationProvider(AuthenticationProvider):
          def _init_(self, ldap_authenticator=None, ldap_authorities_populator=None):
          AuthenticationProvider._init_(self)
          self.ldap_authenticator = ldap_authenticator
          self.ldap_authorities_populator = ldap_authorities_populator
          self.logger = logging.getLogger("springpython.security.providers.Ldap.LdapAuthenticationProvider")

          def authenticate(self, authentication):
          user_details = self.ldap_authenticator.authenticate(authentication)
          print "Context class loader %s" % user_details.getClass().getClassLoader()
          from copy import deepcopy
          results = deepcopy(authentication)
          results.granted_auths = self.ldap_authorities_populator.get_granted_auths(user_details, authentication.username)
          results.setAuthenticated(True)
          l.unbind()
          return results

          Show
          gregturn Greg Turnquist added a comment - - edited Spring Python implementation of security, utilizing spring security/spring ldap jar files: ========================================================================================== """ Copyright 2006-2008 SpringSource ( http://springsource.com ), All Rights Reserved Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ import logging import re import sys from springpython.security import AuthenticationException from springpython.security import AuthenticationServiceException from springpython.security import BadCredentialsException from springpython.security import DisabledException from springpython.security import UsernameNotFoundException from springpython.security.providers import AuthenticationProvider from springpython.security.providers import UsernamePasswordAuthenticationToken from springpython.security.providers.dao import AbstractUserDetailsAuthenticationProvider from springpython.security.providers.encoding import LdapShaPasswordEncoder print "You are in Jython!" import java import org.springframework.security.ldap.DefaultSpringSecurityContextSource import org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator import org.springframework.security.providers.ldap.authenticator.BindAuthenticator import org.springframework.security.providers.ldap.authenticator.PasswordComparisonAuthenticator import org.springframework.security.providers.UsernamePasswordAuthenticationToken from jarray import array print "Using Spring Security to do our LDAP dirty work!" print "Current thread's class loader %s" % java.lang.Thread.currentThread().getContextClassLoader() class DefaultSpringSecurityContextSource(object): def _ init _(self, url): self._context = org.springframework.security.ldap.DefaultSpringSecurityContextSource(url) java.lang.Thread.currentThread().setContextClassLoader(self._context.getClass().getClassLoader()) self._context.afterPropertiesSet() class BindAuthenticator(object): def _ init _(self, context_source=None, user_dn_patterns="uid= {0},ou=people"): self.context_source = context_source self.user_dn_patterns = user_dn_patterns self.logger = logging.getLogger("springpython.security.providers.Ldap.BindAuthenticator") self._authenticator = None def authenticate(self, authentication): if self._authenticator is None: self._authenticator = org.springframework.security.providers.ldap.authenticator.BindAuthenticator(self.context_source._context) self._authenticator.setUserDnPatterns(array( [self.user_dn_patterns] , java.lang.String)) self._authenticator.afterPropertiesSet() #java.lang.Thread.currentThread().setContextClassLoader(self._authenticator.getClass().getClassLoader()) #print "BindAuthenticator class loader %s" % self._authenticator.getClass().getClassLoader() token = org.springframework.security.providers.UsernamePasswordAuthenticationToken(authentication.username, authentication.password) return self._authenticator.authenticate(token) class PasswordComparisonAuthenticator(object): def _ init _(self, context_source=None, user_dn_patterns="uid={0} ,ou=people", password_attr_name="userPassword"): self.context_source = context_source self.user_dn_patterns = user_dn_patterns self.password_attr_name = password_attr_name self.encoder = LdapShaPasswordEncoder() self.logger = logging.getLogger("springpython.security.providers.Ldap.PasswordComparisonAuthenticator") def authenticate(self, authentication): if jython: raise Exception("This code doesn't work inside Jython.") class DefaultLdapAuthoritiesPopulator(object): def _ init _(self, context_source=None, group_search_base="ou=groups", group_search_filter="(member= {0} )", group_role_attr="cn", role_prefix="ROLE_", conv ert_to_upper=True): self.logger = logging.getLogger("springpython.security.providers.Ldap.DefaultLdapAuthoritiesPopulator") self.context_source = context_source self.group_search_base = group_search_base self.group_search_filter = group_search_filter self.group_role_attr = group_role_attr self.role_prefix = role_prefix self.convert_to_upper = convert_to_upper self._populator = org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator(self.context_source._context, self.group_search_base) #java.lang.Thread.currentThread().setContextClassLoader(self._populator.getClass().getClassLoader()) self._populator.setGroupSearchFilter(self.group_search_filter) self._populator.setGroupRoleAttribute(self.group_role_attr) self._populator.setRolePrefix(self.role_prefix) self._populator.setConvertToUpperCase(self.convert_to_upper) print "LdapAuthoritiesPopulator class loader %s" % self._populator.getClass().getClassLoader() def get_granted_auths(self, user_details, username): results = self._populator.getGrantedAuthorities(user_details, username) print results return results class LdapAuthenticationProvider(AuthenticationProvider): def _ init _(self, ldap_authenticator=None, ldap_authorities_populator=None): AuthenticationProvider._ init _(self) self.ldap_authenticator = ldap_authenticator self.ldap_authorities_populator = ldap_authorities_populator self.logger = logging.getLogger("springpython.security.providers.Ldap.LdapAuthenticationProvider") def authenticate(self, authentication): user_details = self.ldap_authenticator.authenticate(authentication) print "Context class loader %s" % user_details.getClass().getClassLoader() from copy import deepcopy results = deepcopy(authentication) results.granted_auths = self.ldap_authorities_populator.get_granted_auths(user_details, authentication.username) results.setAuthenticated(True) l.unbind() return results
          Hide
          gregturn Greg Turnquist added a comment -

          Script that is exercising the logic (run as jython test.py):
          ================================================================
          from springpython.security.providers import UsernamePasswordAuthenticationToken
          from springpython.security.providers.Ldap import DefaultSpringSecurityContextSource
          from springpython.security.providers.Ldap import BindAuthenticator
          from springpython.security.providers.Ldap import PasswordComparisonAuthenticator
          from springpython.security.providers.Ldap import DefaultLdapAuthoritiesPopulator
          from springpython.security.providers.Ldap import LdapAuthenticationProvider

          context = DefaultSpringSecurityContextSource(url="ldap://localhost:53389/dc=springframework,dc=org")
          bindAuthenticator = BindAuthenticator(context_source=context, user_dn_patterns="uid=

          {0},ou=people")
          populator = DefaultLdapAuthoritiesPopulator(context_source=context, group_search_base="ou=groups")
          authProvider = LdapAuthenticationProvider(ldap_authenticator=bindAuthenticator, ldap_authorities_populator=populator)

          passwordAuthenticator = PasswordComparisonAuthenticator(context_source=context, user_dn_patterns="uid={0}

          ,ou=people")
          authProvider2 = LdapAuthenticationProvider(ldap_authenticator=passwordAuthenticator, ldap_authorities_populator=populator)

          authentication = UsernamePasswordAuthenticationToken(username="bob", password="bobspassword")

          print "Input = %s" % authentication

          auth1 = authProvider.authenticate(authentication)

          print "Bind output = %s" % auth1

          print "Input = %s" % authentication

          auth2 = authProvider2.authenticate(authentication)

          print "PasswordComparison output = %s" % auth2

          Show
          gregturn Greg Turnquist added a comment - Script that is exercising the logic (run as jython test.py): ================================================================ from springpython.security.providers import UsernamePasswordAuthenticationToken from springpython.security.providers.Ldap import DefaultSpringSecurityContextSource from springpython.security.providers.Ldap import BindAuthenticator from springpython.security.providers.Ldap import PasswordComparisonAuthenticator from springpython.security.providers.Ldap import DefaultLdapAuthoritiesPopulator from springpython.security.providers.Ldap import LdapAuthenticationProvider context = DefaultSpringSecurityContextSource(url="ldap://localhost:53389/dc=springframework,dc=org") bindAuthenticator = BindAuthenticator(context_source=context, user_dn_patterns="uid= {0},ou=people") populator = DefaultLdapAuthoritiesPopulator(context_source=context, group_search_base="ou=groups") authProvider = LdapAuthenticationProvider(ldap_authenticator=bindAuthenticator, ldap_authorities_populator=populator) passwordAuthenticator = PasswordComparisonAuthenticator(context_source=context, user_dn_patterns="uid={0} ,ou=people") authProvider2 = LdapAuthenticationProvider(ldap_authenticator=passwordAuthenticator, ldap_authorities_populator=populator) authentication = UsernamePasswordAuthenticationToken(username="bob", password="bobspassword") print "Input = %s" % authentication auth1 = authProvider.authenticate(authentication) print "Bind output = %s" % auth1 print "Input = %s" % authentication auth2 = authProvider2.authenticate(authentication) print "PasswordComparison output = %s" % auth2
          Hide
          gregturn Greg Turnquist added a comment -

          Result of script:
          ============================
          [email protected]:[email protected]21$ jython test.py
          You are in Jython!
          Using Spring Security to do our LDAP dirty work!
          Current thread's class loader [email protected]
          Nov 17, 2009 7:07:33 PM org.springframework.security.ldap.DefaultSpringSecurityContextSource <init>
          INFO: URL 'ldap://localhost:53389/dc=springframework,dc=org', root DN is 'dc=springframework,dc=org'
          Nov 17, 2009 7:07:33 PM org.springframework.ldap.core.support.AbstractContextSource afterPropertiesSet
          INFO: Property 'userDn' not set - anonymous context will be used for read-write operations
          Traceback (most recent call last):
          File "test.py", line 10, in <module>
          populator = DefaultLdapAuthoritiesPopulator(context_source=context, group_search_base="ou=groups")
          File "/home/gregturn/src/se-springpython-py/sandbox/gregturnquist/sespringpythonpy-121/src/springpython/security/providers/Ldap_jython.py", line 85, in __init_
          self._populator = org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator(self.context_source._context, self.group_search_base)
          RuntimeError: maximum recursion depth exceeded

          Show
          gregturn Greg Turnquist added a comment - Result of script: ============================ [email protected]:[email protected]21$ jython test.py You are in Jython! Using Spring Security to do our LDAP dirty work! Current thread's class loader [email protected] Nov 17, 2009 7:07:33 PM org.springframework.security.ldap.DefaultSpringSecurityContextSource <init> INFO: URL 'ldap://localhost:53389/dc=springframework,dc=org', root DN is 'dc=springframework,dc=org' Nov 17, 2009 7:07:33 PM org.springframework.ldap.core.support.AbstractContextSource afterPropertiesSet INFO: Property 'userDn' not set - anonymous context will be used for read-write operations Traceback (most recent call last): File "test.py", line 10, in <module> populator = DefaultLdapAuthoritiesPopulator(context_source=context, group_search_base="ou=groups") File "/home/gregturn/src/se-springpython-py/sandbox/gregturnquist/sespringpythonpy-121/src/springpython/security/providers/ Ldap_jython.py", line 85, in __init _ self._populator = org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator(self.context_source._context, self.group_search_base) RuntimeError: maximum recursion depth exceeded
          Hide
          gregturn Greg Turnquist added a comment -

          Completed all mods to get CPython working with LDAP.

          Show
          gregturn Greg Turnquist added a comment - Completed all mods to get CPython working with LDAP.

            People

            • Assignee:
              gregturn Greg Turnquist
              Reporter:
              gregturn Greg Turnquist
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: