2

私はサービスインターフェースを持っています

public interface CompoundService<T extends Compound> {

    T getById(final Long id);

    //...
}

および抽象的な実装

public abstract class CompoundServiceImpl<T extends Compound>
        implements CompoundService<T> {

    //...   

    private Class<T> compoundClass;

    //...
}

のすべての実装にCompoundは、拡張する独自のサービスインターフェイスと、拡張CompoundServiceする独自のサービスクラスが必要CompoundServiceImplです。

ここで、のメソッドに基本的なセキュリティuisngアノテーションを追加したいと思いますCompoundService。私が理解している限り、実際の実装ではなく、インターフェースにそれらを追加する必要があります。ユーザーはの実装ごとに異なる役割を持つことができるので、Compoundこれを考慮に入れる必要があります。意味@PreAuthorize私は実装の名前を取得したいと思いCompoundます、例えば。compoundClass.getSimpleName()。だから私は次のようなものを手に入れます:

public interface CompoundService<T extends Compound> {

    @PreAuthorize("hasRole('read_' + #root.this.compoundClass.getSimpleName())")
    T getById(final Long id);

    //...
}

これは基本的にここで言及されていることです:

https://jira.springsource.org/browse/SEC-1640

しかし、例はなく、私は実際に解決策を得ることができませんでした。だから私は使うべきthisですか?または上記のように#root.this

私の2番目の質問は、これは(春から)プロキシによって実装されるインターフェースにあるので、エクスプレッションthis.compoundClassは実際に適切に評価されるのでしょうか?

最後になりましたが、実際にこれをテストするにはどうすればよいですか?*

*私は実際に完成したアプリケーションを作成しているのではなく、特定の種類のデータベース検索用のフレームワークなど、構成可能なものを作成しています。つまり、ほとんどの承認と認証は実装者からのものでなければなりません。

4

1 に答える 1

2
  1. ユニットテスト

http://www.lancegleason.com/blog/2009/12/07/unit-testing-spring-security-with-annotationsを参照してください

これは古いチュートリアルなので、参照されるスキーマのバージョンを変更する必要があるかもしれません。ただし、さらに重要なのは、そこに示されているSecurityContext.xml構成がSpringSecurity3では機能しないことです。適切な構成についてはSpringSecurity-複数の認証プロバイダーを参照してください。

私は言及された依存関係を必要としませんでした:

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core-tiger</artifactId>
</dependency>

それらがなくても機能しました(ただし、抽象的なテストクラスは作成されませんでした)

  1. root.this

これは実際には正しいアプローチです

問題は、クラスパラメータのgetSimpleName()を使用できないことです。詳細については、http://forum.springsource.org/showthread.php?98570-Getting-Payload-Classname-in-Header-Enricher-via-SpELを参照してください。

そこに示されている回避策はあまり役に立ちませんでした。だから私はこの非常に単純な解決策を思いついた:

文字列プロパティString compoundClassSimpleNameをに追加CompoundServiceImplし、コンストラクター(サブクラスによって呼び出される)に設定するだけです。

Public abstract class CompoundServiceImpl<T extends Compound>
    implements CompoundService<T> {
    
    private String compoundClassSimpleName;

    //...
    
    public ChemicalCompoundServiceImpl(Class<T> compoundClass) {
        this.compoundClass = compoundClass;
        this.compoundClassSimpleName = compoundClass.getSimpleName();
    }
    
    //...
    
    public String getCompoundClassSimpleName(){
        return compoundClassSimpleName;
    }   
}

そして彼女は上記の抽象的なサービスを実装するサービス:

public class TestCompoundServiceImpl extends CompoundServiceImpl<TestCompound>
        implements TestCompoundService {

    //...   

    public TestCompoundServiceImpl() {
        super(TestCompound.class);
    }
    
    //...   
    
}

そして最後に@PreAuthorize注釈の使用法:

public interface CompoundService<T extends Compound> {

    @PreAuthorize("hasRole('read_' + #root.this.getCompoundClassSimpleName())")
    public T getById(final Long id);
}

上記の例では、式は「read_TestCompound」という名前のロールに評価されます。

終わり!

多くの場合、解決策は非常に単純ですが、そこに到達するにはPITAがあります...

編集:

完全を期すために、テストクラス:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
        "classpath:ApplicationContext.xml",
        "classpath:SecurityContext.xml"
        })
public class CompoundServiceSecurityTest {

    @Autowired
    @Qualifier("testCompoundService")
    private TestCompoundService testCompoundService;

    public CompoundServiceSecurityTest() {
    }
    

    @Before
    public void setUp() {
        SecurityContextHolder.getContext().setAuthentication(
            new UsernamePasswordAuthenticationToken("user_test", "pass1"));
    }

     @Test
     public void testGetById() {
        System.out.println("getById");
        Long id = 1000L;
        TestCompound expResult = new TestCompound(id, "Test Compound");
        TestCompound result = testCompoundService.getById(id);
        assertEquals(expResult, result);
     }
}
于 2013-02-21T14:07:53.263 に答える