2013-08-14 3 views
0

У меня есть приложение spring-mvc, которое в настоящее время имеет два канала - веб-приложение и службу REST. У обоих есть http-сессия пользователя, и я могу легко получить «текущего пользователя» в моих классах обслуживания.Удержание «текущего пользователя» в threadlocal

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

Теперь я либо необходимо: 1. изменить свои методы обслуживания слоя, чтобы принять текущий пользователь в качестве параметра или 2. просто изменить класс, который получает текущий пользователь из сеанса HTTP.

У меня также есть требование создать журнал аудита, и я собираюсь использовать Spring AOP для этого. Аспекту также потребуется доступ к «текущему пользователю». Поэтому вариант №1, вероятно, не сработает для меня, и я пойду с №2.

Для опции №2 я создам перехватчик, который поместит текущего пользователя в переменную ThreadLocal. Контроллер для новой службы REST сделает то же самое, а затем на моем уровне обслуживания и в аспекте журнала аудита я могу получить текущего пользователя оттуда.

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

Буду признателен за любые комментарии и идеи.

Оз

Вот как я в настоящее время получить текущего пользователя:

@Override 
public User getCurrentUser() 
{ 
    Authentication currentUser = getAuthentication(); 

    return userService.getByLoginName(currentUser.getName()); 
} 


protected Authentication getAuthentication() 
{ 
    return SecurityContextHolder.getContext().getAuthentication(); 
} 
+0

Некоторый код может помочь. Я понимаю, что вы получаете доступ к сеансу http со своего уровня обслуживания, это правильно? – Pastur

+0

Да, я обновил свое сообщение с образцом. – user1703531

+0

http://stackoverflow.com/questions/14823761/spring-mvc-getting-principal-from-security-context-in-service-layer – Pastur

ответ

2

Я думаю, простой способ сделать то, что вам нужно, это настроить сервлет фильтр для нового REST веб-сервиса для заполнения SecurityContextHolder с Authentication объект построить по запросу параметры.

Вы можете прочитать это: http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#d0e2171 для получения более подробной информации.

С помощью этого решения вам не нужно изменять код для извлечения текущего пользователя. (обратите внимание, что SecurityContextHolder уже использует ThreadLocal для хранения SecurityContext, и поэтому Authentication)

+0

Спасибо! Это самый простой способ сделать это. Вместо использования фильтра я могу установить объект аутентификации непосредственно в контроллере REST, потому что запрос является XML-форматом и потребует дополнительной трансформации. – user1703531

Смежные вопросы