预授权不起作用

2024-01-31

我正在编写一个套接字服务器(无 Web 应用程序!)应用程序,并希望使用基于方法的安全性来处理我的 ACL 需求。我按照我发现的一个小教程进行操作春季安全举例 http://blog.solidcraft.eu/2011/03/spring-security-by-example-securing.html

到目前为止我配置:

<security:global-method-security pre-post-annotations="enabled">
    <security:expression-handler ref="expressionHandler" />
</security:global-method-security>
<bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
    <property name="permissionEvaluator">
        <bean id="permissionEvaluator" class="myPermissionEvaluator" />
    </property>
</bean>

<security:authentication-manager id="authenticationmanager">
    <security:authentication-provider ref="authenticationprovider" />
</security:authentication-manager>
<bean id="authenticationprovider" class="myAuthenticationProvider" />

使用服务 bean:

@Named
public class ChannelService {
    @PreAuthorize("isAuthenticated() and hasPermission(#channel, 'CHANNEL_WRITE')")
    public void writeMessage(Channel channel, String message) { ... }
}

一切都编译完毕,应用程序启动并正常工作,但没有访问控制。我的调试日志显示我的评估器从未被调用。

当我尝试类似的东西时@Secured注释 注释已被评估并且访问被拒绝。但简单的基于角色的安全性不足以满足我的要求。

EDIT做了更多测试:当我仅配置 secure-annotations="enabled" 时,基于角色的安全性有效。当在 ADDITION 中配置 pre-post-annotations="enabled" 时,安全和预授权都不起作用。当我仅配置前后注释时,它仍然不起作用。

EDIT2

更多测试: 仅 secure_annotations="enabled" 对我的通道服务的调用通过 Cglib2AopProxy 一旦我激活前后注释,呼叫就会直接进入通道服务。没有拦截器,没有代理,什么都没有。

我有点绝望了...

EDIT3

我在这里调试记录了我的测试运行是 spring-security 的部分

仅使用 secure-annotations="enabled"

2012-04-12 13:36:46,171 INFO  [main] o.s.s.c.SpringSecurityCoreVersion - You are running with Spring Security Core 3.1.0.RELEASE
2012-04-12 13:36:46,174 INFO  [main] o.s.s.c.SecurityNamespaceHandler - Spring Security 'config' module version is 3.1.0.RELEASE
2012-04-12 13:36:49,042 DEBUG [main] o.s.s.a.m.DelegatingMethodSecurityMetadataSource - Caching method [CacheKey[mystuff.UserService; public void mystuff.UserService.serverBan(java.lang.String,mystuff.models.User,org.joda.time.DateTime)]] with attributes [user]
2012-04-12 13:36:49,138 DEBUG [main] o.s.s.a.i.a.MethodSecurityInterceptor - Validated configuration attributes
2012-04-12 13:36:49,221 DEBUG [main] o.s.s.a.m.DelegatingMethodSecurityMetadataSource - Caching method [CacheKey[mystuff.ChannelService; public void mystuff.ChannelService.writeMessage(mystuff.models.Channel,java.lang.String)]] with attributes [blubb]
2012-04-12 13:36:51,159 DEBUG [main] o.s.s.a.ProviderManager - Authentication attempt using mystuff.GlobalchatAuthenticationProvider
2012-04-12 13:36:56,166 DEBUG [Timer-1] o.s.s.a.ProviderManager - Authentication attempt using mystuff.GlobalchatAuthenticationProvider
2012-04-12 13:36:56,183 DEBUG [Timer-1] o.s.s.a.i.a.MethodSecurityInterceptor - Secure object: ReflectiveMethodInvocation: public void mystuff.ChannelService.writeMessage(mystuff.models.Channel,java.lang.String); target is of class [mystuff.ChannelService]; Attributes: [blubb]
2012-04-12 13:36:56,184 DEBUG [Timer-1] o.s.s.a.i.a.MethodSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@312e8aef: Principal: mystuff.UserId@ced1752b; Credentials: [PROTECTED]; Authenticated: true; Details: null; Not granted any authorities
Exception in thread "Timer-1" org.springframework.security.access.AccessDeniedException: Access is denied
    at org.springframework.security.access.vote.AbstractAccessDecisionManager.checkAllowIfAllAbstainDecisions(AbstractAccessDecisionManager.java:70)
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:88)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:205)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:59)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
    at mystuff.ChannelService$$EnhancerByCGLIB$$3ad5e57f.writeMessage(<generated>)
    at mystuff.run(DataGenerator.java:109)
    at java.util.TimerThread.mainLoop(Timer.java:512)
    at java.util.TimerThread.run(Timer.java:462)
2012-04-12 13:36:56,185 DEBUG [Timer-1] o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.RoleVoter@1cfe174, returned: 0
2012-04-12 13:36:56,185 DEBUG [Timer-1] o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.AuthenticatedVoter@da89a7, returned: 0

与 pre-post-annotations="enabled"

2012-04-12 13:39:54,926 INFO  [main] o.s.s.c.SpringSecurityCoreVersion - You are running with Spring Security Core 3.1.0.RELEASE
2012-04-12 13:39:54,929 INFO  [main] o.s.s.c.SecurityNamespaceHandler - Spring Security 'config' module version is 3.1.0.RELEASE
2012-04-12 13:39:54,989 INFO  [main] o.s.s.c.m.GlobalMethodSecurityBeanDefinitionParser - Using bean 'expressionHandler' as method ExpressionHandler implementation
2012-04-12 13:39:59,812 DEBUG [main] o.s.s.a.ProviderManager - Authentication attempt mystuff.GlobalchatAuthenticationProvider
2012-04-12 13:39:59,850 DEBUG [main] o.s.s.a.i.a.MethodSecurityInterceptor - Validated configuration attributes

据我了解,这个日志输出 spring 没有意识到我的 bean 需要被代理,所以它们不是,所以我没有得到安全性。

EDIT4

我调试记录了完整的冲刺启动...(这是一大日志),我发现:

2012-04-12 14:40:41,385 INFO [main] o.s.c.s.ClassPathXmlApplicationContext - Bean 'channelService' of type [class mystuff.ChannelService] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

有办法找出原因吗?因为据我了解。因为@preauthorize,bean 应该是合格的。仅使用 secure-annotations="enabled" 我得到一个后处理日志。


这个配置对我来说正如预期的那样:

<bean id="securityExpressionHandler"
    class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler" /> 

<bean id="preInvocationAdvice"
    class="org.springframework.security.access.expression.method.ExpressionBasedPreInvocationAdvice"
    p:expressionHandler-ref="securityExpressionHandler" />

<util:list id="decisionVoters">
    <bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
    <bean class="org.springframework.security.access.vote.RoleVoter" />
    <bean class="org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter"
        c:pre-ref="preInvocationAdvice" />
</util:list>

<bean id="accessDecisionManager"
    class="org.springframework.security.access.vote.UnanimousBased"
    c:decisionVoters-ref="decisionVoters" />

<sec:global-method-security
    authentication-manager-ref="authenticationManager"
    access-decision-manager-ref="accessDecisionManager"
    pre-post-annotations="enabled" />

我收到日志消息:

WARN  org.springframework.security.access.expression.DenyAllPermissionEvaluator - 
    Denying user jack permission 'CHANNEL_WRITE' on object Channel[ name=null ]

还有一个例外:

org.springframework.security.access.AccessDeniedException: Access is denied

从一个简单的测试来看:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:META-INF/spring/application-context.xml")
public class SpringSecurityPrePostTest {

    @Autowired
    ChannelService channelService;

    @Test
    public void shouldSecureService() throws Exception {
        Authentication authentication = new UsernamePasswordAuthenticationToken("jack", "sparrow");
        SecurityContext securityContext = SecurityContextHolder.getContext();
        securityContext.setAuthentication(authentication);

        channelService.writeMessage(new Channel(), "test");
    }
}

我做了一件事,使用服务和 JDK 代理上的接口而不是 cglib 来使用不同的方法:

public interface ChannelService {

    void writeMessage(Channel channel, String message);
}

and:

@Component
public class ChannelServiceImpl implements ChannelService {

    private static final Logger LOG = LoggerFactory.getLogger(ChannelServiceImpl.class);

    @Override
    @PreAuthorize("isAuthenticated() and hasPermission(#channel, 'CHANNEL_WRITE')")
    public void writeMessage(Channel channel, String message) {
        LOG.info("Writing message {} to: {}" , message, channel);
    }

}

UPDATE1:


通过这个简化的配置,我得到了相同的结果:

<bean id="securityExpressionHandler"
    class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler" /> 

<sec:global-method-security
    authentication-manager-ref="authenticationManager"
    pre-post-annotations="enabled">
    <sec:expression-handler ref="securityExpressionHandler" />
</sec:global-method-security>

UPDATE2:


来自 Edit4 的调试消息表明channelService可能根本没有 bean 代理,因为它被分类为not eligible for auto-proxying http://www.google.pl/#q=not+eligible+for+auto-proxying. 这个问题 https://stackoverflow.com/questions/1201726/tracking-down-cause-of-springs-not-eligible-for-auto-proxying回答类似的问题 - 尽量不要使用@Autowired或任何其他基于的机制BeanPostProcessors设置参与安全检查的 Bean(即myPermissionEvaluator).


UPDATE3:


You cannot在负责安全检查的 bean 中使用安全资源(即服务)!这会创建一个依赖循环,并且是您的配置中的错误。你must使用情人级别访问(即 DAO)来检查权限,任何不安全!使用受保护的资源实施安全检查是不是你想做的.

如果尽管使用不安全的资源@Autowired事情没有按预期工作,请尝试对涉及安全检查的所有 bean 使用老式 XML 配置样式。还请记住<context:component-scan />实际上是一个BeanDefinitionRegistryPostProcessor并将扫描的bean引入BeanFactory毕竟 XML 中声明的所有内容都已存在。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

预授权不起作用 的相关文章

随机推荐

  • ionic 2 ion-select - 以编程方式关闭选择框

    我正在从事 ionic2 项目 我使用离子选择元件 我搜索一种在选择任何项目时以编程方式关闭选择框的方法 而不是等待用户按 确定
  • 处理无效的 XML 十六进制字符

    我尝试通过网络发送 XML 文档 但收到以下异常 MY LONG EMAIL STRING was specified for the Body element amp gt System ArgumentException x2 hexa
  • 自定义数据集和数据加载器

    我是 pytorch 的新手 我有一个大数据集 由两个 txt 文件组成 一个用于数据 另一个用于目标数据 在训练文件中 每行是长度为 340 的列表 在目标中 每行是长度为 136 的列表 我想问我如何定义我的数据集 以便我可以使用 Da
  • DialogFragment.dismiss 因 NullPointerException 崩溃

    我正在做一些后台工作并在执行此操作时显示 DialogFragment 一旦我的工作完成并调用相关回调 我就会关闭该对话框 当我这样做时 我遇到了由 Android 源中的 NPE 引起的崩溃 如下所示 void dismissIntern
  • 按顺序调用子项目和其他任务的 Gradle 批处理任务

    我正在为多模块项目编写 gradle 1 4 构建文件 所以有根构建 gradle定义如下 subprojects apply plugin java 它定义了build所有子模块的任务 子模块包含在设置 gradle每个模块都有其具有定义
  • 为什么使用 static_cast(x) 而不是 (T)x?

    我听说static cast函数应该优先于 C 风格或简单函数风格的转换 这是真的 为什么 主要原因是经典的 C 类型转换不区分我们所说的static cast lt gt reinterpret cast lt gt const cast
  • PHP 中没有 cookie 的 CSRF 令牌

    我正在寻找一种将 CSRF 令牌添加到我正在制作的应用程序中的方法 需要注意的是 该应用程序当前不使用 cookie 或会话 我很想找到一种引入 CSRF 令牌的方法 而不必 在我的应用程序中引入状态 使用会话或 cookie SESSIO
  • 读取 txt 文件 fscanf 与 fread 与 textscan [重复]

    这个问题在这里已经有答案了 我有一个从 SQL 2005 生成的 txt 文件 ANSI 格式 我努力了textscan and fscanf 整个txt文件只有numeric data 在线资源表明 fscanf 比 textscan 更
  • 获取外部文件目录失败

    OnActivityCreated 我正在做 activity getExternalFilesDir Environment DIRECTORY PICTURES 在 logcat 中我得到 com package W ContextIm
  • 流过滤器的时间复杂度

    我有这样的代码 List
  • 如何在delphi中使用ToastGeneric创建toast通知

    我正在使用 delphi 在桌面上进行开发 我想使用 ToastGeneric 类型通知创建 toast 通知 LToastFactory CreateToastNotification LXMLTemplate 另外 我正在使用 xml
  • 通过“with”语句使用 Python 队列

    有没有使用Python的标准方法Queue in a with陈述 这就是我希望能够使用它的方式 import Queue myqueue Queue Queue with myqueue as nextItem doStuff nextI
  • Shell 脚本 - 在文件中智能替换并在第二个文件中查找

    我有两个文件 一个数据文件和一个查找文件 数据文件的一个字段必须由一个值更改 该值可以在查找文件中找到 数据文件如下所示 2013 04 24 1 0 1635 1 4135 2013 04 24 1 0 9135 1 4135 2013
  • javascript 正则表达式计算空白字符

    我可以使用 javascript 正则表达式来计算字符串中第一个文本字符之前的空白字符数吗 我只关心是否有0 1和2 我当前的工作解决方案是拥有三个正则表达式 仅使用 match 来确定 0 1 或 2 类别 每个类别都有单独的模式 但我正
  • Oracle SQL 中是否有类似于 SUM 函数的 PRODUCT 函数?

    我有一个同事正在寻找这个 但我不记得曾经遇到过类似的事情 有没有一种合理的技术可以让你模拟它 SELECT PRODUCT X FROM SELECT 3 X FROM DUAL UNION ALL SELECT 5 X FROM DUAL
  • 单线程/核心上的并行如何可能?

    现代编程语言为用户提供了一流的并行和并发机制 我了解并行算法是如何编程的 并且可以很好地想象多核CPU上的两个线程如何并行运行 然而 大多数这些平台还支持在单个线程上运行并行进程 这些进程真的并行运行吗 在汇编级别上 两个不同的例程如何在单
  • 为什么这段代码在 jsbin 中有效,但在 jsfiddle 中无效?

    我按照此处另一位用户的建议重新发布 重新表述此内容 下面的代码适用于jsbin http jsbin com osebov 1 edit但不在jsfiddle http jsfiddle net wNaEX 有人知道为什么吗 该问题源于我尝
  • 如何从内容页访问母版页中的用户控件?

    假设我在母版页中有一个标头用户控件 并且想要根据母版页内加载的内容页来更改用户控件的属性 我该怎么办 Thanks 您可以使用两种方法 第一个是通过使用Page Master FindControl controlID 然后您可以将其转换为
  • 查找嵌套 json 对象深处的对象

    我在下面的代码片段中有嵌套的 json 对象 想要查找所有出现的 schema 并将包含该架构值的整个对象保存到另一个对象中 我尝试使用 lodash 过滤器 但没有成功 有没有人有什么建议 element parseResult cont
  • 预授权不起作用

    我正在编写一个套接字服务器 无 Web 应用程序 应用程序 并希望使用基于方法的安全性来处理我的 ACL 需求 我按照我发现的一个小教程进行操作春季安全举例 http blog solidcraft eu 2011 03 spring se