Как получить объект сеанса весной?
Я относительно новичок в Весна и весна безопасности.
Я пытался написать программу, в которой мне нужно было аутентифицировать пользователя на сервере с помощью Spring security,
Я придумал следующее:
public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider{
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken)
throws AuthenticationException
{
System.out.println("Method invoked : additionalAuthenticationChecks isAuthenticated ? :"+usernamePasswordAuthenticationToken.isAuthenticated());
}
@Override
protected UserDetails retrieveUser(String username,UsernamePasswordAuthenticationToken authentication) throws AuthenticationException
{
System.out.println("Method invoked : retrieveUser");
//so far so good, i can authenticate user here, and throw exception if not authenticated!!
//THIS IS WHERE I WANT TO ACCESS SESSION OBJECT
}
}
мой usecase является то, что когда пользователь проходит проверку подлинности, мне нужно разместить атрибут, как:
session.setAttribute("userObject", myUserObject);
myUserObject-это объект некоторого класса, к которому я могу получить доступ через мой серверный код через несколько запрос пользователя.
6 ответов:
твой друг здесь
org.springframework.web.context.request.RequestContextHolder
// example usage public static HttpSession session() { ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); return attr.getRequest().getSession(true); // true == allow create }
это будет заполнено стандартным сервлетом spring MVC dispatch, но если вы используете другую веб-платформу, у вас есть add
org.springframework.web.filter.RequestContextFilter
как фильтр в вашемweb.xml
для управления держатель.EDIT: просто как побочный вопрос, что вы на самом деле пытаетесь сделать, я не уверен, что вам понадобится доступ к
HttpSession
наretieveUser
метод aUserDetailsService
. Весенняя безопасность поставит UserDetails объект в сессии для вас ни как. Он может быть получен путем доступа кSecurityContextHolder
:public static UserDetails currentUserDetails(){ SecurityContext securityContext = SecurityContextHolder.getContext(); Authentication authentication = securityContext.getAuthentication(); if (authentication != null) { Object principal = authentication.getPrincipal(); return principal instanceof UserDetails ? (UserDetails) principal : null; } return null; }
поскольку вы используете Spring, придерживайтесь Spring, не взламывайте его самостоятельно, как и другие посты.
на Весна механическая говорит:
вы не должны напрямую взаимодействовать с HttpSession для обеспечения безопасности цели. Там просто нет оправдания для этого-всегда используйте вместо этого SecurityContextHolder.
рекомендуется использовать следующие рекомендации для доступа к сеансу:
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if (principal instanceof UserDetails) { String username = ((UserDetails)principal).getUsername(); } else { String username = principal.toString(); }
ключевым моментом здесь является эта весна и весенняя безопасность делают все виды отличных вещей для вас, таких как предотвращение фиксации сеанса. Эти вещи предполагают, что вы используете Spring framework, поскольку он был разработан для использования. Итак, в вашем сервлете сделайте его контекстным и получите доступ к сеансу, как в приведенном выше примере.
Если вам просто нужно спрятать некоторые данные в области сеанса, попробуйте создать некоторый боб с областью сеанса, например и пусть autowire делает свою магию. :)
действительно, Вы можете получить доступ к информации из сеанса, даже когда сеанс уничтожается на HttpSessionLisener, выполнив:
public void sessionDestroyed(HttpSessionEvent hse) { SecurityContextImpl sci = (SecurityContextImpl) hse.getSession().getAttribute("SPRING_SECURITY_CONTEXT"); // be sure to check is not null since for users who just get into the home page but never get authenticated it will be if (sci != null) { UserDetails cud = (UserDetails) sci.getAuthentication().getPrincipal(); // do whatever you need here with the UserDetails } }
или вы также можете получить доступ к информации в любом месте, где у вас есть объект HttpSession, например:
SecurityContextImpl sci = (SecurityContextImpl) session().getAttribute("SPRING_SECURITY_CONTEXT");
последнее, если у вас есть что-то вроде:
HttpSession sesssion = ...; // can come from request.getSession(false);
Я сделал свои собственные utils. это удобно. :)
package samples.utils; import java.util.Arrays; import java.util.Collection; import java.util.Locale; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javax.sql.DataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.NoUniqueBeanDefinitionException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.MessageSource; import org.springframework.core.convert.ConversionService; import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.ui.context.Theme; import org.springframework.util.ClassUtils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.ThemeResolver; import org.springframework.web.servlet.support.RequestContextUtils; /** * SpringMVC通用工具 * * @author 应卓(yingzhor@gmail.com) * */ public final class WebContextHolder { private static final Logger LOGGER = LoggerFactory.getLogger(WebContextHolder.class); private static WebContextHolder INSTANCE = new WebContextHolder(); public WebContextHolder get() { return INSTANCE; } private WebContextHolder() { super(); } // -------------------------------------------------------------------------------------------------------------- public HttpServletRequest getRequest() { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); return attributes.getRequest(); } public HttpSession getSession() { return getSession(true); } public HttpSession getSession(boolean create) { return getRequest().getSession(create); } public String getSessionId() { return getSession().getId(); } public ServletContext getServletContext() { return getSession().getServletContext(); // servlet2.3 } public Locale getLocale() { return RequestContextUtils.getLocale(getRequest()); } public Theme getTheme() { return RequestContextUtils.getTheme(getRequest()); } public ApplicationContext getApplicationContext() { return WebApplicationContextUtils.getWebApplicationContext(getServletContext()); } public ApplicationEventPublisher getApplicationEventPublisher() { return (ApplicationEventPublisher) getApplicationContext(); } public LocaleResolver getLocaleResolver() { return RequestContextUtils.getLocaleResolver(getRequest()); } public ThemeResolver getThemeResolver() { return RequestContextUtils.getThemeResolver(getRequest()); } public ResourceLoader getResourceLoader() { return (ResourceLoader) getApplicationContext(); } public ResourcePatternResolver getResourcePatternResolver() { return (ResourcePatternResolver) getApplicationContext(); } public MessageSource getMessageSource() { return (MessageSource) getApplicationContext(); } public ConversionService getConversionService() { return getBeanFromApplicationContext(ConversionService.class); } public DataSource getDataSource() { return getBeanFromApplicationContext(DataSource.class); } public Collection<String> getActiveProfiles() { return Arrays.asList(getApplicationContext().getEnvironment().getActiveProfiles()); } public ClassLoader getBeanClassLoader() { return ClassUtils.getDefaultClassLoader(); } private <T> T getBeanFromApplicationContext(Class<T> requiredType) { try { return getApplicationContext().getBean(requiredType); } catch (NoUniqueBeanDefinitionException e) { LOGGER.error(e.getMessage(), e); throw e; } catch (NoSuchBeanDefinitionException e) { LOGGER.warn(e.getMessage()); return null; } } }
Я пытаюсь со следующим кодом и отлично работать
import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; /** * Created by jaime on 14/01/15. */ @Controller public class obteinUserSession { @RequestMapping(value = "/loginds", method = RequestMethod.GET) public String UserSession(ModelMap modelMap) { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); String name = auth.getName(); modelMap.addAttribute("username", name); return "hellos " + name; }
если все, что вам нужно, это данные пользователя, для Весенняя Версия 4.x можно использовать
@AuthenticationPrincipal
и@EnableWebSecurity
- тег, представленной весной, как показано ниже.Настройки Безопасности Класс:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { ... }
метод контроллера:
@RequestMapping("/messages/inbox") public ModelAndView findMessagesForUser(@AuthenticationPrincipal User user) { ... }