这是一个spring boot 2.0.6应用程序,使用一个MVC控制器,使用@PreAuthorize和#oauth2。hasScope来保护控制器endpoint。我使用@WebMvcTest编写了控制器测试。然而,当#oauth2时,似乎正在发出请求。hasScope
正在被调用,它没有给出一个可以与某个地方进行比较的值。我怎么了?
例外
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: Failed to evaluate expression '#oauth2.hasScope('foo')'
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:71)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:166)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:133)
...
Caused by: java.lang.IllegalArgumentException: Failed to evaluate expression '#oauth2.hasScope('eq.distributor')'
at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:30)
at org.springframework.security.access.expression.method.ExpressionBasedPreInvocationAdvice.before(ExpressionBasedPreInvocationAdvice.java:59)
at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.vote(PreInvocationAuthorizationAdviceVoter.java:72)
... 72 more
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1011E: Method call: Attempted to call method hasScope(java.lang.String) on null context object
at org.springframework.expression.spel.ast.MethodReference.throwIfNotNullSafe(MethodReference.java:153)
at org.springframework.expression.spel.ast.MethodReference.getValueRef(MethodReference.java:82)
... 94 more
考试班
@RunWith(SpringRunner.class)
@WebMvcTest
public class MockMvcTestBase {
@Autowired
protected WebApplicationContext context;
private ObjectMapper objectMapper;
private MockMvc mockMvc;
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation)
.uris()
.withScheme("http")
.withHost("development.com")
.withPort(80))
.alwaysDo(document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())))
.apply(springSecurity())
.build();
this.objectMapper = new ObjectMapper();
}
@Test
@WithMockUser(username = "testclient", authorities = "foo")
public void givenValidUser_whenGetOrderDetailsWebEC_thenGetOrder() throws Exception {
getMockMvc().perform(get("/ok")
.header("Authorization", authorizationHeader()))
.andExpect(status().isOk())
.andExpect(content().string("ok"));
}
}
身份验证配置
@Configuration
@EnableAuthorizationServer
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true)
@SuppressWarnings("static-method")
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Bean
public static PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("testclient")
.secret("password")
.authorizedGrantTypes("client_credentials")
.accessTokenValiditySeconds(0)
.scopes("foo")
.and()
.withClient("bar")
.secret("password")
.authorizedGrantTypes("client_credentials")
.accessTokenValiditySeconds(0)
.scopes("eq.distributor");
}
}
控制器
@PreAuthorize("#oauth2.hasScope('foo')")
@RequestMapping(value = "/ok", method = RequestMethod.GET)
public String ok() {
return "ok";
}
Spring Security调试输出
org.springframework.mock.web.MockHttpServletRequest@54704b46
servletPath:
pathInfo:/ok
headers:
Authorization: Bearer 57962883-e379-433b-b613-1f888471fb84
Accept: application/json;charset=UTF-8
Security filter chain: [
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
LogoutFilter
OAuth2AuthenticationProcessingFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
关于我在设置中缺少的任何帮助都会非常有帮助。似乎确实有问题,好像它实际上是在尝试验证,会返回401/403。也不例外。减去编译所需的更改,这在Spring Boot 1.5.9下工作。
如果我把模拟mvc注释换成@SpringBootTest,这是可行的,但是我不需要这些测试上的数据库,所以我想把它设置为不需要加载它。
这是因为Spring使用的是DefaultMethodSecurityExpressionHandler
。请参见:#oauth2方法级别的安全表达式
要解决问题,请执行以下操作:
AuthorizationServerConfig
@EnableGlobalMethod odSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
对我来说重要的是,我已经在另一个配置上安装了@EnableGlobalMethod odSecurity
,所以Spring最初忽略了新的配置类
我在身份验证期间重定向到google时出错 网页具有:某些请求的作用域无效。{无效=[https://www.googleapis.com/drive/v2/files]}了解更多请求详细信息范围=https://www.googleapis.com/drive/v2/files 在我的驱动SDK控制台上,启用两个范围:[https://www.googleapis.com/auth/drive]
我试图测试两个不同的控制器类,因为我想测试两个类中的每个方法,我将使用@WebMvcTest,我的问题是有一种方法可以将模拟注入到两个类中,可能是这样的? 当然,这会产生错误,所以这是否意味着当使用@WebMvcTest时,我们只能在一个控制器中测试方法?每班
我试图在一个web应用程序(Java1.8/Tomcat8)中使用最新的JavaMail1.6.0 api,代表该应用程序的客户机用户发送电子邮件。一些客户使用Gmail。我不想要求他们按照javamail FAQ的建议,在他们的谷歌账户中允许访问不安全的应用程序,如果需要的话,我愿意实现oauth2。 创建了一个应用程序 为应用程序(clientid,clientsecret)创建了oauth2
问题内容: 运行期间是否可以注入示波器或控制器?或任何其他建议将服务动态注入控制器? 提前致谢 问题答案: 可以使用$ injector 将服务动态(按名称)注入到控制器中。能够通过控制器参数注入服务只是Angular提供的一种便利。在后台,Angular使用$ injector来检索对象实例。但是我们也可以自己使用$ injector。 小提琴。
我尝试注入$scope,然后使用,但这不起作用? 有人能提供建议吗?
通过 Google 对用户进行身份验证 OAuth2 是用于授权的行业标准协议。它提供了一种机制,使用户可以在不共享用户名,密码和其他私有凭据的情况下,向Web 和桌面应用程序授予对私有信息的访问权限。 本教程构建了一个扩展程序,该扩展程序使用Google People API 和Chrome Identity API 访问用户的 Google 联系人。由于扩展程序无法通过 HTTPS加载,无法执