【发布时间】:2022-01-22 21:31:15
【问题描述】:
我是 Spring Boot 和 Spring Security 的新手,并且继承了一个使用它们的 webapp 项目。我们将把 webapp 迁移到一个新的部署环境。我们将要更改的一件事是身份验证机制,以便它可以在新环境中运行。同时,我想使用一些现有的 PostMan 测试来运行 REST 端点,绕过安全性。基本上,我想暂时禁用安全性。
我有一个提供全局方法级别安全性的类:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
// ...
}
我有多个控制器类,例如,提供用户信息的类:
@RestController
public class UserController {
@ApiOperation(value = "Gets the list of users for an admin.")
@PreAuthorize("#oauth2.hasScope('dashboard') and #oauth2.hasScope('read') and hasRole('ROLE_SYSADMIN')")
@GetMapping(value = "/user/list", produces = MediaType.APPLICATION_JSON_VALUE)
@AuditAccess(message = "Accessing /user/list")
public ResponseEntity<List<UserResponse>> getUserList() {
// ...
}
// ...
}
如果我尝试运行我的 PostMan 测试,它们会失败,因为在我的本地测试环境中没有设置身份验证机制。我第一次尝试绕过安全性是注释掉@EnableGlobalMethodSecurity 行,但这导致了运行时错误,可能是由于方法上的@PreAuthorize 注释。如果我也注释掉这些,我可以让测试运行。但是,有许多这样的注释分布在许多文件中。我宁愿不评论这一切。我宁愿暂时替换一个“什么都不做”的方法安全版本。这是我的尝试:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
/**
* This class is designed to let everything pass the method filter, i.e.,
* effectively removing method level security.
*/
class DoNothingMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
public Object filter(Object filterTarget, Expression filterExpression, EvaluationContext ctx) {
return filterTarget;
}
@Override
public void setReturnObject(Object returnObject, EvaluationContext ctx) {
// do nothing
}
}
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
MethodSecurityExpressionHandler doNothingHandler =
new DoNothingMethodSecurityExpressionHandler();
return doNothingHandler;
// TODO restore below
// return new OAuth2MethodSecurityExpressionHandler();
}
}
如果我尝试运行我的 PostMan 测试
GET http://localhost:8080/myapp/user/list
我收到一个错误:
2021-12-21 06:28:14,252 INFO [stdout] (default task-1) Request: http://localhost:8080/myapp/user/list }raised
2021-12-21 06:28:14,253 INFO [stdout] (default task-1) org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
2021-12-21 06:28:14,254 INFO [stdout] (default task-1) at org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:379) ~[spring-security-core-5.3.1.RELEASE.jar:5.3.1.RELEASE]
2021-12-21 06:28:14,254 INFO [stdout] (default task-1) at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:223) ~[spring-security-core-5.3.1.RELEASE.jar:5.3.1.RELEASE]
2021-12-21 06:28:14,254 INFO [stdout] (default task-1) at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:65) ~[spring-security-core-5.3.1.RELEASE.jar:5.3.1.RELEASE]
2021-12-21 06:28:14,255 INFO [stdout] (default task-1) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
2021-12-21 06:28:14,255 INFO [stdout] (default task-1) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
2021-12-21 06:28:14,256 INFO [stdout] (default task-1) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
2021-12-21 06:28:14,257 INFO [stdout] (default task-1) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
2021-12-21 06:28:14,257 INFO [stdout] (default task-1) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
2021-12-21 06:28:14,257 INFO [stdout] (default task-1) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
2021-12-21 06:28:14,258 INFO [stdout] (default task-1) at mycompany.rest.controller.UserController$$EnhancerBySpringCGLIB$$f2b6b566.getUserList(<generated>) ~[classes:?]
2021-12-21 06:28:14,259 INFO [stdout] (default task-1) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_271]
2021-12-21 06:28:14,259 INFO [stdout] (default task-1) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_271]
2021-12-21 06:28:14,260 INFO [stdout] (default task-1) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_271]
2021-12-21 06:28:14,260 INFO [stdout] (default task-1) at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_271]
2021-12-21 06:28:14,260 INFO [stdout] (default task-1) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.5.RELEASE.jar:5.2.5.RELEASE]
2021-12-21 06:28:14,261 INFO [stdout] (default task-1) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.5.RELEASE.jar:5.2.5.RELEASE]
2021-12-21 06:28:14,261 INFO [stdout] (default task-1) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
2021-12-21 06:28:14,263 INFO [stdout] (default task-1) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
2021-12-21 06:28:14,264 INFO [stdout] (default task-1) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
2021-12-21 06:28:14,265 INFO [stdout] (default task-1) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
2021-12-21 06:28:14,265 INFO [stdout] (default task-1) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
2021-12-21 06:28:14,266 INFO [stdout] (default task-1) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
出于某种原因,我们仍在尝试进行身份验证。
这个问题与其他一些问题(Spring Boot 2.0 Disable Default Security、Spring Oauth2 : Authentication Object was not found in the SecurityContext 和 An Authentication object was not found in the SecurityContext - Spring 3.2.2)类似,但涉及不同的版本和不同的用例。我无法弄清楚如何将这些答案应用于我的情况。我的 Spring 环境包括:
<spring.version>5.2.5.RELEASE</spring.version>
<spring.oath2.version>2.4.1.RELEASE</spring.oath2.version>
<spring.boot.version>2.2.6.RELEASE</spring.boot.version>
<spring.jwt.version>1.1.0.RELEASE</spring.jwt.version>
<spring.security.version>5.3.1.RELEASE</spring.security.version>
什么是绕过安全的简单方法?
【问题讨论】:
-
我首先想知道你为什么使用多个不同版本的 spring,spring 是一个生态系统,版本可以协同工作,spring-boot 自动拉入 spring 上下文,并且 spring security 已经自带nimbus jwt 库,所以我首先想知道奇怪的依赖用法的原因
-
如果这是一个 spring boot 应用程序,你应该使用 spring boot parent 或 bom,然后使用 spring boot 启动器让 spring 为你处理版本。为什么我要指出这一点是因为我不想对由于混乱的依赖关系而“可能不起作用”的事情给出答案
-
@Toerktumlare - 我不知道为什么版本不一致;这些是我继承的版本号。我会尽力清理它们。
标签: spring spring-boot spring-mvc spring-security