2013-03-04 6 views
6

मैंने अपने आराम एपीआई में वसंत सुरक्षा को लागू करने के लिए कुछ धागे का पालन किया है। प्रारंभ में मैं @ सुरक्षित एनोटेशन पर फंस गया हूं, अब मुझे यह हल हो गया है, मैं पहुंच से वंचित हूं।@ सुरक्षित उपयोगकर्ता प्राप्त उपयोगकर्ता के लिए एक्सेस अस्वीकृत

मेरी समस्या की तरह लगता है जैसे ध्वनि: @secured with granted authorities throws access denied exception - लेकिन मुझे अभी भी पहुंच अस्वीकार कर रही है।

यहाँ मेरी सेटअप है:

वसंत-security.xml

<authentication-manager> 
    <authentication-provider user-service-ref="userDetailsService"> 
     <password-encoder ref="passwordEncoder" /> 
    </authentication-provider> 
</authentication-manager> 

<beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.PlaintextPasswordEncoder"/> 

<user-service id="userDetailsService"> 
    <user name="john" password="john1" authorities="ROLE_USER, ROLE_ADMIN" /> 
    <user name="jane" password="jane1" authorities="ROLE_USER" /> 
    <user name="apiuser" password="apiuser" authorities="PERMISSION_TEST" /> 
</user-service> 

नियंत्रक:

@Controller 
@RequestMapping("/secure") 
public class SecureController 
{ 
    private static final Logger logger = Logger.getLogger(SecureController.class); 

    @Secured("PERMISSION_TEST") 
    @RequestMapping(value = "/makeRequest", method = RequestMethod.GET) 
    @ResponseBody 
    public SimpleDTO executeSecureCall() 
    { 
     logger.debug("[executeSecureCall] Received request to a secure method"); 

     SimpleDTO dto = new SimpleDTO(); 
     dto.setStringVariable("You are authorized!"); 

     return dto; 
    } 

} 

अब - बिना उचित

<security:global-method-security secured-annotations="enabled"/> 

मेरे अनुरोध के माध्यम से (इस वजह से @Secured एनोटेशन नजरअंदाज कर दिया है) हो जाता है। जब मैं उस में और "apiuser"/"apiuser" का उपयोग कर उस तक पहुंचने में डाल दिया, मैं पहुँच हो रही है से इनकार किया, डीबग लॉग:

11:42:43,899 [http-apr-8080-exec-4] DEBUG MethodSecurityInterceptor - Previously Authenticated: org.springframew[email protected]cc12af5d: Principal: [email protected]: Username: apiuser; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: PERMISSION_TEST; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: PERMISSION_TEST 

11:42:43,899 [http-apr-8080-exec-4] DEBUG AffirmativeBased - Voter: [email protected], returned: 0 
11:42:43,900 [http-apr-8080-exec-4] DEBUG AffirmativeBased - Voter: [email protected]6ec2, returned: 0 

11:42:43,902 [http-apr-8080-exec-4] DEBUG AnnotationMethodHandlerExceptionResolver - Resolving exception from handler [[email protected]]: org.springframework.security.access.AccessDeniedException: Access is denied 
11:42:43,905 [http-apr-8080-exec-4] DEBUG ResponseStatusExceptionResolver - Resolving exception from handler [[email protected]]: org.springframework.security.access.AccessDeniedException: Access is denied 
11:42:43,906 [http-apr-8080-exec-4] DEBUG DefaultHandlerExceptionResolver - Resolving exception from handler [[email protected]]: org.springframework.security.access.AccessDeniedException: Access is denied 
11:42:43,909 [http-apr-8080-exec-4] DEBUG DispatcherServlet - Could not complete request 
org.springframework.security.access.AccessDeniedException: Access is denied 

विचार?

अग्रिम धन्यवाद!

उत्तर

19

जैसा कि मुझे याद है @Secured एनोटेशन केवल डिफ़ॉल्ट रूप से ROLE_ से शुरू होने वाले भूमिका नामों के साथ काम करता है।

आप @PreAuthorize("hasAuthority('PERMISSION_TEST')") पर स्विच कर सकते हैं (pre-post-annotations="enabled" के साथ) या अपनी भूमिका का नाम बदलें।

+0

भयानक - बहुत बहुत धन्यवाद! –

+0

मैंने उत्तर जोड़ा जो बताता है कि एक्सेस क्यों अस्वीकार कर दी गई थी। –

+0

धन्यवाद! आंतरिक कार्यकलापों को जानना अच्छा है –

8

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

प्रलेखन से

:

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

RoleVoter आदेश अगर यह मतदान कर सकते हैं तय करने के लिए में (डिफ़ॉल्ट रूप से) ROLE_ उपसर्ग का उपयोग करता है। आप RoleVoter.setRolePrefix() विधि के साथ उस डिफ़ॉल्ट उपसर्ग को बदल सकते हैं।

स्रोत कोड से:

public class RoleVoter implements AccessDecisionVoter<Object> { 

(...) 

private String rolePrefix = "ROLE_"; 

(...) 

public void setRolePrefix(String rolePrefix) { 

    this.rolePrefix = rolePrefix; 

} 

(...) 

public boolean supports(ConfigAttribute attribute) { 

    if ((attribute.getAttribute() != null) && 
       attribute.getAttribute().startsWith(getRolePrefix())) { 
     return true; 
    } else { 
     return false; 
    } 
} 

(...) 

public int vote(Authentication authentication, Object object, 
         Collection<ConfigAttribute> attributes) { 
    int result = ACCESS_ABSTAIN; 
    Collection<? extends GrantedAuthority> authorities = 
              extractAuthorities(authentication); 

    for (ConfigAttribute attribute : attributes) { 
     if (this.supports(attribute)) { 
      result = ACCESS_DENIED; 

      // Attempt to find a matching granted authority 
      for (GrantedAuthority authority : authorities) { 
       if (attribute.getAttribute().equals(authority.getAuthority())) { 
        return ACCESS_GRANTED; 
       } 
      } 
     } 
    } 

    return result; 
} 

PERMISSION_TEST निर्णय लेने से ROLE_ तो RoleVoter नहीं खाता के साथ शुरू नहीं करता है। AuthenticatedVoter भी बहुत दूर है (जैसा कि आपने उपसर्ग को @Secured एनोटेशन में उपयोग नहीं किया है)।

अंत में, AffirmativeBasedAccessDecisionManager के कार्यान्वयन AccessDeniedException फेंकता है क्योंकि AccessDecisionVoters दोनों वोटिंग से दूर हैं।

AffirmativeBased के लिए

जावा डॉक्स:

org.springframework.security.access.AccessDecisionManager कि एक्सेस मिल जाती है, यदि कोई हो AccessDecisionVoter सकारात्मक प्रतिक्रिया लौटाता की सरल ठोस कार्यान्वयन।

संबंधित मुद्दे