Spring Securityは@PreAuthorize
Springコントローラーメソッドの場合
はい、正常に動作します。
<security:global-method-security pre-post-annotations="enabled" />
に...-servlet.xml
が必要です。また、 CGLIBプロキシ が必要なため、コントローラーにインターフェイスがないか、proxy-target-class = true
を使用する必要があります。
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>
アプリのセキュリティコンテキスト内。
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()を呼び出します。
この質問が出されてから2年以上が経ちましたが、今日の問題のために@Secured
、@PreAuthorize
など@Controller
s。
うまくいかなかったのは@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>
Xml構成を変更して機能させる方法については既に回答があります。ただし、コードベースの構成で作業している場合は、@Configuration
クラス:
@EnableGlobalMethodSecurity(prePostEnabled=true)
Andyが提供する回答を拡張するには、次を使用できます。
@PreAuthorize("hasRole('foo')")
特定の役割を確認します。
最初に、このアノテーションをWebSecurityConfigに追加して、@ Preおよび@Postアノテーションを有効にする必要があります。
@EnableGlobalMethodSecurity(prePostEnabled = true)
次のようにロール/権限を確認することもできます
@PreAuthorize("hasAuthority('ROLE_ADMIN')")
に相当
@PreAuthorize("hasRole('ROLE_ADMIN')")
次のように複数のロール/権限を確認することもできます
@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER') or ...")