दिलचस्प पोस्ट
php सरणी डुप्लिकेट ढूंढते हैं, उन्हें समूहीकृत करें और डुप्लिकेट हटाएं आईओएस 7 के तहत मैं UIPickerView में पाठ का रंग कैसे बदल सकता हूँ? एकाधिक सीमांकक के साथ स्ट्रिंग.split () का उपयोग करें PHP के अंदर से .sql फ़ाइलों को लोड करना Angular.js के माध्यम से सत्र को बनाए रखना एंड्रॉइड पर एक प्रोग्राम प्रोग्राम डाउनलोड करें स्प्रिंग एमवीसी कस्टम स्कोप बीन मूल्यों पर दो बार दोहराएं जीआईटी और निर्देशिका / * की अनदेखी के बीच अंतर क्या है? फेसबुक में शेबांग / हैशबैंग (#!) और नए ट्विटर यूआरएल के लिए क्या है? ट्विटर बूटस्ट्रैप 3 में ईवेंट को संक्षिप्त करने के लिए बाध्यकारी आप PHP में एक स्ट्रिंग कैसे बना सकते हैं जिसमें बैकस्लैश है? कैसे jQuery में बुदबुदाती घटनाओं को रोकने के लिए? VBA मैक्रो टाइमर शैली पर कोड को चलाने के लिए सेकंड के प्रत्येक सेट नंबर, अर्थात 120 सेकंड सी प्रोग्राम में सीरियल टर्मिनल पर बाइनरी डेटा कैसे पढ़ा जाए?

सक्रिय उपयोगकर्ता के उपयोगकर्ता कैसे प्राप्त करें Details

मेरे नियंत्रकों में, जब मुझे सक्रिय (लॉग इन) उपयोगकर्ता की आवश्यकता होती है, तो मैं अपने UserDetails कार्यान्वयन प्राप्त करने के लिए निम्न कार्य कर रहा हूं:

 User activeUser = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal(); log.debug(activeUser.getSomeCustomField()); 

यह ठीक काम करता है, लेकिन मुझे लगता था कि स्प्रिंग इस तरह से एक मामले में जीवन को आसान बना सकता है। क्या उपयोगकर्ता के पास एक नियंत्रक या विधि में autowired है?

उदाहरण के लिए, कुछ ऐसा:

 public ModelAndView someRequestHandler(Principal principal) { ... } 

लेकिन UserDetails प्राप्त करने के बजाय, मुझे इसके बजाय एक UserDetails मिला है?

मैं एक सुरुचिपूर्ण समाधान की तलाश कर रहा हूँ कोई विचार?

Solutions Collecting From Web of "सक्रिय उपयोगकर्ता के उपयोगकर्ता कैसे प्राप्त करें Details"

प्रस्तावना: स्प्रिंग-सुरक्षा 3.2 के बाद से इस उत्तर के अंत में वर्णित एक अच्छी व्याख्या @AuthenticationPrincipal । जब आप स्प्रिंग-सुरक्षा> = 3.2 का उपयोग करते हैं तो यह सबसे अच्छा तरीका है

जब आप:

  • स्प्रिंग-सुरक्षा के पुराने संस्करण का उपयोग करें,
  • अपने कस्टम उपयोगकर्ता ऑब्जेक्ट को कुछ जानकारी (जैसे लॉग इन या आईडी) द्वारा प्रिंसिपल में संग्रहीत या लोड करने की जरूरत है
  • सीखना चाहते हैं कि कैसे एक HandlerMethodArgumentResolver या WebArgumentResolver यह एक शानदार तरीके से हल कर सकता है, या बस @AuthenticationPrincipal और AuthenticationPrincipalArgumentResolver पीछे की पृष्ठभूमि सीखना चाहते हैं (क्योंकि यह एक HandlerMethodArgumentResolver पर आधारित है)

तो पढ़ना जारी रखो – और बस @AuthenticationPrincipal उपयोग @AuthenticationPrincipal और रोब @AuthenticationPrincipal ( @AuthenticationPrincipal लेखक) और लुकास @AuthenticationPrincipal (उनके उत्तर के लिए) के लिए धन्यवाद।

(बीटीडब्लू: मेरा जवाब थोड़ा बड़ा है (जनवरी 2012), इसलिए यह लुकास @AuthenticationPrincipal जो स्प्रिंग सुरक्षा 3.2 पर @AuthenticationPrincipal एनोटेशन सॉल्यूशन बेस के साथ पहली बार आया था।)


तब आप अपने नियंत्रक में उपयोग कर सकते हैं

 public ModelAndView someRequestHandler(Principal principal) { User activeUser = (User) ((Authentication) principal).getPrincipal(); ... } 

यह ठीक है अगर आपको इसकी आवश्यकता एक बार। लेकिन अगर आपको इसके बदसूरत कई बार इसकी आवश्यकता है क्योंकि यह आपके नियंत्रक को आधारभूत संरचना के विवरण के साथ प्रदत्त करती है, जो सामान्य रूप से ढांचे द्वारा छिपी जानी चाहिए।

तो क्या आप वास्तव में चाहते हैं कि इस तरह एक नियंत्रक होना चाहिए:

 public ModelAndView someRequestHandler(@ActiveUser User activeUser) { ... } 

इसलिए आपको केवल एक WebArgumentResolver लागू करने की आवश्यकता है इसकी एक विधि है

 Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) throws Exception 

यह वेब अनुरोध (दूसरा पैरामीटर) मिलता है और User को लौटा देना चाहिए यदि यह विधि तर्क (पहला पैरामीटर) के लिए जिम्मेदार है।

स्प्रिंग 3.1 के बाद से एक नई अवधारणा है जो कि HandlerMethodArgumentResolver यदि आप स्प्रिंग 3.1+ का उपयोग करते हैं तो आपको इसका उपयोग करना चाहिए। (यह अगले भाग में इस उत्तर में वर्णित है))

 public class CurrentUserWebArgumentResolver implements WebArgumentResolver{ Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) { if(methodParameter is for type User && methodParameter is annotated with @ActiveUser) { Principal principal = webRequest.getUserPrincipal(); return (User) ((Authentication) principal).getPrincipal(); } else { return WebArgumentResolver.UNRESOLVED; } } } 

आपको कस्टम टिप्पणी को परिभाषित करने की आवश्यकता है – आप इसे छोड़ सकते हैं यदि उपयोगकर्ता के हर उदाहरण को हमेशा सुरक्षा संदर्भ से लिया जाना चाहिए, लेकिन कभी कमान वस्तु नहीं है।

 @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ActiveUser {} 

विन्यास में आपको केवल यह जोड़ना होगा:

 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" id="applicationConversionService"> <property name="customArgumentResolver"> <bean class="CurrentUserWebArgumentResolver"/> </property> </bean> 

@ देखें: स्प्रिंग एमवीसी @ कंट्रोलर विधि तर्क को अनुकूलित करना सीखें

यह ध्यान दिया जाना चाहिए कि यदि आप स्प्रिंग 3.1 का उपयोग कर रहे हैं, तो वे हैंडलर-मोडअर्जमेटरॉल्वर की सलाह देते हैं WebArgumentResolver – जय द्वारा टिप्पणी देखें


स्प्रिंग 3.1+ के लिए HandlerMethodArgumentResolver के साथ HandlerMethodArgumentResolver

 public class CurrentUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter methodParameter) { return methodParameter.getParameterAnnotation(ActiveUser.class) != null && methodParameter.getParameterType().equals(User.class); } @Override public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { if (this.supportsParameter(methodParameter)) { Principal principal = webRequest.getUserPrincipal(); return (User) ((Authentication) principal).getPrincipal(); } else { return WebArgumentResolver.UNRESOLVED; } } } 

विन्यास में आपको यह जोड़ना होगा

 <mvc:annotation-driven> <mvc:argument-resolvers> <bean class="CurrentUserHandlerMethodArgumentResolver"/> </mvc:argument-resolvers> </mvc:annotation-driven> 

@ स्प्रिंग एमवीसी 3.1 हैंडलरमॉइडआगरमेंटरसोलर अंतरफलक का लाभ उठाएं


स्प्रिंग-सुरक्षा 3.2 समाधान

स्प्रिंग सुरक्षा 3.2 (स्प्रिंग 3.2 के साथ भ्रमित नहीं है) समाधान में स्वयं का निर्माण होता है: @AuthenticationPrincipal । यह अच्छी तरह से लुकास श्मेल्झेसेन के जवाब में वर्णित है

यह सिर्फ लिख रहा है

 ModelAndView someRequestHandler(@AuthenticationPrincipal User activeUser) { ... } 

इस कार्य को पाने के लिए आपको AuthenticationPrincipalArgumentResolver @EnableWebMvcSecurity को रजिस्टर करने की आवश्यकता है: या तो "सक्रिय" @EnableWebMvcSecurity द्वारा या इस बीन को mvc:argument-resolvers भीतर दर्ज करके mvc:argument-resolvers – उसी प्रकार मैंने इसके बारे में ऊपर स्प्रिंग 3.1 समाधान के साथ वर्णित किया है।

@ स्पीच सुरक्षा 3.2 संदर्भ, अध्याय 11.2। @AuthenticationPrincipal

जबकि राल्फ्स का जवाब एक शानदार समाधान प्रदान करता है, जबकि स्प्रिंग सुरक्षा 3.2 के साथ आप अपने स्वयं के ArgumentResolver को लागू करने की आवश्यकता नहीं रखते हैं।

यदि आपके पास UserDetails डिटेल्स UserDetails कस्टम CustomUser तो आप यह कर सकते हैं:

 @RequestMapping("/messages/inbox") public ModelAndView findMessagesForUser(@AuthenticationPrincipal CustomUser customUser) { // .. find messags for this user and return them ... } 

स्प्रिंग सुरक्षा दस्तावेज़ीकरण देखें : @ प्राधिकरण प्रिंसिपल

स्प्रिंग सुरक्षा का उद्देश्य अन्य गैर-स्प्रिंग फ्रेमवर्क के साथ काम करना है, इसलिए इसे वसंत MVC के साथ कसकर एकीकृत नहीं किया गया है। वसंत सुरक्षा Authentication ऑब्जेक्ट को HttpServletRequest.getUserPrincipal() पद्धति से डिफ़ॉल्ट रूप से वापस लौटाता है ताकि आप प्रिंसिपल के रूप में प्राप्त करें। आप अपने UserDetails ऑब्जेक्ट को सीधे से इसका उपयोग करके प्राप्त कर सकते हैं

 UserDetails ud = ((Authentication)principal).getPrincipal() 

यह भी ध्यान रखें कि ऑब्जेक्ट प्रकार उपयोग किए गए प्रमाणीकरण तंत्र के आधार पर भिन्न हो सकते हैं (उदाहरण के लिए आपको UsernamePasswordAuthenticationToken UserDetails नहीं मिल सकता है) और Authentication को कड़ाई से एक UserDetails होता है यह एक स्ट्रिंग या किसी अन्य प्रकार का हो सकता है।

यदि आप सीधे SecurityContextHolder को कॉल नहीं करना चाहते हैं, तो सबसे खूबसूरत दृष्टिकोण (जो मैं का पालन करेगा) अपने कस्टम सुरक्षा संदर्भ एक्सेसर इंटरफ़ेस को इंजेक्ट करने के लिए है जो आपकी आवश्यकताओं और उपयोगकर्ता ऑब्जेक्ट प्रकार से मेल खाती है। उदाहरण के लिए, प्रासंगिक विधियों के साथ, एक इंटरफ़ेस बनाएं:

 interface MySecurityAccessor { MyUserDetails getCurrentUser(); // Other methods } 

इसके बाद आप अपने मानक कार्यान्वयन में SecurityContextHolder कंसोर्टहेल्डर तक पहुंच कर इसे लागू कर सकते हैं, इस प्रकार आपके कोड को स्प्रिंग सिक्योरिटी से पूरी तरह से डीक्यूप्लिंग कर सकते हैं। फिर इन नियंत्रकों में घुसने की आवश्यकता होती है, जो कि वर्तमान उपयोगकर्ता पर सुरक्षा जानकारी या जानकारी तक पहुंच की आवश्यकता होती है।

अन्य मुख्य लाभ यह है कि थ्रेड-स्थानीय लोगों के बारे में चिंता करने के बिना परीक्षण के लिए निश्चित डेटा के साथ सरल कार्यान्वयन करना आसान है और इसी तरह

HandlerInterceptor इंटरफ़ेस को लागू करें, और फिर UserDetails को प्रत्येक अनुरोध में इंजेक्ट करें UserDetails मॉडल है, निम्नानुसार है:

 @Component public class UserInterceptor implements HandlerInterceptor { ....other methods not shown.... public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { if(modelAndView != null){ modelAndView.addObject("user", (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal()); } } 

स्प्रिंग सिक्योरिटी वर्जन 3.2 के साथ शुरू, कस्टम कार्यक्षमता जो पुराने उत्तरों में से कुछ के द्वारा लागू की गई है, @AuthenticationPrincipal एनोटेशन के रूप में बॉक्स से बाहर मौजूद है जो AuthenticationPrincipalArgumentResolver द्वारा समर्थित @AuthenticationPrincipal

इसके उपयोग का एक सरल उदाहरण है:

 @Controller public class MyController { @RequestMapping("/user/current/show") public String show(@AuthenticationPrincipal CustomUser customUser) { // do something with CustomUser return "view"; } } 

कस्टम यूज़र को authentication.getPrincipal() से असाइन किया जाना चाहिए।

यहां प्रमाणीकरण के संबंधित Javadocs हैं प्रिंसिपल और प्रमाणीकरण PrincipalArgumentResolver

 @Controller public abstract class AbstractController { @ModelAttribute("loggedUser") public User getLoggedUser() { return (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal(); } } 

और अगर आपको अधिकृत उपयोगकर्ता को टेम्पलेट्स (जैसे जेएसपी) का इस्तेमाल करना है तो

 <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> <sec:authentication property="principal.yourCustomField"/> 

के साथ साथ

  <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> <version>${spring-security.version}</version> </dependency>