grails spring-security grails-plugin spring-ldap spring-security-ldap

¿Cómo integrar un usuario LDAP con la tabla PERSON creada por Spring Security en Grails?



spring-security grails-plugin (1)

Por lo tanto, necesita esencialmente asignar el usuario AD a una Persona.

Estas son las 3 clases que necesita en src / groovy. Obviamente, modifíquelos según sea necesario:

package yourpackagename import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUser import org.springframework.security.core.GrantedAuthority class CustomUserDetails extends GrailsUser{ final String firstName final String lastName CustomUserDetails(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<GrantedAuthority> authorities, long id, String firstName, String lastName) { super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities, id) this.firstName = firstName this.lastName = lastName } } package yourpackagenamehere import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUserDetailsService import org.springframework.security.core.authority.GrantedAuthorityImpl import org.springframework.security.core.userdetails.UserDetails import org.springframework.security.core.userdetails.UsernameNotFoundException import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils class CustomUserDetailsService implements GrailsUserDetailsService { /** * Some Spring Security classes (e.g. RoleHierarchyVoter) expect at least one role, so * we give a user with no granted roles this one which gets past that restriction but * doesn''t grant anything. */ static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)] UserDetails loadUserByUsername(String username, boolean loadRoles) throws UsernameNotFoundException { return loadUserByUsername(username) } UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User.withTransaction { status -> User user = User.findByUsername(username) if (!user) throw new UsernameNotFoundException(''User not found'', username) def authorities = user.authorities.collect {new GrantedAuthorityImpl(it.authority)} return new CustomUserDetails(user.username, user.password, user.enabled, !user.accountExpired, !user.passwordExpired, !user.accountLocked, authorities ?: NO_ROLES, user.id, user.firstName, user.lastName) } as UserDetails } } package yourpackagenamehere import groovy.sql.Sql import org.springframework.ldap.core.DirContextAdapter import org.springframework.ldap.core.DirContextOperations import org.springframework.security.core.userdetails.UserDetails import org.springframework.security.ldap.userdetails.UserDetailsContextMapper import org.springframework.security.core.authority.GrantedAuthorityImpl import org.springframework.security.core.GrantedAuthority import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils import org.springframework.security.core.userdetails.UsernameNotFoundException import org.springframework.security.authentication.DisabledException class CustomUserDetailsContextMapper implements UserDetailsContextMapper { private static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)] def dataSource @Override public CustomUserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<GrantedAuthority> authority) { username = username.toLowerCase() User user = User.findByUsername(username) String firstName = ctx.originalAttrs.attrs[''givenname''].values[0] String lastName = ctx.originalAttrs.attrs[''sn''].values[0] def roles User.withTransaction { if(!user){ user = new User(username: username, enabled: true, firstName: firstName, lastName: lastName) user.save(flush: true) } else { user = User.findByUsername(username) user.firstName = firstName user.lastName = lastName user.save(flush: true) } roles = user.getAuthorities() } if ( !user.enabled ) throw new DisabledException("User is disabled", username) def authorities = roles.collect { new GrantedAuthorityImpl(it.authority) } authorities.addAll(authority) def userDetails = new CustomUserDetails(username, user.password, user.enabled, false, false, false, authorities, user.id, user.firstName, user.lastName) return userDetails } @Override public void mapUserToContext(UserDetails arg0, DirContextAdapter arg1) { } }

En configuración en spring / resources.groovy:

import yourpackagenamehere.CustomUserDetailsService import yourpackagenamehere.CustomUserDetailsContextMapper beans = { userDetailsService(CustomUserDetailsService) ldapUserDetailsMapper(CustomUserDetailsContextMapper) { dataSource = ref("dataSource") } }

En Config.groovy, aquí están mis configuraciones:

grails.plugins.springsecurity.ldap.context.managerDn = ''CN=username,OU=People,DC=foo,DC=com'' grails.plugins.springsecurity.ldap.context.managerPassword = ''password'' grails.plugins.springsecurity.ldap.context.server = ''ldap://foo.com:389/'' grails.plugins.springsecurity.ldap.authorities.ignorePartialResultException = true grails.plugins.springsecurity.ldap.search.base = ''ou=People,dc=foo,dc=com'' grails.plugins.springsecurity.ldap.search.filter="sAMAccountName={0}" grails.plugins.springsecurity.ldap.search.searchSubtree = true grails.plugins.springsecurity.ldap.auth.hideUserNotFoundExceptions = false grails.plugins.springsecurity.ldap.search.attributesToReturn = null grails.plugins.springsecurity.providerNames = [''ldapAuthProvider'', ''anonymousAuthenticationProvider''] grails.plugins.springsecurity.ldap.mapper.userDetailsClass = ''CustomUserDetails'' grails.plugins.springsecurity.ldap.authorities.retrieveGroupRoles = true grails.plugins.springsecurity.ldap.authorities.retrieveDatabaseRoles = true grails.plugins.springsecurity.ldap.authorities.groupSearchBase =''dc=foo,dc=com'' grails.plugins.springsecurity.ldap.authorities.groupSearchFilter = ''member={0}''

Estamos creando una aplicación de Grails donde queremos que el usuario inicie sesión usando sus credenciales de Active Directory. Además, queremos otorgarle al propietario del negocio de esta aplicación la capacidad de controlar quién tiene acceso a ciertos enlaces (acciones). Debido a esto, estamos utilizando los siguientes complementos en nuestra aplicación de griales:

  1. Spring Security Core
  2. Seguridad de primavera LDAP
  3. UI de seguridad de primavera

Debido a que queremos capacitar al usuario comercial para crear roles personalizados con ciertos permisos (acciones) sobre la marcha cuando sea necesario, creemos que la mejor configuración de Spring Security es el enfoque basado en la base de datos Requestmap.

Hasta ahora hemos logrado lo siguiente:

  • Estamos pudiendo autenticar con éxito contra Active Directory.
  • También hemos sido capaces de crear diferentes asignaciones de solicitudes para diferentes roles (ROLE_XXX) a través de la interfaz UI del plugin spring-security-ui

Problemas / Preguntas

El complemento spring-security-core creó las siguientes tablas:

  • PERSONA
  • AUTORIDAD
  • PERSON_AUTHORITY
  • REQUESTMAP

Estas son las tablas que admiten la creación de Roles, la asignación de URL a los roles. Sin embargo, la tabla Person_Authoritity como el nombre de la convención implica que es una relación de muchos a muchos entre una PERSONA y una AUTORIDAD (ROL) ya que una persona puede tener más de una función. Mi problema es que no tengo una Persona porque la persona ya existe en Active Directory (una fuente externa) y no fue creada en la aplicación.

¿Hay alguna manera de hacer que el usuario autenticado sea la PERSONA? La solución de seguridad de primavera requiere que la persona en fila u objeto, sin embargo, prefiera referirse a ella.

También he publicado la pregunta aquí:

http://grails.1312388.n4.nabble.com/Issues-integrating-LDAP-Authentication-with-Requestmap-to-Secure-URLs-td4644040.html

Gracias,