Eu sou relativamente novo para Primavera segurança e Primavera.
Eu estava tentando escrever um programa em que precisava autenticar um usuário na extremidade do servidor usando a segurança Spring,
Eu vim com o seguinte:
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
}
}
Meu caso de uso é que, quando um usuário é autenticado, preciso colocar um atributo como:
session.setAttribute("userObject", myUserObject);
myUserObject é um objeto de alguma classe que posso acessar por meio de meu código de servidor em várias solicitações de usuário.
fonte
<listener><listener-class>org.springframework.web.context.request.RequestContextListener</listener-class></listener>
Já que você está usando o Spring, fique com o Spring, não faça hack sozinho como as outras postagens.
O manual do Spring diz:
A prática recomendada sugerida para acessar a sessão é:
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if (principal instanceof UserDetails) { String username = ((UserDetails)principal).getUsername(); } else { String username = principal.toString(); }
A chave aqui é que Spring e Spring Security fazem todos os tipos de coisas excelentes para você, como a Prevenção de fixação de sessão. Essas coisas pressupõem que você está usando a estrutura Spring da forma como foi projetada para ser usada. Portanto, em seu servlet, torne-o ciente do contexto e acesse a sessão como no exemplo acima.
Se você precisa apenas armazenar alguns dados no escopo da sessão, tente criar algum bean com escopo de sessão como este exemplo e deixe o autowire fazer sua mágica. :)
fonte
eu fiz meus próprios utils. é útil. :)
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; } } }
fonte
Na verdade, você pode acessar as informações da sessão mesmo quando a sessão está sendo destruída em um HttpSessionLisener, fazendo:
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 } }
ou você também pode acessar as informações em qualquer lugar que tenha o objeto HttpSession disponível, como:
SecurityContextImpl sci = (SecurityContextImpl) session().getAttribute("SPRING_SECURITY_CONTEXT");
o último presumindo que você tenha algo como:
HttpSession sesssion = ...; // can come from request.getSession(false);
fonte
Eu tento com o próximo código e trabalho excelente
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; }
fonte
Se tudo o que você precisa é detalhes de usuário, para Primavera versão 4.x você pode usar
@AuthenticationPrincipal
e@EnableWebSecurity
tag fornecido pela Primavera como mostrado abaixo.Classe de configuração de segurança:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { ... }
Método do controlador:
@RequestMapping("/messages/inbox") public ModelAndView findMessagesForUser(@AuthenticationPrincipal User user) { ... }
fonte
Em meu cenário, injetei o HttpSession na classe CustomAuthenticationProvider assim
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); } }
fonte
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); attr.getSessionId();
fonte