स्प्रिंग सुरक्षा का उपयोग करते समय, सेम में वर्तमान उपयोगकर्ता नाम (यानी SecurityContext) जानकारी प्राप्त करने का उचित तरीका क्या है?


288

मेरे पास स्प्रिंग एमवीसी वेब ऐप है जो स्प्रिंग सुरक्षा का उपयोग करता है। मैं वर्तमान में लॉग इन उपयोगकर्ता का उपयोगकर्ता नाम जानना चाहता हूं। मैं नीचे दिए गए कोड स्निपेट का उपयोग कर रहा हूं। क्या यह स्वीकृत तरीका है?

मुझे इस नियंत्रक के अंदर एक स्थिर विधि के लिए कॉल करना पसंद नहीं है - जो स्प्रिंग, IMHO के पूरे उद्देश्य को हरा देता है। क्या इसके बदले में वर्तमान SecurityContext, या current Authentication के लिए एप्लिकेशन को कॉन्फ़िगर करने का कोई तरीका है?

  @RequestMapping(method = RequestMethod.GET)
  public ModelAndView showResults(final HttpServletRequest request...) {
    final String currentUser = SecurityContextHolder.getContext().getAuthentication().getName();
    ...
  }

सुपर क्लास के रूप में आपके पास कंट्रोलर (सुरक्षित नियंत्रक) क्यों नहीं है, सिक्योरिटी कॉन्टेक्स्ट से उपयोगकर्ता प्राप्त करें और इसे उस वर्ग के अंदर एक उदाहरण चर के रूप में सेट करें? इस तरह जब आप सुरक्षित नियंत्रक का विस्तार करते हैं, तो आपके पूरे वर्ग को वर्तमान संदर्भ के उपयोगकर्ता प्रिंसिपल तक पहुंच प्राप्त होगी।
देहान दे क्रोस

जवाबों:


259

यदि आप स्प्रिंग 3 का उपयोग कर रहे हैं , तो सबसे आसान तरीका है:

 @RequestMapping(method = RequestMethod.GET)   
 public ModelAndView showResults(final HttpServletRequest request, Principal principal) {

     final String currentUser = principal.getName();

 }

69

इस सवाल का जवाब देने के बाद से वसंत की दुनिया में बहुत कुछ बदल गया है। स्प्रिंग ने एक नियंत्रक में वर्तमान उपयोगकर्ता को प्राप्त करना आसान बना दिया है। अन्य सेम के लिए, स्प्रिंग ने लेखक के सुझावों को अपनाया और 'SecurityContextHolder' के इंजेक्शन को सरल बनाया। अधिक विवरण टिप्पणियों में हैं।


यह वह उपाय है जिसे मैंने समाप्त किया है। SecurityContextHolderअपने नियंत्रक में उपयोग करने के बजाय , मैं कुछ ऐसा इंजेक्ट करना चाहता हूं जो SecurityContextHolderहुड के नीचे उपयोग करता है , लेकिन मेरे कोड से उस सिंगलटन जैसी कक्षा को अलग करता है। मुझे अपने स्वयं के इंटरफ़ेस को रोल करने के अलावा ऐसा करने का कोई तरीका नहीं मिला, जैसे:

public interface SecurityContextFacade {

  SecurityContext getContext();

  void setContext(SecurityContext securityContext);

}

अब, मेरा नियंत्रक (या जो भी POJO) ऐसा दिखेगा:

public class FooController {

  private final SecurityContextFacade securityContextFacade;

  public FooController(SecurityContextFacade securityContextFacade) {
    this.securityContextFacade = securityContextFacade;
  }

  public void doSomething(){
    SecurityContext context = securityContextFacade.getContext();
    // do something w/ context
  }

}

और, इंटरफ़ेस के डिकूपिंग का एक बिंदु होने के कारण, यूनिट परीक्षण सीधा है। इस उदाहरण में मैं मॉकिटो का उपयोग करता हूं:

public class FooControllerTest {

  private FooController controller;
  private SecurityContextFacade mockSecurityContextFacade;
  private SecurityContext mockSecurityContext;

  @Before
  public void setUp() throws Exception {
    mockSecurityContextFacade = mock(SecurityContextFacade.class);
    mockSecurityContext = mock(SecurityContext.class);
    stub(mockSecurityContextFacade.getContext()).toReturn(mockSecurityContext);
    controller = new FooController(mockSecurityContextFacade);
  }

  @Test
  public void testDoSomething() {
    controller.doSomething();
    verify(mockSecurityContextFacade).getContext();
  }

}

इंटरफ़ेस का डिफ़ॉल्ट कार्यान्वयन इस तरह दिखता है:

public class SecurityContextHolderFacade implements SecurityContextFacade {

  public SecurityContext getContext() {
    return SecurityContextHolder.getContext();
  }

  public void setContext(SecurityContext securityContext) {
    SecurityContextHolder.setContext(securityContext);
  }

}

और, अंत में, उत्पादन वसंत विन्यास इस तरह दिखता है:

<bean id="myController" class="com.foo.FooController">
     ...
  <constructor-arg index="1">
    <bean class="com.foo.SecurityContextHolderFacade">
  </constructor-arg>
</bean>

यह थोड़ा मूर्खतापूर्ण से अधिक लगता है कि स्प्रिंग, सभी चीजों के एक निर्भरता इंजेक्शन कंटेनर, ने कुछ इसी तरह के इंजेक्शन लगाने का तरीका नहीं दिया है। मैं समझता हूं कि मुझे SecurityContextHolderएसेगी से विरासत में मिला था, लेकिन फिर भी। बात यह है, वे इतने करीब हैं - यदि केवल SecurityContextHolderअंतर्निहित SecurityContextHolderStrategyउदाहरण (जो एक इंटरफ़ेस है) प्राप्त करने के लिए एक गेटर था , तो आप उसे इंजेक्ट कर सकते हैं। वास्तव में, मैंने उस प्रभाव के लिए एक जीरा मुद्दा भी खोला

एक आखिरी बात - मैंने अभी पहले जो उत्तर दिया था, उसे काफी हद तक बदल दिया है। इतिहास की जाँच करें अगर आप उत्सुक हैं, लेकिन जैसा कि एक सहकर्मी ने मुझे बताया, मेरा पिछला उत्तर बहु-सूत्रीय वातावरण में काम नहीं करेगा। अंतर्निहित SecurityContextHolderStrategyद्वारा इस्तेमाल किया SecurityContextHolder, डिफ़ॉल्ट, की एक आवृत्ति ThreadLocalSecurityContextHolderStrategyहै, जो भंडार SecurityContextएक में ThreadLocal। इसलिए, SecurityContextशुरुआती समय में सीधे बीन में इंजेक्शन लगाने के लिए यह एक अच्छा विचार नहीं है - इसे ThreadLocalबहु-थ्रेडेड वातावरण में, प्रत्येक बार से पुनर्प्राप्त करने की आवश्यकता हो सकती है, इसलिए सही एक को पुनः प्राप्त किया जा सकता है।


1
मुझे आपका समाधान पसंद है - यह स्प्रिंग में फैक्टरी-विधि समर्थन का एक चतुर उपयोग है। उस ने कहा, यह आपके लिए काम कर रहा है क्योंकि नियंत्रक वस्तु को वेब अनुरोध के लिए स्कोप किया गया है। यदि आपने नियंत्रक बीन के दायरे को गलत तरीके से बदल दिया है, तो यह टूट जाएगा।
पॉल मोरी

2
पिछली दो टिप्पणियाँ एक पुराने, गलत उत्तर को संदर्भित करती हैं जिसे मैंने अभी-अभी प्रतिस्थापित किया है।
स्कॉट बेल

12
क्या यह अभी भी वर्तमान स्प्रिंग रिलीज़ के साथ अनुशंसित समाधान है? मुझे विश्वास नहीं हो रहा है कि इसे सिर्फ यूजरनेम प्राप्त करने के लिए इतना कोड चाहिए।
ता सास

6
यदि आप स्प्रिंग सिक्योरिटी 3.0.x का उपयोग कर रहे हैं, तो उन्होंने JIRA मुद्दे में मेरा सुझाव लागू किया जिसे मैंने jira.springsource.org/browse/SEC-1188 पर लॉग इन किया ताकि आप अब SecurityContextHolderStrategy उदाहरण (SecurityContextHolder से) को सीधे अपने बीन में मानक के माध्यम से इंजेक्ट कर सकें। वसंत विन्यास।
स्कॉट गठरी

4
कृपया tsunade21 उत्तर देखें। स्प्रिंग 3 अब आपको अपने नियंत्रक में एक विधि तर्क के रूप में java.security.Principal का उपयोग करने की अनुमति देता है
पैट्रिक

22

मैं मानता हूं कि वर्तमान उपयोगकर्ता की बदबू के लिए SecurityContext को क्वेरी करना, इस समस्या को संभालने के लिए एक बहुत ही अन-स्प्रिंग तरीका है।

मैंने इस समस्या से निपटने के लिए एक स्थिर "सहायक" वर्ग लिखा; यह गंदी बात है कि यह एक वैश्विक और स्थैतिक तरीका है, लेकिन मैंने इस तरह से सोचा कि अगर हम सुरक्षा से संबंधित किसी भी चीज को बदलते हैं, तो कम से कम मुझे केवल एक स्थान पर विवरण बदलना होगा:

/**
* Returns the domain User object for the currently logged in user, or null
* if no User is logged in.
* 
* @return User object for the currently logged in user, or null if no User
*         is logged in.
*/
public static User getCurrentUser() {

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

    if (principal instanceof MyUserDetails) return ((MyUserDetails) principal).getUser();

    // principal object is either null or represents anonymous user -
    // neither of which our domain User object can represent - so return null
    return null;
}


/**
 * Utility method to determine if the current user is logged in /
 * authenticated.
 * <p>
 * Equivalent of calling:
 * <p>
 * <code>getCurrentUser() != null</code>
 * 
 * @return if user is logged in
 */
public static boolean isLoggedIn() {
    return getCurrentUser() != null;
}

22
यह तब तक है जब तक SecurityContextHolder.getContext () है, और बाद वाला थ्रेडसेफ़ है क्योंकि यह सुरक्षा विवरण को थ्रेडलोक में रखता है। यह कोड कोई राज्य नहीं रखता है।
मैट बी

22

इसे अपने JSP पृष्ठों में दिखाने के लिए, आप स्प्रिंग सुरक्षा टैग Lib का उपयोग कर सकते हैं:

http://static.springsource.org/spring-security/site/docs/3.0.x/reference/taglibs.html

किसी भी टैग का उपयोग करने के लिए, आपके पास अपने JSP में घोषित सुरक्षा टैगलिब होना चाहिए:

<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>

फिर एक jsp पेज में कुछ इस तरह से करें:

<security:authorize access="isAuthenticated()">
    logged in as <security:authentication property="principal.username" /> 
</security:authorize>

<security:authorize access="! isAuthenticated()">
    not logged in
</security:authorize>

नोट: जैसा कि @ SBerg413 द्वारा टिप्पणियों में उल्लेख किया गया है, आपको जोड़ना होगा

उपयोग-भाव = "true"

इसके लिए "http" टैग को Security.xml कॉन्फिग में काम करने के लिए कॉन्फ़िगर करें।


ऐसा लगता है कि यह शायद स्प्रिंग सिक्योरिटी द्वारा अनुमोदित तरीका है!
निक स्पेसक

3
काम करने के लिए इस विधि के लिए, आपको सुरक्षा -xml कॉन्फ़िगरेशन में http टैग में उपयोग-अभिव्यक्ति = "सही" जोड़ने की आवश्यकता है।
SBerg413

धन्यवाद @ SBerg413, मैं अपना उत्तर संपादित करूँगा और अपना महत्वपूर्ण स्पष्टीकरण दूंगा!
ब्रैड पार्क्स

14

यदि आप स्प्रिंग सिक्योरिटी वर्जन = = 3.2 का उपयोग कर रहे हैं, तो आप @AuthenticationPrincipalएनोटेशन का उपयोग कर सकते हैं :

@RequestMapping(method = RequestMethod.GET)
public ModelAndView showResults(@AuthenticationPrincipal CustomUser currentUser, HttpServletRequest request) {
    String currentUsername = currentUser.getUsername();
    // ...
}

यहाँ, CustomUserएक कस्टम ऑब्जेक्ट है जो UserDetailsएक कस्टम द्वारा लौटाया जाता हैUserDetailsService

अधिक जानकारी स्प्रिंग सुरक्षा संदर्भ डॉक्स के @AuthenticationPrincipal अध्याय में पाई जा सकती है ।


13

मुझे HttpServletRequest.getUserPrincipal () द्वारा प्रमाणित उपयोगकर्ता मिलता है;

उदाहरण:

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.support.RequestContext;

import foo.Form;

@Controller
@RequestMapping(value="/welcome")
public class IndexController {

    @RequestMapping(method=RequestMethod.GET)
    public String getCreateForm(Model model, HttpServletRequest request) {

        if(request.getUserPrincipal() != null) {
            String loginName = request.getUserPrincipal().getName();
            System.out.println("loginName : " + loginName );
        }

        model.addAttribute("form", new Form());
        return "welcome";
    }
}

मुझे आपका समाधान पसंद है। स्प्रिंग विशेषज्ञों के लिए: क्या यह सुरक्षित, अच्छा समाधान है?
8

एक अच्छा समाधान नहीं। nullयदि उपयोगकर्ता गुमनाम रूप से ( http> anonymousस्प्रिंग सुरक्षा XML में तत्व) प्रमाणित है तो आपको मिलेगा । SecurityContextHolderया SecurityContextHolderStrategyउचित तरीका है।
नाउकर

1
ताकि मैंने जाँच की है कि नहीं तो null request.getUserPrincipal ()! = Null।
digz6666

फिल्टर में अशक्त है
एलेक्स78191

9

स्प्रिंग 3+ में आपके पास निम्नलिखित विकल्प हैं।

विकल्प 1 :

@RequestMapping(method = RequestMethod.GET)    
public String currentUserNameByPrincipal(Principal principal) {
    return principal.getName();
}

विकल्प 2 :

@RequestMapping(method = RequestMethod.GET)
public String currentUserNameByAuthentication(Authentication authentication) {
    return authentication.getName();
}

विकल्प 3:

@RequestMapping(method = RequestMethod.GET)    
public String currentUserByHTTPRequest(HttpServletRequest request) {
    return request.getUserPrincipal().getName();

}

विकल्प 4: फैंसी एक: अधिक विवरण के लिए इसे देखें

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

1
3.2 के बाद से, स्प्रिंग-सिक्योरिटी-वेब आपके लिंक से @CurrentUserकस्टम की तरह काम करता है @ActiveUser
माइक पार्ट्रीज

@ माइककार्ट्रिज, मुझे लगता है कि आप क्या कह रहे हैं, कोई लिंक नहीं मिल रहा है ?? या अधिक जानकारी ??
अजराफती

1
मेरी गलती - मैंने स्प्रिंग सिक्योरिटी ऑथेंटिकेशनपीनिप्रीसालअर्गुमेंट Resolver javadoc को गलत समझा । @AuthenticationPrincipalकस्टम @CurrentUserएनोटेशन के साथ रैपिंग करते हुए एक उदाहरण दिखाया गया है । 3.2 के बाद से हमें लिंक किए गए उत्तर में कस्टम तर्क रिज़ॉल्वर लागू करने की आवश्यकता नहीं है। इस अन्य उत्तर में अधिक विवरण है।
माइक पार्टरिज

5

हां, स्टेटिक्स आमतौर पर खराब होते हैं - आम तौर पर, लेकिन इस मामले में, स्टेटिक सबसे सुरक्षित कोड है जिसे आप लिख सकते हैं। चूंकि सुरक्षा संदर्भ वर्तमान में चल रहे धागे के साथ एक प्रिंसिपल को जोड़ता है, इसलिए सबसे सुरक्षित कोड सीधे थ्रेड से स्थैतिक तक पहुंच सकेगा। एक आवरण वर्ग के पीछे पहुंच को छिपाकर जो इंजेक्शन लगाया जाता है, वह हमलावर को अधिक अंक के साथ हमला करने के लिए प्रदान करता है। उन्हें कोड तक पहुंच की आवश्यकता नहीं होगी (जो कि जार में हस्ताक्षर किए जाने पर उन्हें बदलने में कठिन समय होगा), उन्हें बस कॉन्फ़िगरेशन को ओवरराइड करने का एक तरीका चाहिए, जो रनटाइम पर किया जा सकता है या क्लासपाथ पर कुछ एक्सएमएल फिसल सकता है। यहां तक ​​कि हस्ताक्षरित कोड में एनोटेशन इंजेक्शन का उपयोग करना बाहरी एक्सएमएल के साथ बहुत अधिक उपयोगी होगा। ऐसे XML बदमाश प्रिंसिपल के साथ चल रहे सिस्टम को इंजेक्ट कर सकते हैं।


5

मैं बस यही करूंगा:

request.getRemoteUser();

1
यह काम कर सकता है, लेकिन मज़बूती से नहीं। Javadoc से: "क्या उपयोगकर्ता का नाम प्रत्येक बाद के अनुरोध के साथ भेजा जाता है, ब्राउज़र और प्रमाणीकरण के प्रकार पर निर्भर करता है।" - download-llnw.oracle.com/javaee/6/api/javax/servlet/http/…
Scott Bale

3
यह स्प्रिंग सिक्योरिटी वेब एप्लिकेशन में रिमोट यूज़रनेम पाने के लिए वास्तव में एक वैध और बहुत ही सरल तरीका है। मानक फ़िल्टर श्रृंखला में एक SecurityContextHolderAwareRequestFilterअनुरोध शामिल होता है जो अनुरोध को लागू करता है और एक्सेस करके इस कॉल को लागू करता है SecurityContextHolder
को भेड़

4

पिछले स्प्रिंग MVC ऐप के लिए मैंने लिखा, मैंने SecurityContext धारक को इंजेक्ट नहीं किया, लेकिन मेरे पास एक आधार नियंत्रक था कि मेरे पास इससे संबंधित दो उपयोगिता विधियाँ थीं ... isAuthenticated () और getUsername ()। आंतरिक रूप से वे आपके द्वारा वर्णित स्टैटिक विधि को करते हैं।

कम से कम तब यह केवल एक ही बार होता है यदि आपको बाद में रिफ्लेक्टर की आवश्यकता होती है।


3

आप स्प्रिंग AOP aproach का उपयोग कर सकते हैं। उदाहरण के लिए यदि आपके पास कुछ सेवा है, जिसे वर्तमान प्रिंसिपल को जानना होगा। आप कस्टम एनोटेशन यानी @Principal का परिचय दे सकते हैं, जो दर्शाता है कि यह सेवा प्रमुख निर्भर होनी चाहिए।

public class SomeService {
    private String principal;
    @Principal
    public setPrincipal(String principal){
        this.principal=principal;
    }
}

फिर आपकी सलाह में, जो मुझे लगता है कि MethodBeforeAdvice का विस्तार करने की आवश्यकता है, उस विशेष सेवा की जांच करें @Principal एनोटेशन और प्रिंसिपल नाम इंजेक्ट करें, या इसके बजाय इसे 'ANONYMOUS' पर सेट करें।


मुझे सेवा वर्ग के अंदर प्रिंसिपल तक पहुंचने की आवश्यकता है क्या आप जीथब पर एक पूर्ण उदाहरण पोस्ट कर सकते हैं? मैं वसंत एओपी नहीं जानता, इसलिए अनुरोध।
राकेश वाघेला

2

एकमात्र समस्या यह है कि स्प्रिंग सिक्योरिटी के साथ प्रमाणित होने के बाद भी, उपयोगकर्ता / प्रमुख बीन कंटेनर में मौजूद नहीं है, इसलिए निर्भरता-इंजेक्शन करना मुश्किल होगा। इससे पहले कि हम स्प्रिंग सिक्योरिटी का इस्तेमाल करते, हम एक सत्र-स्कॉप्ड बीन तैयार करते, जिसमें वर्तमान प्रिंसिपल थे, उसे "ऑथर्स सर्विस" में इंजेक्ट करें और फिर उस सर्विस को एप्लिकेशन की अधिकांश अन्य सेवाओं में इंजेक्ट करें। तो उन सेवाओं को ऑब्जेक्ट प्राप्त करने के लिए बसभीखाना होगा। यदि आपके पास अपने कोड में एक जगह है जहां आपको सत्र में उसी प्रिंसिपल का संदर्भ मिलता है, तो आप इसे अपने सत्र-स्कोप बीन पर संपत्ति के रूप में सेट कर सकते हैं।


1

इसे इस्तेमाल करे

प्रमाणीकरण प्रमाणीकरण = SecurityContextHolder.getContext ()। GetAuthentication ();
स्ट्रिंग उपयोगकर्ता नाम = प्रमाणीकरण.गेटनाम ();


3
SecurityContextHolder.getContext () स्थैतिक विधि को कॉल करना वही है जो मुझे मूल प्रश्न में शिकायत कर रहा था। आपने कुछ भी उत्तर नहीं दिया है।
स्कॉट बोले 20

2
हालाँकि, यह वही है जो प्रलेखन की सिफारिश करता है: static.springsource.org/spring-security/site/docs/3.0.x/… तो क्या आप इसे टालकर पूरा कर रहे हैं? आप एक साधारण समस्या के जटिल समाधान की तलाश में हैं। सबसे अच्छा - आपको एक ही व्यवहार मिलता है। सबसे कम, आपको एक बग या सुरक्षा छेद मिलता है।
बॉब कर्न्स

2
@BusKerns परीक्षण के लिए, यह थ्रेड लोकल पर डालने के विपरीत प्रमाणीकरण को इंजेक्ट करने में सक्षम होने के लिए क्लीनर है।

1

सबसे अच्छा समाधान यदि आप स्प्रिंग 3 का उपयोग कर रहे हैं और आपके नियंत्रक में प्रमाणित प्रिंसिपल की आवश्यकता है, तो ऐसा कुछ करना है:

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;

    @Controller
    public class KnoteController {
        @RequestMapping(method = RequestMethod.GET)
        public java.lang.String list(Model uiModel, UsernamePasswordAuthenticationToken authToken) {

            if (authToken instanceof UsernamePasswordAuthenticationToken) {
                user = (User) authToken.getPrincipal();
            }
            ...

    }

1
जब आप पैरामीटर पहले से ही टाइप कर रहे हैं, तो उपयोगकर्ता नामपासपैथ औथेंटिकेशनटोकन चेक इन क्यों कर रहे हैं?
स्कॉट बले

(schemToken Instof UsernamePasswordAuthenticationToken) कार्यात्मक के बराबर है अगर (CortToken! = null)। उत्तरार्द्ध थोड़ा क्लीनर हो सकता है लेकिन अन्यथा कोई अंतर नहीं है।
मार्क

1

मैं कक्षाओं में और साथ ही एनोटेट में @AuthenticationPrincipalएनोटेशन का उपयोग कर रहा हूं । पूर्व .:@Controller@ControllerAdvicer

@ControllerAdvice
public class ControllerAdvicer
{
    private static final Logger LOGGER = LoggerFactory.getLogger(ControllerAdvicer.class);


    @ModelAttribute("userActive")
    public UserActive currentUser(@AuthenticationPrincipal UserActive currentUser)
    {
        return currentUser;
    }
}

UserActiveलॉग इन की गई उपयोगकर्ता सेवाओं के लिए मैं कक्षा का उपयोग कहां करता हूं, और इससे बढ़ाता हूं org.springframework.security.core.userdetails.User। कुछ इस तरह:

public class UserActive extends org.springframework.security.core.userdetails.User
{

    private final User user;

    public UserActive(User user)
    {
        super(user.getUsername(), user.getPasswordHash(), user.getGrantedAuthorities());
        this.user = user;
    }

     //More functions
}

वास्तव में आसान।


0

Principalअपने नियंत्रक विधि में एक निर्भरता के रूप में परिभाषित करें और वसंत आह्वान पर आपकी विधि में वर्तमान प्रमाणित उपयोगकर्ता को इंजेक्ट करेगा।


-2

मुझे फ्रेंडमार्क पेज पर उपयोगकर्ता के विवरण का समर्थन करने का अपना तरीका साझा करना पसंद है। सब कुछ बहुत सरल है और पूरी तरह से काम कर रहा है!

आपको बस default-target-url(पृष्ठ-लॉग-इन के बाद पृष्ठ पर ) प्रमाणीकरण की शर्त रखनी होगी : यह उस पृष्ठ के लिए मेरी नियंत्रण विधि है:

@RequestMapping(value = "/monitoring", method = RequestMethod.GET)
public ModelAndView getMonitoringPage(Model model, final HttpServletRequest request) {
    showRequestLog("monitoring");


    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    String userName = authentication.getName();
    //create a new session
    HttpSession session = request.getSession(true);
    session.setAttribute("username", userName);

    return new ModelAndView(catalogPath + "monitoring");
}

और यह मेरा ftl कोड है:

<@security.authorize ifAnyGranted="ROLE_ADMIN, ROLE_USER">
<p style="padding-right: 20px;">Logged in as ${username!"Anonymous" }</p>
</@security.authorize> 

और यही है, प्राधिकरण के बाद हर पेज पर उपयोगकर्ता नाम दिखाई देगा।


जवाब देने की कोशिश करने के लिए धन्यवाद, लेकिन स्थैतिक विधि SecurityContextHolder.getContext () का उपयोग ठीक वही है जो मैं बचना चाहता था, और पहली बार में मैंने यह सवाल पूछा था।
स्कॉट बेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.