Внедрение LdapTemplate для возврата сведений о пользователе внутри службы Grails вызывает исключение нулевого указателя - PullRequest
1 голос
/ 04 февраля 2012

Я некоторое время боролся с Spring Security LDAP, и как раз когда я, наконец, подумал, что его превзошли в отправке, он снова подвел меня.

Сценарий: у меня есть пользователиВойдите в систему, используя учетные данные своей организации, которые я затем проверяю по внутренней базе данных пользователей.Если они не существуют, я создаю их локально, а затем устанавливаю их локальные полномочия (я не могу дотронуться до сервера LDAP, только аутентифицируюсь на нем - поэтому я не могу добавить туда полномочия).Это работает нормально ... но затем я хочу добавить пару полей из LDAP - их полное имя и адрес электронной почты, и именно здесь все идет не так.

У меня есть поиск LDAP, работающий в контроллере - используяследующий код (я вставил ldapTemplate далее):

def fullName = ldapTemplate.search("", "(uid=" + uid + "*)", new AttributesMapper() {
        @Override
        public Object mapFromAttributes(Attributes attrs) throws NamingException {
            return attrs.get("cn").get()
        }
    })

, и это прекрасно работает.Но когда я тиражирую этот код в сервисе, который называется пост-аутентификацией, ldapTemplate всегда становится пустым ... Я пробовал несколько разных вещей, но не могу заставить его правильно заполниться ... может кто-нибудь пролить светпочему?Я надеюсь, что это что-то глупое, что я делаю с 4:21 утра, и я должен был быть в постели около 6 часов назад ...

РЕДАКТИРОВАТЬ: Вот код обслуживания, как было запрошено, спасибо за принятиеПосмотрите, Берт, - в настоящее время он не очень надежен, так как у меня еще не получалось, просто создав нового локального пользователя - еще есть над чем поработать.

package com.myPackage

import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
import org.springframework.ldap.core.AttributesMapper
import org.springframework.security.core.Authentication
import org.springframework.security.core.authority.GrantedAuthorityImpl
import org.springframework.security.web.authentication.AuthenticationSuccessHandler
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler

import org.apache.commons.lang.RandomStringUtils

class PostAuthHandlerService implements AuthenticationSuccessHandler {

def springSecurityService
def ldapTemplate

private AuthenticationSuccessHandler target = new SavedRequestAwareAuthenticationSuccessHandler();
private List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)]

public void onAuthenticationSuccess(HttpServletRequest request,
        HttpServletResponse response, Authentication auth) {
    def username = auth.principal.getAt("username")
    User.withTransaction { status ->
        // Check to see if this user exists in the local db
        def user = User.findByUsername(username)
        if (!user) { // User doesn't exist yet, so create and make a user...
            def userRole = Role.findByAuthority('ROLE_USER') ?:
                    new Role(authority: 'ROLE_AM').save(failOnError: true)
            user = new User(
                    username: username,
                    password: auth.getCredentials() ?: placeholderPassword(),
                    displayName: getLdapDetails("username", "cn") ?: "",
                    email: getLdapDetails("username", "mail") ?: "",
                    enabled: true).save(failOnError: true)
            UserRole.create user, userRole
        }
        else {
            println("--- You exist already! Updating details")
            user.displayName = getLdapDetails("username", "cn") ?: ""
        }
        target.onAuthenticationSuccess(request, response, auth)
    }
}

def getLdapDetails(username, attr) {
    return ldapTemplate.search("", "(uid=$username*)", new AttributesMapper() {
        @Override
        public Object mapFromAttributes(Attributes attrs) throws NamingException {
            return attrs.get(attr).get()
        }
    })
}

def placeholderPassword () {
    // This is here because we also allow local logins for some users.  
    // If the password is not available, then create a big ugly one...
    return org.apache.commons.lang.RandomStringUtils.randomAlphanumeric(128)
}

public void proceed(HttpServletRequest request,
HttpServletResponse response, Authentication auth) {
    target.onAuthenticationSuccess(request, response, auth)
}

}

2ndРедактировать: я пробовал разные вещи - в том числе пытался использовать springSecurityService.reauthenticate, чтобы использовать локального пользователя во время сеанса, а не LDAP - и этот бин также нулевой ... кажется, что я могуне добавляю никаких бобов в мой сервис вообще.

В конце концов я нашел этот пост: http://burtbeckwith.com/blog/?p=993, который дал мне обходной путь, и теперь у меня все работает ... но я все еще хотел быЯ знаю, почему он этого не сделал ... Мне так много нужно узнать в Граальсе, и трудно понять, с чего начать.

Заранее спасибо

Стив

1 Ответ

2 голосов
/ 05 февраля 2012

Как вы вводите аутентификациюSuccessHandler? Вы должны попытаться определить authenticationSuccessHandler в resources.xml

Grails 1.3.5 и пружинное защитное ядро ​​

...