web-dev-qa-db-ja.com

Spring Securityは、Springコントローラのメソッドで@PreAuthorizeを使用できますか?

Spring Securityは@PreAuthorize Springコントローラーメソッドの場合

71
egervari

はい、正常に動作します。

<security:global-method-security pre-post-annotations="enabled" />...-servlet.xmlが必要です。また、 CGLIBプロキシ が必要なため、コントローラーにインターフェイスがないか、proxy-target-class = trueを使用する必要があります。

68
axtavt

Spring Security FAQ (emphasis mine)を参照してください。

Spring Webアプリケーションでは、ディスパッチャサーブレットのSpring MVC Beanを保持するアプリケーションコンテキストは、メインアプリケーションコンテキストから分離されていることがよくあります。多くの場合、myapp-servlet.xmlというファイルで定義されます。ここで、「myapp」はweb.xmlでSpring DispatcherServletに割り当てられた名前です。アプリケーションは複数のDispatcherServletを持つことができ、それぞれに独自の分離されたアプリケーションコンテキストがあります。これらの「子」コンテキストのBeanは、アプリケーションの他の部分からは見えません。 「親」アプリケーションコンテキストは、web.xmlで定義したContextLoaderListenerによってロードされ、すべての子コンテキストに表示されます。この親コンテキストは通常​​、要素を含むセキュリティ構成を定義する場所です。その結果、これらのWeb Beanのメソッドに適用されるセキュリティ制約は適用されません。これは、BeanがDispatcherServletコンテキストから見えないためです。宣言をWebコンテキストに移動するか、保護するBeanをメインアプリケーションコンテキストに移動する必要があります。

一般に、個々のWebコントローラーではなく、サービス層でメソッドセキュリティを適用することをお勧めします。

サービスレイヤーにポイントカットを適用する場合は、<global-method-security>アプリのセキュリティコンテキスト内。

23
Tomasz

Spring 3.1を使用している場合は、これを使用してかなりクールなことができます。 https://github.com/mohchi/spring-security-request-mapping をご覧ください。 @PreAuthorizeとSpring MVCのRequestMappingHandlerMappingを統合するサンプルプロジェクトであるため、次のようなことができます。

@RequestMapping("/")
@PreAuthorize("isAuthenticated()")
public String authenticatedHomePage() {
    return "authenticatedHomePage";
}

@RequestMapping("/")
public String homePage() {
    return "homePage";
}

ユーザーが認証された場合、「/」のリクエストは、authenticateHomePage()を呼び出します。それ以外の場合、homePage()を呼び出します。

17
andy

この質問が出されてから2年以上が経ちましたが、今日の問題のために@Secured@PreAuthorizeなど@Controllers。

うまくいかなかったのは@Validated と組み合わせ @Securedコントローラー:

@Controller
@Secured("ROLE_ADMIN")
public class AdministrationController {

// @InitBinder here...

@RequestMapping(value = "/administration/add-product", method = RequestMethod.POST)
public String addProductPost(@ModelAttribute("product") @Validated ProductDto product, BindingResult bindingResult) {
    // ...
}

Validatorは起動せず(Spring MVC 4.1.2、Spring Security 3.2.5)、チェックは実行されません。

同様の問題は、Springが使用するCGLIBプロキシが原因で発生します(クラスに実装されたインターフェイスがない場合、SpringはCGLIBプロキシを作成します。クラスにインターフェイスが実装されている場合、JDKプロキシが生成されます- ドキュメント詳細はこちら および こちら )。

上記のリンクの回答で述べたように、通常はインターフェイスを実装するサービスレイヤーでSpring Securityアノテーションを使用する方がよい(JDKプロキシが使用される)ので、このような問題は発生しません。

Webコントローラーを保護する場合は、<http>および<intercept-url />は、コントローラーのメソッドではなく特定のURLにバインドされており、非常にうまく機能します。私の場合:

<http use-expressions="true" disable-url-rewriting="true">

    ...

    <intercept-url pattern="/administration/**" access="hasRole('ROLE_ADMIN')" />

</http>
9
dominik

Xml構成を変更して機能させる方法については既に回答があります。ただし、コードベースの構成で作業している場合は、@Configurationクラス:

@EnableGlobalMethodSecurity(prePostEnabled=true)
5
OlgaMaciaszek

Andyが提供する回答を拡張するには、次を使用できます。

@PreAuthorize("hasRole('foo')")

特定の役割を確認します。

1
Atul

最初に、このアノテーションをWebSecurityConfigに追加して、@ Preおよび@Postアノテーションを有効にする必要があります。

    @EnableGlobalMethodSecurity(prePostEnabled = true)

次のようにロール/権限を確認することもできます

    @PreAuthorize("hasAuthority('ROLE_ADMIN')")

に相当

    @PreAuthorize("hasRole('ROLE_ADMIN')")

次のように複数のロール/権限を確認することもできます

    @PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER') or ...")
0
Siddhey Sankhe