2013-03-04 14 views
6

Geri kalan API'ma Spring Security uygulamasını uygulamak için birkaç iş parçacığı takip ettim. Başlangıçta, @Secured annotation'ın göz ardı edilmesine bağlı kaldım, şimdi çözdüğümü anladım, erişim reddedilirken takıldım.@Secured işlevi Erişim yetkili kullanıcı için Reddedildi

Sorunumuma çok benzer geliyor: @secured with granted authorities throws access denied exception - ama yine de erişim reddediliyor. İşte

benim Kurulum:

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

Kontrolör:

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

} 
Şimdi

- olmadan düzgün

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

My isteği (@Secured açıklama göz ardı edilir çünkü bu) geçer. Ben ve "apiuser"/"apiuser" kullanarak erişen koydu, ben erişimi elde tutulur, ayıklama günlüğü yalanladı:

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 

Düşünceler?

Şimdiden teşekkürler!

cevap

19

@Secured ek açıklamasını hatırladığım gibi, yalnızca varsayılan olarak ROLE_ başlayarak rol adları çalışır.

@PreAuthorize("hasAuthority('PERMISSION_TEST')")'a (pre-post-annotations="enabled" ile) geçiş yapabilir veya rolünüzü değiştirebilirsiniz.

+0

awesome - çok teşekkürler! –

+0

Erişimin neden reddedildiğini açıklayan bir yanıt ekledim. –

+0

teşekkürler! iç işleyişi bilmek güzel –

8

Michail Nikolaev'e biraz daha eklemek istiyorum. Cevabım kaynak kod açısından. Erişimin neden reddedildiğini anlamanızı istiyorum. erişime dayalı bir ad yapılandırmayı kullandığınızda

, AccessDecisionManager bir varsayılan örnek sizin için otomatik olarak kaydedilir ve metot çağrımı ve web URL erişimi için erişim kararları için kullanılacaktır: belgelerine

intercept-url ve protect-pointcut bildirimlerinde belirttiğiniz nitelikler (ve ek açıklamalarla güvenli yöntemler kullanıyorsanız). Varsayılan strateji, RoleVoter ve AuthenticatedVoter ile AffirmativeBased AccessDecisionManager kullanmaktır.

RoleVoter o oy kullanabilirsiniz eğer karar vermek için (varsayılan olarak) ROLE_ öneki kullanır. Bu varsayılan öneki RoleVoter.setRolePrefix() yöntemiyle değiştirebilirsiniz.Kaynak kodu itibaren

:

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

karar vermekten ROLE_ yüzden RoleVoter kaçındığı ile başlamaz. AuthenticatedVoter da yok ( @Secured ek açıklamasında IS_AUTHENTICATED_ önekini kullanmadığınız için). Her iki AccessDecisionVoters oylamaya katılmaması nedeniyle

Son olarak, AccessDecisionManager ait AffirmativeBased uygulaması AccessDeniedException atar. AffirmativeBased için

Java docs: Herhangi AccessDecisionVoter olumlu bir yanıt döndürürse erişim izni org.springframework.security.access.AccessDecisionManager ait

Basit somut uygulama.

İlgili konular