আমি বসন্তে সেশন অবজেক্টটি কীভাবে পাব?


88

আমি বসন্ত এবং বসন্ত সুরক্ষায় তুলনামূলকভাবে নতুন ।

আমি একটি প্রোগ্রাম লেখার চেষ্টা করছিলাম যেখানে স্প্রিং সিকিউরিটি ব্যবহার করে সার্ভারের শেষে কোনও ব্যবহারকারীর অনুমোদনের দরকার ছিল,

আমি নিম্নলিখিত নিয়ে এসেছি:

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 এমন কিছু শ্রেণীর অবজেক্ট যা আমি একাধিক ব্যবহারকারীর অনুরোধের মাধ্যমে আমার সার্ভার কোড জুড়ে অ্যাক্সেস করতে পারি।

উত্তর:


147

তোমার বন্ধু এখানে 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
}

এটি স্ট্যান্ডার্ড স্প্রিং এমভিসি প্রেরণ সার্ভলেট দ্বারা পপুলেটেড হবে, তবে আপনি যদি কোনও ভিন্ন ওয়েব ফ্রেমওয়ার্ক ব্যবহার করেন তবে ধারককে পরিচালনা করতে org.springframework.web.filter.RequestContextFilterআপনি নিজের ফিল্টার হিসাবে যুক্ত করেছেন web.xml

সম্পাদনা করুন : আপনি আসলে যা করার চেষ্টা করছেন তার সাইড ইস্যু হিসাবে, আমি নিশ্চিত না যে HttpSessionএর retieveUserপদ্ধতিতে আপনার অ্যাক্সেসের দরকার হবে UserDetailsService। বসন্ত সুরক্ষা আপনার যেভাবে কীভাবে ইউজারডিটেলসকে সেশনে রাখবে। এটি অ্যাক্সেস করে পুনরুদ্ধার করা যেতে পারে 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;
}

4
@ প্রথম পয়েন্ট: আমি অনুরোধকন্টেক্সটহোল্ডারটি ব্যবহার করার চেষ্টা করেছি, এটি আমাকে একটি ত্রুটি দিয়েছে: কোনও থ্রেড-বাউন্ড অনুরোধ পাওয়া যায় নি: আপনি কি উল্লেখ করছেন ... বর্তমান অনুরোধটি ফাঁস করতে অনুরোধকন্টেক্সটলেস্টাইনার বা অনুরোধকন্টেক্সট ফিল্টার ব্যবহার করুন। আমি যে ফিল্টারগুলি অনুমান করি তা চেষ্টা করে দেখিনি, এটি চেষ্টা করব এবং এটি কাজ করে কিনা আপনাকে জানাতে হবে। @second পয়েন্ট: আসলে তার একটি কাস্টম বস্তুর অত: পর আমি UserDetails পছন্দ করা হয়নি সম্ভব হলে করণীয় অনুরূপ বিষয়ে আমার অন্যান্য প্রশ্ন দেখুন: stackoverflow.com/questions/1629273/...
Salvin ফ্রান্সিস

4
আপনি যদি প্রেরণ সার্ভলেটটি ব্যবহার না করে থাকেন তবে আপনাকে কনফিগার করতে হবে: অনুরোধকন্টেক্সটফিল্টার
গ্যারেথ ডেভিস

4
দুঃখিত আমার ভুল ... কোডটি আমার নিজের প্রকল্প থেকে রূপান্তর করেছে যা getRequest ব্যবহার করে, উত্তরটি আপডেট হয়েছে
গ্যারেথ ডেভিস

4
ডানদিকে যা দেখায় ঠিক আছে ... একটি ডিবাগারে আপনার কোডটি থামানোর চেষ্টা করুন এবং অনুরোধকন্টেক্সট ফিল্টার কল স্ট্যাকের মধ্যে রয়েছে তা যাচাই করে দেখুন
গ্যারেথ ডেভিস

4
আমি দেখেছি যে অনুরোধকন্টেক্সটলেস্টার আমার জন্য কাজ করে নি, যেখানে অনুরোধকন্টেক্সটলিস্টনার করেছেন ...<listener><listener-class>org.springframework.web.context.request.RequestContextListener</listener-class></listener>
জোশ

33

যেহেতু আপনি বসন্ত ব্যবহার করছেন, বসন্তের সাথে লেগে থাকুন, অন্য পোস্টের পোস্টের মতো এটি নিজে হ্যাক করবেন না।

স্প্রিং ম্যানুয়াল বলেছেন:

সুরক্ষার প্রয়োজনে আপনার এইচটিটিপিএসশনের সাথে সরাসরি যোগাযোগ করা উচিত নয়। এটি করার জন্য কেবল কোনও ন্যায়সঙ্গততা নেই - এর পরিবর্তে সর্বদা সিকিউরিটি কনটেক্সটহোল্ডার ব্যবহার করুন।

অধিবেশন অ্যাক্সেসের জন্য প্রস্তাবিত সেরা অনুশীলনটি হ'ল:

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

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

এখানে মূল কীটি হ'ল স্প্রিং এবং স্প্রিং সিকিউরিটি আপনার জন্য সেশন ফিক্সেশন প্রতিরোধের মতো দুর্দান্ত সব ধরণের জিনিস করে। এই জিনিসগুলি ধরে নিয়েছে যে আপনি বসন্তের কাঠামোটি ব্যবহার করার জন্য ডিজাইন করেছিলেন হিসাবে এটি ব্যবহার করছেন। সুতরাং, আপনার সার্লেটে, এটি প্রসঙ্গে সচেতন করুন এবং উপরের উদাহরণের মতো সেশনে অ্যাক্সেস করুন।

আপনার যদি সেশনের স্কোপটিতে কেবল কিছু ডেটা স্ট্যাশ করার দরকার হয় তবে উদাহরণটির মতো কিছু সেশন স্কোপড শিম তৈরি করার চেষ্টা করুন এবং স্বতঃশক্তিকে এর যাদু করতে দিন। :)


5

আমি আমার নিজের ব্যবহার তৈরি করেছি। এটা সহজ। :)

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

সত্যই আপনি এইচটিটিপিএসশনলাইজারারে অধিবেশনটি ধ্বংস করার পরেও সেশন থেকে তথ্য অ্যাক্সেস করতে পারবেন:

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

অথবা আপনি যে কোনও জায়গায় এইচটিটিপিএসশন অবজেক্টটি উপলভ্য হিসাবে যে কোনও জায়গায় তথ্য অ্যাক্সেস করতে পারবেন:

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

শেষ অনুমান করে আপনার মতো কিছু রয়েছে:

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

3

আমি পরবর্তী কোড দিয়ে চেষ্টা করি এবং দুর্দান্ত কাজ করি

    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
আপনার কোড সহ একটি ব্যাখ্যা যোগ করুন। এখানে প্রায় কাউকে প্রশ্নের কোড বা লিঙ্ক নিক্ষেপ করা আসলেই কোনও উত্তর নয়।
রুমি

2

আপনার যা যা প্রয়োজন তা যদি ব্যবহারকারীর বিবরণ হয় তবে স্প্রিং সংস্করণ ৪.x এর জন্য আপনি নীচে দেখানো হিসাবে বসন্তের সরবরাহ @AuthenticationPrincipalএবং ব্যবহার করতে পারেন @EnableWebSecurity

সুরক্ষা কনফিগারেশন ক্লাস:

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

নিয়ামক পদ্ধতি:

@RequestMapping("/messages/inbox")
public ModelAndView findMessagesForUser(@AuthenticationPrincipal User user) {
    ...
}

1

আমার দৃশ্যে, আমি এইচটিটিপিএসশনটিকে কাস্টমআউটহেন্টিকেশনপ্রোভাইডার শ্রেণিতে ইনজেক্ট করেছি

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

0
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
attr.getSessionId();

4
এটি কীভাবে অন্যান্য বিদ্যমান উত্তরের তুলনায় সমস্যাটি সমাধান করে তা আপনার উত্তরটিতে কিছু অতিরিক্ত তথ্য যুক্ত করতে পারেন?
slfan
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.