2013-03-04 10 views
6

私は、残りのAPIにSpring Securityを実装するためにかなりのスレッドを実行しました。最初は、@Securedアノテーションが無視されてしまいました。これで解決されました。アクセスが拒否されてしまいました。@Secured関数は、許可されたユーザに対してアクセス拒否を受け取ります。

私の問題は、@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

私はMichail Nikolaevの答えにもう少し追加したいと思います。 私の答えは、ソースコードの観点からです。アクセスが拒否された理由を理解していただきたい。ドキュメントから

:あなたが名前空間の構成を使用する場合

、AccessDecisionManagerのデフォルトインスタンスが自動的に登録されており、アクセスに基づいて、メソッド呼び出しとWeb URLへのアクセスのためのアクセスの決定を行うために使用されますintercept-urlおよびprotect-pointcut宣言(および注釈保護メソッドを使用している場合は注釈)で指定する属性。 デフォルトの戦略は、RoleVoterとAuthenticatedVoterでAffirmativeBased 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 abstains too 接頭辞を@Secured注釈に使用していないためです。

最後に、AccessDecisionManagerの実装では、AccessDecisionVotersの両方が投票から拒否されたため、AccessDeniedExceptionがスローされます。 AffirmativeBasedため

のJavaドキュメント:任意のAccessDecisionVoterが肯定的な応答を返す場合 アクセスを許可 org.springframework.security.access.AccessDecisionManagerの

シンプルな具体的な実装。

関連する問題