Comment obtenir L'objet Session au printemps?

je suis relativement nouveau à Printemps et le Printemps de sécurité.

j'ai essayé d'écrire un programme où j'avais besoin d'authentifier un utilisateur à l'extrémité du serveur en utilisant la sécurité du ressort,

j'ai trouvé ce qui suit:

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 usecase est que lorsqu'un utilisateur est authentifié, je dois placer un attribut comme:

session.setAttribute("userObject", myUserObject);

myUserObject est un objet d'une certaine classe que je peux accéder à travers mon code serveur à travers plusieurs requêtes utilisateur.

74
demandé sur Andremoniy 2009-10-27 10:26:24

6 réponses

votre ami ici 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
}

ce champ sera rempli par le servlet standard MVC dispatch servlet, mais si vous utilisez un framework web différent, vous devez ajouter org.springframework.web.filter.RequestContextFilter comme filtre dans votre web.xml pour gérer le support.

EDIT : juste comme une question secondaire ce que vous essayez réellement de faire, Je ne suis pas sûr que vous devriez avoir accès à la HttpSession en la méthode retieveUser d'un UserDetailsService . Spring security mettra L'objet UserDetails dans la session pour vous de quelle manière. Il peut être récupéré en accédant au 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;
}
118
répondu Gareth Davis 2015-04-08 05:35:04

depuis que vous utilisez le ressort, coller avec le ressort, ne le hacker pas vous-même comme les autres posits de poste.

Le "151940920 de" Printemps " manuel dit:

vous ne devriez pas interagir directement avec HttpSession pour la sécurité but. Il n'y a tout simplement aucune justification pour le faire - toujours utiliser la SecurityContextHolder à la place.

la meilleure pratique suggérée pour accéder à la la séance 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 la sécurité du ressort et du ressort font toutes sortes de bonnes choses pour vous comme la prévention de la Fixation de Session. Ces choses supposent que vous utilisez le cadre de ressort comme il a été conçu pour être utilisé. Ainsi, dans votre servlet, mettez-le en contexte et accédez à la session comme dans l'exemple ci-dessus.

si vous avez juste besoin de stocker des données dans la portée de la session, essayez de créer une session scoped bean comme ceci exemple et laisser autowire faire sa magie. :)

29
répondu Joseph Lust 2017-05-23 12:34:25

en effet, vous pouvez accéder aux informations de la session même lorsque la session est détruite sur un 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 partout où vous avez l'objet HttpSession disponible comme:

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

le dernier en supposant que vous avez quelque chose comme:

HttpSession sesssion = ...; // can come from request.getSession(false);
4
répondu OscarG 2013-04-25 18:05:01

j'ai fait mes propres 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;
        }
    }

}
4
répondu Zhuo YING 2014-02-28 06:34:56

j'ai essayer avec le code suivant et le travail excellent

    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;
        }
3
répondu jaimeRambo 2016-06-10 19:26:36

si tout ce que vous avez besoin est des détails de L'utilisateur, pour version printemps 4.x vous pouvez utiliser @AuthenticationPrincipal et @EnableWebSecurity étiquette fournie par le ressort comme indiqué ci-dessous.

Configuration De La Sécurité De La Classe:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
   ...
}

méthode du contrôleur:

@RequestMapping("/messages/inbox")
public ModelAndView findMessagesForUser(@AuthenticationPrincipal User user) {
    ...
}
1
répondu pranjal thakur 2017-09-24 15:13:50