我有一个简单的SpringBoot应用程序与网络安全和方法安全配置使用自定义SecurityExpressionRoot。当我从IDE (例如STS或IDEA)启动SB应用程序并调用我得到的端点时
org.springframework.expression.spel.SpelEvaluationException: EL1004E:
Method call: Method hasAnyAccess(java.lang.String) cannot be found on
org.springframework.security.access.expression.method.MethodSecurityExpressionRoot type当我使用 jar文件从CLI启动SB应用程序时,端点调用成功:
INFO 11282 --- [nio-8080-exec-4] c.e.CustomMethodSecurityExpressionRoot :
< CustomMethodSecurityExpressionRoot(): [org.springframework.security.authentication.UsernamePasswordAuthenticationToken@442a8f33: Principal: org.springframework.security.core.userdetails.User@36ebcb: Username: user; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@166c8: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 36E17CAA657E897B1682BFF27EA7DA1F; Granted Authorities: ROLE_USER]
INFO 11282 --- [nio-8080-exec-4] c.e.CustomMethodSecurityExpressionRoot :
> hasAnyAccess(): [[FULL_ACCESS]]任何帮助都是非常感谢的。
Web安全配置:
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
...
}方法安全配置:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
CustomMethodSecurityExpressionHandler expressionHandler = new CustomMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(new CustomPermissionEvaluator());
return expressionHandler;
}
}方法安全表达式处理程序:
public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
@Override
protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) {
CustomMethodSecurityExpressionRoot root = new CustomMethodSecurityExpressionRoot(authentication);
root.setPermissionEvaluator(getPermissionEvaluator());
root.setTrustResolver(this.trustResolver);
root.setRoleHierarchy(getRoleHierarchy());
return root;
}
}安全表达式根:
public class CustomMethodSecurityExpressionRoot extends SecurityExpressionRoot implements MethodSecurityExpressionOperations {
public CustomMethodSecurityExpressionRoot(Authentication authentication) {
super(authentication);
LOGGER.info("< CustomMethodSecurityExpressionRoot(): [{}]", authentication);
}
public final boolean hasAnyAccess(String... accessLevels) {
LOGGER.info("> hasAnyAccess(): [{}]", Arrays.asList(accessLevels));
return true;
}
}休息控制器:
@RestController
@RequestMapping("/")
public class MyController {
@PreAuthorize("hasAnyRole('ROLE_USER') && hasAnyAccess('FULL_ACCESS')")
@RequestMapping(value = "hello", method = RequestMethod.GET)
public String hello(@RequestParam String name) {
return "Hello '" + name + "' at " + System.currentTimeMillis() + "\n";
}
}更新1:当SB应用程序用
mvn spring-boot:runGlobalMethodSecurityConfiguration更新2:从日志中获得的在从IDE启动时似乎是的-- my MethodSecurityConfig扩展被覆盖
INFO 5927 --- [ main] o.s.b.f.s.DefaultListableBeanFactory :
Overriding bean definition for bean 'methodSecurityInterceptor' with a different definition:
replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=methodSecurityConfig; factoryMethodName=methodSecurityInterceptor; initMethodName=null; destroyMethodName=(inferred);
defined in class path resource [com/example/MethodSecurityConfig.class]]
with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; factoryMethodName=methodSecurityInterceptor; initMethodName=null; destroyMethodName=(inferred);
defined in class path resource [org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.class]]
INFO 5927 --- [ main] o.s.b.f.s.DefaultListableBeanFactory :
Overriding bean definition for bean 'methodSecurityMetadataSource' with a different definition:
replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=methodSecurityConfig; factoryMethodName=methodSecurityMetadataSource; initMethodName=null; destroyMethodName=(inferred);
defined in class path resource [com/example/MethodSecurityConfig.class]]
with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; factoryMethodName=methodSecurityMetadataSource; initMethodName=null; destroyMethodName=(inferred);
defined in class path resource [org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.class]]当从JAR 启动时,我的GlobalMethodSecurityConfiguration扩展MethodSecurityConfig覆盖
INFO 6092 --- [ main] o.s.b.f.s.DefaultListableBeanFactory :
Overriding bean definition for bean 'methodSecurityInterceptor' with a different definition:
replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; factoryMethodName=methodSecurityInterceptor; initMethodName=null; destroyMethodName=(inferred);
defined in class path resource [org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.class]]
with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=methodSecurityConfig; factoryMethodName=methodSecurityInterceptor; initMethodName=null; destroyMethodName=(inferred);
defined in class path resource [com/example/MethodSecurityConfig.class]]
INFO 6092 --- [ main] o.s.b.f.s.DefaultListableBeanFactory :
Overriding bean definition for bean 'methodSecurityMetadataSource' with a different definition:
replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; factoryMethodName=methodSecurityMetadataSource; initMethodName=null; destroyMethodName=(inferred);
defined in class path resource [org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.class]]
with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=methodSecurityConfig; factoryMethodName=methodSecurityMetadataSource; initMethodName=null; destroyMethodName=(inferred);
defined in class path resource [com/example/MethodSecurityConfig.class]]发布于 2018-10-16 05:30:00
经过一些调查之后,它发现了为这两者指定的@EnableGlobalMethodSecurity(prePostEnabled = true)注释。
WebSecurityConfigurerAdapter扩展和GlobalMethodSecurityConfiguration扩展造成了问题。从WebSecurityConfigurerAdapter中删除注释解决了这个问题。
https://stackoverflow.com/questions/52792167
复制相似问题