使用 @RolesAllowed 和 @PreAuthorize 保护控制器方法 [英] Securing controller method with @RolesAllowed and @PreAuthorize

查看:17
本文介绍了使用 @RolesAllowed 和 @PreAuthorize 保护控制器方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在为这个问题头痛一段时间.为了找到合适的解决方案,我已尽我所能,并遵循了大量 Stackoverflow 示例和解决方案.

I've been banging my head over this one for a while now. I've done everything I could in order to find an appropriate solution and followed a lot of Stackoverflow examples and solutions.

首先,我使用基于注释的解决方案.当我注释我的服务时,prePostEnabled 起作用,但当我注释控制器时则不起​​作用.此外,即使在我的服务上,jsr250Enabled 也不起作用.

First, I'm using annotation based solution. When I annotate my services, prePostEnabled works, but not when I annotate the controllers, it doesn't. Also, even on my services, jsr250Enabled doesn't work.

通过将注释从安全配置移动到 MVC 配置,我发现了很多案例,这在我的案例中不起作用.

I've found a lot of case closed by moving the annotation from the security config to the MVC config, which in my case doesn't work.

我的设置如下所示:https://github.com/spring-projects/spring-security-oauth-javaconfig/tree/master/samples/oauth2-sparklr

但我使用 Servlet 3.0,并且在我的 web.xml 中没有任何内容.

But I use Servlet 3.0 and doesn't have anything in my web.xml.

我的 SecurityInitializer 看起来像这样:

My SecurityInitializer looks like this:

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
}

我的 MVC 初始值设定项如下所示:

My MVC initializer looks like this:

public class MvcWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[]{WebSecurityConfig.class, MethodSecurityConfig.class};
}

@Override
protected Class<?>[] getServletConfigClasses() {
    return new Class<?>[]{SpringMvcConfig.class};
}

@Override
protected String[] getServletMappings() {
    return new String[]{ApiPaths.API + "/*", "/res.jsp"};
}

我的网络安全配置初始化如下:

My WebSecurity config is initialized like this:

@Configuration
@EnableWebSecurity
@ComponentScan(value = {"com.roler.res.**.server"}, excludeFilters = {
    @Filter(type = FilterType.ASSIGNABLE_TYPE, value = SpringMvcConfig.class),
    @Filter(type = FilterType.ASSIGNABLE_TYPE, value = MethodSecurityConfig.class),
    @Filter(type = FilterType.REGEX, pattern = "com.xyz.*.controller.*")})
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

我的 SpringMvcConfig 是这样初始化的:

And my SpringMvcConfig is initialized like this:

@Configuration
@EnableWebMvc
@ComponentScan(value = "com.xyz.**.controller")
public class SpringMvcConfig extends WebMvcConfigurerAdapter {

如果你有任何想法,我已经没力气了,谢谢!

If you have any ideas, I'm out of juice, Thanks!

推荐答案

你描述的症状让我想到了代理问题.注解在服务层很好用,因为服务一般都会实现接口,Spring可以很方便的使用JDK代理来放置AOP授权.

The symptoms you describe make me think to a problem of proxying. Annotations works fine on service layer, because services generally implements interfaces, and Spring can easily use a JDK proxy to put the AOP authorizations.

但是控制器一般不实现接口.这就是为什么 PreAuthorize 注解在服务层使用的频率更高的原因.恕我直言,您最好尝试在控制器上使用基于 URL 模式的授权而不是 PreAuthorize 注释.另一种方法是使用带有 CGLIB 的目标类代理.

But controllers generally do not implement interfaces. That's the reason why PreAuthorize annotation are more frequently used in service layer. IMHO, you'd better try to use URL pattern based authorization instead of PreAuthorize annotations on controller. The alternative would be to use target class proxying with CGLIB.

要使用 PreAuthorize 和 JSR-250 注释,您必须

To use PreAuthorize and JSR-250 annotations, you must

@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)

  • 如果您在应用程序中的任何其他地方使用带有 JDK 代理的 Spring AOP,请让所有要使用方法安全性的控制器类实现声明所有受保护方法的接口

  • if you use anywhere else in your application Spring AOP with JDK proxies, make all controller classes in which you want to use method security implement interfaces declaring all protected methods

    如果您在应用程序中的任何其他地方使用带有 CGLIB 代理的 Spring AOP,请将 proxyTargetClass = true 添加到 @EnableGlobalMethodSecurity :

    if you use anywhere else in your application Spring AOP with CGLIB proxies, add proxyTargetClass = true to @EnableGlobalMethodSecurity :

    @EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true,
            proxyTargetClass = true)
    

  • 如果您想在 Spring 3.2 版本以下使用 CGLIB 代理,请将 CGLIB 库添加到您的类路径(CGLIB 类包含在 Spring 3.2+ 中)

  • if you want to use CGLIB proxies with Spring version under 3.2, add CGLIB library to your classpath (CGLIB classes are included in Spring 3.2+)

    但无论如何,我的建议是尝试将方法安全性转移到通常已经支持 AOP 的服务层.

    But anyway, my advice is to try to move method security to service layer which normally already supports AOP.

    这篇关于使用 @RolesAllowed 和 @PreAuthorize 保护控制器方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆