2015-09-17 2 views
0

У меня есть приложение, в котором логин должен содержать номер организации, поэтому логин должен быть имя пользователя + пароль + номер организации.Настроить логин в плагине Grails Spring Security

Образец случая: Если имя пользователя + пароль совпадает с существующим пользователем, мне нужно проверить, имеет ли этот пользователь идентификатор организации. Если нет, логин должен завершиться ошибкой.

Я видел, что форма входа в систему с плагином безопасности плагина отправляется в /app/j_spring_security_check, но не может найти, где это фактически реализовано.

Также я не уверен, что прикосновение к этому является правильным способом реализации этого пользовательского входа.

Мой вопрос в том, где/как настроить действие входа? (чтобы он потерпел неудачу в случае, описанном выше).

ответ

1

Мы можем сделать это, переопределив фильтр UserNamePasswordAuthenticationFilter и предоставив нашу пользовательскую попытку аутентификации. Итак, перейдите в файл DefaultSecurityConfig.groovy (внутри плагинов). Смотрите диаграмму дерева ниже:

target 
     |-work 
      |-plugins 
        |-spring-security-core-2.0-RC5 
              |-conf 
               |-DefaultSecurityConfig.groovy 

В DefaultSecurityConfig.groovy под APF закрытия мы указываем filterProcessUrl, который мы можем переопределить в Config.groovy Grails приложения, как мы делаем для других свойств (например rejectIfNoRule)

grails.plugin.springsecurity.apf.filterProcessesUrl="your url" 

сейчас мы поняли, как он проверяет подлинность. Давайте настроим его собственный способ, переопределив метод tryAuthentication фильтра с именем UsernamePasswordAuthenticationFilter. Например, см ниже (также, пройти через встроенные комментарии, добавленные там)

package org.springframework.security.web.authentication; 

    import javax.servlet.http.HttpServletRequest; 
    import javax.servlet.http.HttpServletResponse; 
    import org.springframework.security.authentication.AuthenticationServiceException; 
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 
    import org.springframework.security.core.Authentication; 
    import org.springframework.security.core.AuthenticationException; 
    import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; 
    import org.springframework.util.Assert; 

    public class CustomUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter { 
     public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username"; 
     public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password"; 
     /** @deprecated */ 
     @Deprecated 
     public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME"; 
     private String usernameParameter = "j_username"; 
     private String passwordParameter = "j_password"; 
     private String organisationParameter = 'j_organisation' 
     private boolean postOnly = true; 

     public UsernamePasswordAuthenticationFilter() { 
      super("/j_spring_security_check"); 
     } 

     public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { 
      if(this.postOnly && !request.getMethod().equals("POST")) { 
       throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); 
      } else { 
       String username = this.obtainUsername(request); 
       String password = this.obtainPassword(request); 
       String password = this.obtainOrganisation(request); 

       //regular implementation in spring security plugin /** 
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); 
       this.setDetails(request, authRequest); 
       return   this.getAuthenticationManager().authenticate(authRequest); 
      } 
**/ 

//Your custom implementation goes here(Authenticate on the basis of organisation as well). Here you need to customise authenticate as per your requirement so that it checks for organisation as well. 
     } 

     protected String obtainOrganisation(HttpServletRequest request) { 
     return request.getParameter(this.organisationParameter); 
    }  

     protected String obtainPassword(HttpServletRequest request) { 
      return request.getParameter(this.passwordParameter); 
     } 

     protected String obtainUsername(HttpServletRequest request) { 
      return request.getParameter(this.usernameParameter); 
     } 

     protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) { 
      authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request)); 
     } 

     public void setUsernameParameter(String usernameParameter) { 
      Assert.hasText(usernameParameter, "Username parameter must not be empty or null"); 
      this.usernameParameter = usernameParameter; 
     } 

     public void setPasswordParameter(String passwordParameter) { 
      Assert.hasText(passwordParameter, "Password parameter must not be empty or null"); 
      this.passwordParameter = passwordParameter; 
     } 

     public void setPostOnly(boolean postOnly) { 
      this.postOnly = postOnly; 
     } 

     public final String getUsernameParameter() { 
      return this.usernameParameter; 
     } 

     public final String getPasswordParameter() { 
      return this.passwordParameter; 
     } 
    } 

Следовательно, это больше первостепенной задачу в плане пружинной безопасности.

Чтобы получить более четкое представление о том же прочитать this nice link для Java и для Grails чтения this

Надеется, что это помогает.

Эти блоги дают более подробное представление о тех же требованиях.

+0

Hi Vinay спасибо за объяснение. Я тестирую ваше решение. Один вопрос, где я могу настроить новый CustomUsernamePasswordAuthenticationFilter для фактического фильтрации запросов? –

+0

Хотя вы можете создать каталог conf или src/groovy и зарегистрировать его в Config.groovy. Не уверенный в том, какие проблемы мы можем столкнуться. Я создаю проект POC для того же самого и дам вам знать, хорошо ли он работает, и поделиться ссылкой публичного репо git/bitbucket. –

+0

Изучая код пружины, кажется, что «весенний» способ сделать это немного сложнее: 1. создать реализацию AbstractAuthenticationToken, чтобы вернуть объект авторизации из фильтра, 2. создать реализацию AuthenticationProvider для фактической проверки подлинности, как этот: https://github.com/spring-projects/spring-security/blob/master/core/src/main/java/org/springframework/security/authentication/dao/AbstractUserDetailsAuthenticationProvider.java, 3. Мне нужно для регистрации этого провайдера в ProviderManager (не уверен, как я это делаю сейчас). Я буду продолжать пытаться. –