98 votes

Comment puis-je obtenir l'Objet de la Session de Printemps?

Je suis relativement nouveau pour le Printemps et le Printemps de sécurité.

J'ai été de tenter d'écrire un programme où j'avais besoin d'authentifier un utilisateur à la fin du serveur à l'aide de Printemps de sécurité,

Je suis venu avec les éléments suivants:

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
    }
}

Mon cas d'utilisation, c'est que lorsqu'un utilisateur est authentifié, j'ai besoin de placer un attribut comme:

session.setAttribute("userObject", myUserObject);

myUserObject est un objet de la classe que je puisse y accéder tout au long de mon code serveur à travers de multiples demandes de l'utilisateur.

161voto

Gareth Davis Points 16190

Votre ami est - 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
}

Ceci est complété par la norme spring mvc expédition servlet, mais si vous utilisez un autre framework web vous avez ajouter org.springframework.web.filter.RequestContextFilter comme un filtre dans votre web.xml pour gérer le titulaire.

EDIT: juste comme une question de côté ce que vous êtes réellement en train de faire, je ne suis pas sûr que vous devriez avoir besoin d'accéder à l' HttpSession dans la retieveUser méthode de UserDetailsService. Printemps de sécurité va mettre la UserDetails objet dans la session pour vous de toute façon. Il peut être récupéré en accédant à l' SecurityContextHolder:

public static UserDetails currentUserDetails(){
    SecurityContext securityContext = SecurityContextHolder.getContext();
    Authentication authentication = securityContext.getAuthentication();
    if (authentication != null) {
        Object principal = authentication.getPrincipal();
        return principal instanceof UserDetails ? principal : null;
    }
    return null;
}

37voto

Joseph Lust Points 4961

Depuis que vous utilisez le Printemps, bâton avec le Printemps, à ne pas pirater vous-même comme les autres post postule.

Le Printemps manuel dit:

Vous ne devriez pas interagir directement avec les HttpSession pour la sécurité fins. Il n'y a tout simplement aucune raison de le faire, utilisez toujours des le SecurityContextHolder à la place.

Les meilleures pratiques pour l'accès à la session est:

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

if (principal instanceof UserDetails) {
  String username = ((UserDetails)principal).getUsername();
} else {
  String username = principal.toString();
}

La clé ici est que le Ressort et la Sécurité font toutes sortes de grandes choses pour vous comme la Session de la Fixation de la Prévention. Ces choses supposons que vous êtes en utilisant le framework Spring comme il a été conçu pour être utilisé. Donc, dans votre servlet, de le rendre sensible au contexte et à l'accès à la session comme l'exemple ci-dessus.

Si vous avez juste besoin de ranger les quelques données de la session, essayez de créer de session étendue bean comme cet exemple et de laisser autowire faire sa magie. :)

6voto

Zhuo YING Points 74

j'ai fait ma propre utils. il est très pratique. :)

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;
        }
    }

}

4voto

OscarG Points 210

En effet, vous pouvez accéder aux informations de la session, même lorsque la session est détruite sur une HttpSessionLisener en faisant:

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 vous pouvez également accéder à l'information de n'importe où vous avez l'objet HttpSession disponibles comme:

SecurityContextImpl sci = (SecurityContextImpl) session().getAttribute("SPRING_SECURITY_CONTEXT");

la dernière en supposant que vous avez quelque chose comme:

HttpSession sesssion = ...; // can come from request.getSession(false);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X