kotlin 在dev-profile上模拟身份验证

57hvy0tb  于 2023-11-21  发布在  Kotlin
关注(0)|答案(2)|浏览(253)

我正在试用Sping Boot 3.1.x,想知道是否有一个简单的解决方案来模拟一个用户的开发配置文件的oauth2 ResourceServer。使用quarkus这是非常容易实现的,但我与Sping Boot 斗争。
基本上,设置是一个不在开发机器上运行的oidc代理背后的资源服务器。因此,需要通过application.properties配置(角色/声明)的某种fakeuser来充当请求的JWT。这样,主体的每个消费者都会收到一个具有指定角色的经过身份验证的主体。
我该如何实施这样的解决方案?

aamkag61

aamkag611#

我目前的解决方案看起来像这样:
我通过将SecurityContextHolder.getContext().authentication设置为AbstractAuthenticationToken的实现来添加OncePerRequestFilter伪造身份验证。

override fun doFilterInternal(request: HttpServletRequest,
                                  response: HttpServletResponse,
                                  chain: FilterChain) {

  val principal = JWTClaimsSet.Builder()
                 .claim("sub", sub)
                 .claim("email", email)
                 .build();

  val authentication = UsernamePasswordAuthenticationToken(principal, null, roles.map { SimpleGrantedAuthority(it) })
        SecurityContextHolder.getContext().authentication = authentication

  chain.doFilter(request, response)
}

字符串
角色,子,电子邮件是通过配置注入模拟用户的需要。我没有麻烦使用正确的AuthToken实现,因为我不需要适合。
这段代码应该(就像我在问题中提到的)只在本地开发上运行,因为这显然是一个安全问题

wkftcu5l

wkftcu5l2#

我在这个Baeldung article中详细介绍了如何在单元和集成(@SpringBootTest)测试中使用模拟的OAuth2身份验证。
你必须选择:

  • spring-security-test中的内容用于OAuth2:MockMvc请求后处理器(如jwt())或WebTestClient mutator(如mockJwt()
  • 使用我编写的测试注解(并在Maven central上发布)

作为免责声明,我写了所有这些(OAuth2的spring-security-test中的内容,我是spring-addons的repo的所有者)。我个人偏爱注解,因为它不仅在使用MockMvcWebTestClient测试@Controller时有效,而且在使用方法安全性测试任何其他类型的@Component(如@Service@Repository)时也有效。
非常多价@WithMockAuthentication的样品用法:

@SpringBootTest(classes = { SecurityConfig.class, MessageService.class })
class MessageServiceTests {

    @Autowired
    private SecuredService securedService;
    
    @Test
    @WithMockAuthentication("BAD_BOY")
    void givenUserIsNotGrantedWithNice_whenCallNice_thenThrows() {
        assertThrows(Exception.class, () -> securedService.nice());
    }

    @Test
    @WithMockAuthentication(name = "brice", authorities = "NICE")
    void givenUserIsNice_whenCallNice_thenReturnsGreeting() {
        assertThat(securedService.nice()).isEqualTo("Dear brice, glad to see you!");
    }

    @ParameterizedTest
    @AuthenticationSource(
        @WithMockAuthentication(name = "brice", authorities = "NICE"),
        @WithMockAuthentication(name = "ch4mp", authorities = { "VERY_NICE", "AUTHOR" }))
    void givenUserIsAuthenticated_whenCallHello_thenReturnsGreeting(@ParameterizedAuthentication Authentication auth) {
        assertThat(securedService.hello()).isEqualTo("Hello %s.".formatted(auth.getName()));
    }
}

字符串
@WithJwt的示例用法,它在配置中使用身份验证转换器bean(实现Converter<Jwt, AbstractAuthenticationToken>,就像JwtAuthenticationConverter一样)`:

@Import(AuthenticationFactoriesTestConf.class) // when using spring-addons-oauth2-test but not spring-addons-starter-oidc
// @AddonsWebmvcComponentTest // when using spring-addons-starter-oidc along with spring-addons-starter-oidc-test (already imports AuthenticationFactoriesTestConf for you)
@SpringBootTest(classes = { SecurityConfig.class, MessageService.class })
class MessageServiceTests {

    @Autowired
    private SecuredService securedService;

    @Autowired
    WithJwt.AuthenticationFactory authFactory;
    
    @Test
    @WithJwt("igor.json")
    void givenUserIsIgor_whenCallNice_thenThrows() {
        assertThrows(Exception.class, () -> securedService.nice());
    }

    @Test
    @WithJwt("brice.json")
    void givenUserIsBrice_whenCallNice_thenReturnsGreeting() {
        assertThat(securedService.nice()).isEqualTo("Dear brice, glad to see you!");
    }

    @ParameterizedTest
    @MethodSource("identities")
    void givenUserIsAuthenticated_whenCallHello_thenReturnsGreeting(@ParameterizedAuthentication Authentication auth) {
        assertThat(securedService.hello()).isEqualTo("Hello %s.".formatted(auth.getName()));
    }

    Stream<AbstractAuthenticationToken> identities() {
        return authFactory.authenticationsFrom("brice.json", "igor.json");
    }
}

相关问题