Минимальная конфигурация SpringSecurity, необходимая для извлечения пользователя - PullRequest
1 голос
/ 25 марта 2011

У меня есть приложение Spring MVC, которое в данный момент не использует SpringSecurity.Я написал AuditInterceptor для журналов аудита Hibernate, в котором нужен способ получить пользователя, вошедшего в систему.Из того, что я могу найти в Интернете, лучший способ сделать это через SecurityContextHolder SpringSecurity.Однако в настоящий момент мне не нужны никакие другие функции SpringSecurity, и я не хочу переписывать, как приложение выполняет аутентификацию или авторизацию в настоящее время.

По сути, то, что я ищуэто минимальный объем конфигурации, необходимый для того, чтобы сохранить вошедшего в систему пользователя в SecurityContextHolder и снова вернуть его обратно в мой AuditInterceptor.


Моей первой попыткой было добавить следующую строку на страницу входа в систему, которая существует в настоящее время:

Authentication auth = new UsernamePasswordAuthenticationToken(u.getName(), u.getPassword());
SecurityContextHolder.getContext().setAuthentication(auth);

И добавить следующее к перехватчику:

SecurityContext secureContext = SecurityContextHolder.getContext();
Authentication auth = secureContext.getAuthentication();
Object principal = auth.getPrincipal();

String userName = null;
if (principal instanceof UserDetails) {
   UserDetails userDetails = (UserDetails) principal;
   userName = userDetails.getUsername();
} else {
   userName = principal.toString();
}

Это было успешно, но, к сожалению, не безопасно для потоков.У кого-нибудь есть другие идеи?

Ответы [ 3 ]

0 голосов
/ 25 марта 2011

Из вашего комментария ...

У меня есть существующее приложение Spring MVC, которое в настоящее время не использует SpringSecurity ..., для которого требуется способ получить пользователя, вошедшего в систему в данный момент

Разве вы не можете просто использовать HttpServletRequest.getUserPrincipal () ?

Возвращает объект java.security.Principal, содержащий имя текущего аутентифицированного пользователя.Если пользователь не прошел проверку подлинности, метод возвращает значение null.

Наконец, ваши комментарии по безопасности потоков кажутся сомнительными, поскольку объекты контекста безопасности и объекты цены являются неизменными и по умолчанию хранятся в хранилище ThreadLocal, что делаетони совершенно безопасны для ниток.

0 голосов
/ 25 марта 2011

Спасибо за помощь, все.Я смог найти следующее объяснение от http://static.springsource.org/spring-security/site/docs/3.0.x/reference/technical-overview.html:

In an application which receives concurrent requests in a single session, 
the same SecurityContext instance will be shared between threads. Even though 
a ThreadLocal is being used, it is the same instance that is retrieved from 
the HttpSession for each thread. This has implications if you wish to  
temporarily change the context under which a thread is running. If you just use 
SecurityContextHolder.getContext().setAuthentication(anAuthentication), then 
the Authentication object will change in all concurrent threads which share the 
same SecurityContext instance.

Немного дальнейшего поиска выявило суть моей проблемы - я пропустил определение критического компонента:

<bean id="securityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>

SecurityContextPersistenceFilter гарантирует, что все будет очищено соответствующим образом при необходимости.

0 голосов
/ 25 марта 2011

Я не уверен, как вы называете это не потокобезопасным.Ваша реализация выглядит отлично.Это потокобезопасно до тех пор, пока вы извлекаете контекст каждый раз так, как вы это реализовали.SecurityContextHolder является экземпляром ThreadLocalSecurityContextHolderStrategy, который хранит SecurityContext в ThreadLocal.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...