5

アノテーションをテストするためのサンプルクラスが@PreAuthorizeあります。これは多かれ少なかれ次のようになります。

class BankService {

    @PreAuthorize("hasCustomRole('ROLE_CUSTOM') or hasRole('ROLE_EXAMPLE')")
    Double getAccountBalance(Integer accountNumber) {
        return 1234;
    }

    @PreAuthorize("#accountNumber > 400")
    int getValue(Integer accountNumber) {
        return 1234;
    }
}

あなたは私が追加している注釈でhasCustomRole(String expression)気付くことができます:@PreAuthorize

public class CustomSecurityExpressionRoot extends SecurityExpressionRoot {

    public CustomSecurityExpressionRoot(Authentication auth) {
        super(auth);
    }

    public boolean hasCustomRole(String expression) {
       return /* some magic */;
    }
}

また、私はDefaultMethodSecurityExpressionHandler次のように拡張しています:

public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {

    public CustomMethodSecurityExpressionHandler() {
        super();
    }

    @Override
    public EvaluationContext createEvaluationContext(Authentication auth, MethodInvocation mi) {
        StandardEvaluationContext ctx = (StandardEvaluationContext) super.createEvaluationContext(auth, mi);
        ctx.setRootObject(new CustomSecurityExpressionRoot(auth));
        return ctx;
    }
}

結局、すべてが包まれていresources.groovyます:

beans = {
  /* ... some stuff ... */

  xmlns security:'http://www.springframework.org/schema/security'

  security.'global-method-security'('pre-post-annotations': 'enabled') {
    security.'expression-handler'(ref: 'expressionHandler')
  }

  expressionHandler(my.package.plugin.security.expression.CustomMethodSecurityExpressionHandler)
}

ここで、からセキュリティ部分を削除すると、resources.groovy当然、hasCustomRole()メソッドを使用できなくなりますが、次のように機能します。

assert bankService.getValue(500) == 1234

しかし、私が自分の実装を注入すると、前のステートメントは次のようになります。

Access is denied
org.springframework.security.access.AccessDeniedException: Access is denied

さらに調査した後、私はこれを見つけました:

prepost.PrePostAnnotationSecurityMetadataSource Looking for Pre/Post annotations for method 'getValue' on target class 'class my.package.plugin.security.test.BankService'
prepost.PrePostAnnotationSecurityMetadataSource @org.springframework.security.access.prepost.PreAuthorize(value=#accountNumber > 400) found on specific method: public int my.package.plugin.security.test.BankService.getValue(java.lang.Integer)
method.DelegatingMethodSecurityMetadataSource Adding security method [CacheKey[my.package.plugin.security.test.BankService; public int my.package.plugin.security.test.BankService.getValue(java.lang.Integer)]] with attributes [[authorize: '#accountNumber > 400', filter: 'null', filterTarget: 'null']]
aopalliance.MethodSecurityInterceptor Secure object: ReflectiveMethodInvocation: public int my.package.plugin.security.test.BankService.getValue(java.lang.Integer); target is of class [my.package.plugin.security.test.BankService$$EnhancerByCGLIB$$c590f9ac]; Attributes: [[authorize: '#accountNumber > 400', filter: 'null', filterTarget: 'null']]
aopalliance.MethodSecurityInterceptor Previously Authenticated: org.springframework.security.authentication.TestingAuthenticationToken@b35bafc3: Principal: test; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_TELLER
method.MethodSecurityEvaluationContext Unable to resolve method parameter names for method: public final int my.package.plugin.security.test.BankService$$EnhancerByCGLIB$$c590f9ac.getValue(java.lang.Integer). Debug symbol information is required if you are using parameter names in expressions.

興味深い部分はですDebug symbol information is required if you are using parameter names in expressions.。これは、クラスが変数名に関するデバッグ情報なしでコンパイルされることを示唆しています。しかし、自分のBeanを注入しなければ、すべてが正常に機能します。

デバッグ情報が欠落している理由と、それを修正する方法は何でしょうか。

これは、Grails 2.0.4用に開発されたGrailsプラグインであり、バージョン1.2.7.3のspring-security-coreプラグイン、バージョン1.1のspring-security-aclプラグイン、およびSpringSecurity3.0.7.RELEASEを使用しています。

編集:

この問題をさらに面白くするために、これは後で私が発見したものです。。を使用して.classファイルを調べると、「欠落している」デバッグ情報が実際に存在しますjavap。したがって、クラスは正しくコンパイルされますが、Springはとにかく文句を言います...

4

1 に答える 1

0

問題を修正しましたが、取得していたログの例外とメッセージが問題から遠く離れている理由が正確にはわかりません。

grails-app/conf/spring/resources.groovyGrailsで構築されたアプリケーションと同じように使用できると仮定して1つの間違いをしました。resources.groovyまた、ドキュメントには、で構成されたBeanがこの場合は機能しないと明示的に記載されていませんが、 resources.groovy(他のいくつかのファイルの中でも)デフォルトでパッケージから除外されると記載されています。

テストの実行中の奇妙な動作については説明していませんが、この種の構成には適していません。

Spring Security構成をからresources.groovyプラグイン記述子に移動した後、次のようにします。

class MyOwnGrailsPlugin {

  /* ... some stuff ... */

  def doWithSpring = {
    /* ... some spring stuff ... */

    xmlns security:'http://www.springframework.org/schema/security'

    security.'global-method-security'('pre-post-annotations': 'enabled') {
      security.'expression-handler'(ref: 'expressionHandler')
    }

    expressionHandler(my.package.plugin.security.expression.CustomMethodSecurityExpressionHandler)
  }
}

すべてが正常に機能し、テストに合格します。

于 2012-12-01T21:49:11.467 に答える