Передача пароля для методов для Spring MVC Controller - AOP или Spring Security? - PullRequest
1 голос
/ 08 февраля 2011

Я недавно использовал Spring MVC с аннотированными контроллерами для страниц JSP.У меня есть класс, похожий на этот:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
public class AdminController {

   @RequestMapping(value = "/doStuff1.htm", method = RequestMethod.POST)
   public void doStuff1(@RequestParam("password")String password) {

        // do some stuff

   }

   @RequestMapping(value = "/doStuff2.htm", method = RequestMethod.POST)    
   public void doStuff2(
       @RequestParam("password")String password,
       @RequestParam("foo")String foo{

        // do some stuff

   }    
}   

Как вы можете видеть, каждый вызов будет иметь переданный параметр пароля. Пароль читается из диалога и передается в каждый отправленный вызов.

Я бы хотел избавиться от параметра пароля из вызовов методов, чтобы получить «более чистый» код.

Я быстро взглянул на безопасность Spring для этой цели, но она выглядела немного тяжелой.Может быть, АОП можно использовать?

Есть ли очевидное решение, которое я упускаю?

Большое спасибо, - Скотт

Ответы [ 2 ]

6 голосов
/ 08 февраля 2011

Как видите, для каждого звонка будет передаваться параметр пароля. Пароль читается из диалога и передается в каждый отправленный звонок.

а) Это ужасная практика. Это означает, что любой, у кого есть сетевой сниффер, сможет увидеть ваш пароль повсюду. Возможно, было бы хорошо ввести пароль один раз (хотя было бы лучше использовать безопасный способ передачи пароля), но тогда сеанс должен содержать токен аутентификации

б) Только пароль? Никогда не используйте пароль без имени пользователя! При атаке грубой силой любой автономный пароль в конечном итоге будет взломан, но комбинации имени пользователя и пароля гораздо сложнее взломать.

в) Методы вашего контроллера не должны знать или заботиться о паролях. Это не их забота. У них есть работа, работа с паролями / безопасность - это междисциплинарная проблема, и ее не следует реализовывать на уровне контроллера. Что приводит нас к вопросу:

Что использовать: AOP или Spring Security?

AOP - очень мощный способ реализации сквозных функций, но у него есть некоторые недостатки:

  • если вы используете Spring AOP , советующие контроллеры будут работать, только если вы используете прокси с поддержкой интерфейса (и определение интерфейсов для кода, который никогда не вызывается через Java, немного неудобно) или используете подклассы на основе CGLib до proxy-target-class="true" (в конфигурации XML). Последний имеет забавные побочные эффекты, такие как двойное исполнение конструкторов. Многие используют это, но я бы посоветовал против этого. Это означает, что Spring AOP не является хорошим выбором.
  • если вы используете статическую AspectJ компиляцию, тем не менее, вы вносите свои соображения безопасности в код приложения. Параметры безопасности должны быть настраиваемыми без перекомпиляции классов, поэтому я бы сказал, что у нас также нет запрета.

Итак, мое предложение:

Использовать Spring Security

Spring Security - это специальное решение для выполнения именно того, что вам нужно: защита сайтов на основе Spring (с использованием Spring MVC или другой веб-платформы). Хотя Spring Security может быть огромным монстром, в большинстве случаев необходимая конфигурация минимальна:

<http auto-config='true'>
    <!-- restrict all URLs to role ROLE_USER -->
    <intercept-url pattern="/**" access="ROLE_USER" />
</http>
<authentication-manager>
    <authentication-provider>
      <user-service>
        <!-- define two users, jimi and bob -->
        <user name="jimi" password="jimispassword"
              authorities="ROLE_USER, ROLE_ADMIN" />
        <user name="bob" password="bobspassword"
              authorities="ROLE_USER" />
      </user-service>
    </authentication-provider>
</authentication-manager>

(взято из раздела A Минимальное <http> Конфигурация )

0 голосов
/ 09 февраля 2011

Как упоминалось в предыдущем посте, лучше отправлять данные для входа в систему только один раз за сеанс и сохранять токен аутентификации внутри сеанса пользователя.

Для проверки токена вы можете реализовать интерфейс HandlerInterceptor из Springframework.

Например

public class MyHandlerInterceptor extends HandlerInterceptorAdapter {

public boolean preHandle(HttpServletRequest request,
        HttpServletResponse response, Object handler) throws Exception {

    //check authentication
}

}

и конфигурации:

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
    <list>
        <bean id="myInterceptor" class="...MyInterceptor"/>
    </list>
</property>

...