Я относительно новичок в Spring и Spring security.
Я пытался написать программу, в которой мне нужно было аутентифицировать пользователя на стороне сервера, используя безопасность Spring,
Я придумал следующее:
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
}
}
Мой вариант использования заключается в том, что при аутентификации пользователя мне нужно разместить такой атрибут, как:
session.setAttribute("userObject", myUserObject);
myUserObject - это объект некоторого класса, к которому я могу получить доступ через мой серверный код через несколько пользовательских запросов.
источник
<listener><listener-class>org.springframework.web.context.request.RequestContextListener</listener-class></listener>
Поскольку вы используете Spring, придерживайтесь Spring, а не взламывайте его самостоятельно, как другие посты.
В руководстве Spring говорится:
Рекомендуемая передовая практика для доступа к сеансу:
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if (principal instanceof UserDetails) { String username = ((UserDetails)principal).getUsername(); } else { String username = principal.toString(); }
Ключевым моментом здесь является то, что Spring и Spring Security делают для вас всевозможные отличные вещи, такие как Session Fixation Prevention. Эти вещи предполагают, что вы используете фреймворк Spring так, как он был разработан для использования. Итак, в вашем сервлете сделайте его контекстно-зависимым и получите доступ к сеансу, как в приведенном выше примере.
Если вам просто нужно спрятать некоторые данные в области видимости сеанса, попробуйте создать bean-компонент с привязкой к сеансу, как в этом примере, и позвольте autowire творить чудеса. :)
источник
я сделал свои собственные утилиты. это удобно. :)
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; } } }
источник
Действительно, вы можете получить доступ к информации из сеанса, даже если сеанс уничтожается на 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);
источник
Я пробую со следующим кодом и отлично работаю
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; }
источник
Если все, что вам нужно, это сведения о пользователе, для Spring версии 4.x вы можете использовать
@AuthenticationPrincipal
и@EnableWebSecurity
теги, предоставленные Spring, как показано ниже.Класс конфигурации безопасности:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { ... }
Метод контроллера:
@RequestMapping("/messages/inbox") public ModelAndView findMessagesForUser(@AuthenticationPrincipal User user) { ... }
источник
В моем сценарии я ввел HttpSession в класс CustomAuthenticationProvider следующим образом
public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider{ @Autowired private HttpSession httpSession; @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 httpSession.setAttribute("userObject", myUserObject); } }
источник
источник