8

@RequestBodySpring Securityでを保護する適切な方法は何ですか?

例:AUserは複数のsを持つことができBlog、それぞれが複数のsを持つことができます。ユーザーが特定のブログへのエントリを保存しようとすると、リクエストは次のようになります。BlogEntry

@RequestMapping(value="/api/entry", method=RequestMethod.POST)
@ResponseBody
public Entry save(@Valid @RequestBody Entry entry) {
    this.entryService.save(entry);
    return entry;
}

これで、着信entryにはがありBlog、ユーザーはリクエストを修正して他の誰かのブログを選択し、そのエントリを自分のブログに効果的に投稿することができます。検証でこれをキャッチすることはできましたが(永続層をクエリしてBlog、がログインに属していることを確認しますUser)、これはSpringSecurityで処理する必要があると思います。もしそうなら、どうすればこれを行うことができますか?

4

1 に答える 1

10

このような状況でした。

これが2つの解決策です。あまり好きではなかった

@RequestMapping(value="/api/entry", method=RequestMethod.POST)
@ResponseBody
@PreAuthorize("#entry.author.name == principal.name)"
public Entry save(@Valid @RequestBody Entry entry, Principal principal) {
    this.entryService.save(entry);
    return entry;
} 

また

@RequestMapping(value="/api/entry", method=RequestMethod.POST)
    @ResponseBody
    @PreAuthorize("Decision.isOK(entry, principal)")
    public Entry save(@Valid @RequestBody Entry entry, Principal principal) {
        this.entryService.save(entry);
        return entry;
    }

//その場合、SpringはDecisionクラスから静的isOk()メソッドを呼び出します。ブール値を返す必要があります。

Springは、メソッドのプリンシパルプリンシパル許可オブジェクトを注入します。心配する必要はありません。@PreAuthorize注釈を有効にする

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

2番目のアスペクトの使用。アスペクトを作成します。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Protector {
}

@Aspect
@Component
public class MyAspect {
   @Before("@annotation(com.xyz.Protector)")
   public void before(JoinPoint joinPoint) throws Throwable {
        //u can get method object from joinPoint object, 
        Method method = ((MethodSignature)joinPoint.getMethodSignature()).getMethod();
        //As long as you have Method object you can read the parameter objects (Entry and Principal) with reflection. 
        //So Compare here: If entry.getOwner().getId().equal(principal.getName()) blah blah blah  
    }
}

@RequestMapping(value="/api/entry", method=RequestMethod.POST)
@ResponseBody
@Protector
public Entry save(@Valid @RequestBody Entry entry, Principal principal) {
    this.entryService.save(entry);
    return entry;
} 

あなたがアスペクトを持っているなら、あなたは実行時にもっと所有することができます

このulrも参照してください

于 2012-09-27T01:02:27.310 に答える