6

Spring Security を残りの API に実装するために、かなりの数のスレッドをたどってきました。最初は@Securedアノテーションが無視されて行き詰まりましたが、それが解決されたので、アクセスが拒否されて行き詰まりました。

私の問題は非常に似ているように聞こえます: @secured with grant authority がアクセス拒否の例外をスローしますが、それでもアクセスが拒否されます。

これが私のセットアップです:

spring-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.springframework.security.authentication.UsernamePasswordAuthenticationToken@cc12af5d: Principal: org.springframework.security.core.userdetails.User@d059c8e5: Username: apiuser; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: PERMISSION_TEST; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: PERMISSION_TEST

11:42:43,899 [http-apr-8080-exec-4] DEBUG AffirmativeBased - Voter: org.springframework.security.access.vote.RoleVoter@2a9a42ef, returned: 0
11:42:43,900 [http-apr-8080-exec-4] DEBUG AffirmativeBased - Voter: org.springframework.security.access.vote.AuthenticatedVoter@75a06ec2, returned: 0

11:42:43,902 [http-apr-8080-exec-4] DEBUG AnnotationMethodHandlerExceptionResolver - Resolving exception from handler [com.test.webapp.spring.controller.SecureController@342d150f]: org.springframework.security.access.AccessDeniedException: Access is denied
11:42:43,905 [http-apr-8080-exec-4] DEBUG ResponseStatusExceptionResolver - Resolving exception from handler [com.test.webapp.spring.controller.SecureController@342d150f]: org.springframework.security.access.AccessDeniedException: Access is denied
11:42:43,906 [http-apr-8080-exec-4] DEBUG DefaultHandlerExceptionResolver - Resolving exception from handler [com.test.webapp.spring.controller.SecureController@342d150f]: 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

考え?

前もって感謝します!

4

2 に答える 2

25

私が覚えているように@Secured、注釈はデフォルトで始まるロール名でのみ機能 ROLE_します。

に切り替えるか、役割の名前を変更できます@PreAuthorize("hasAuthority('PERMISSION_TEST')")pre-post-annotations="enabled"

于 2013-03-04T17:06:58.973 に答える
8

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

ドキュメントから:

名前空間構成を使用すると、AccessDecisionManager のデフォルト インスタンスが自動的に登録され、intercept-url および protect-pointcut 宣言で指定したアクセス属性に基づいて、メソッド呼び出しと Web URL アクセスのアクセス決定を行うために使用されます。 (および、アノテーションで保護されたメソッドを使用している場合はアノテーション内)。デフォルトの戦略は、AffirmativeBased AccessDecisionManager を RoleVoter および AuthenticatedVoter とともに使用することです。

RoleVoterROLE_投票できるかどうかを決定するために、プレフィックス (デフォルト) を使用します。メソッドでそのデフォルトの接頭辞を変更できます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も棄権します(注釈IS_AUTHENTICATED_で接頭辞を使用していないため)。@Secured

最後に、両方とも投票を棄権したため、スローAffirmativeBasedの実装。AccessDecisionManagerAccessDeniedExceptionAccessDecisionVoters

の Java ドキュメントAffirmativeBased:

いずれかの AccessDecisionVoter が肯定応答を返した場合にアクセスを許可する org.springframework.security.access.AccessDecisionManager の単純で具象的な実装。

于 2013-03-04T18:10:22.273 に答える