1
votes

Comment tester le serveur de ressources OAuth2 avec une simulation

J'ai mon serveur OAUTH2, dont les autres services ont besoin pour demander un jeton jwt pour pouvoir accéder aux points de terminaison.

Jusqu'ici tout va bien, tout va bien.

Mais maintenant j'écris les tests, et ils renvoient tous l'erreur 401 sans autorisation. J'ai déjà compris que c'est parce que les tests ne font aucune requête pour le serveur OAuth2.

Ce que je voulais savoir, c'est comment faire une simulation à partir d'un JWT ou du serveur oauth2.


0 commentaires

3 Réponses :


2
votes

Le moyen le plus simple est de simuler directement un jeton JWT, vous pouvez utiliser une clé de signature différente pour vos tests afin de ne pas créer de coupure de sécurité pour votre backend.


2 commentaires

Comment puis-je faire cela? Avez-vous un exemple?


vous pouvez créer votre propre jeton JWT en utilisant un framework, il y en a beaucoup sur jwt.io



1
votes

Si vous avez besoin de simuler un JWT, la meilleure solution est d'utiliser un générateur JWT ciblant vos tests en utilisant Bibliothèque Nimbus JWT + JOSE

Par exemple, ci-dessous est un code directement extrait de JSON Web Token (JWT) avec signature RSA , qui montre la génération JWT ainsi que l'assertion qui est très très similaire à un test.

import java.util.Date;

import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.*;
import com.nimbusds.jose.jwk.*;
import com.nimbusds.jose.jwk.gen.*;
import com.nimbusds.jwt.*;


// RSA signatures require a public and private RSA key pair, the public key 
// must be made known to the JWS recipient in order to verify the signatures
RSAKey rsaJWK = new RSAKeyGenerator(2048)
    .keyID("123")
    .generate();
RSAKey rsaPublicJWK = rsaJWK.toPublicJWK();

// Create RSA-signer with the private key
JWSSigner signer = new RSASSASigner(rsaJWK);

// Prepare JWT with claims set
JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
    .subject("alice")
    .issuer("https://c2id.com")
    .expirationTime(new Date(new Date().getTime() + 60 * 1000))
    .build();

SignedJWT signedJWT = new SignedJWT(
    new JWSHeader.Builder(JWSAlgorithm.RS256).keyID(rsaJWK.getKeyID()).build(),
    claimsSet);

// Compute the RSA signature
signedJWT.sign(signer);

// To serialize to compact form, produces something like
// eyJhbGciOiJSUzI1NiJ9.SW4gUlNBIHdlIHRydXN0IQ.IRMQENi4nJyp4er2L
// mZq3ivwoAjqa1uUkSBKFIX7ATndFF5ivnt-m8uApHO4kfIFOrW7w2Ezmlg3Qd
// maXlS9DhN0nUk_hGI3amEjkKd0BWYCB8vfUbUv0XGjQip78AI4z1PrFRNidm7
// -jPDm5Iq0SZnjKjCNS5Q15fokXZc8u0A
String s = signedJWT.serialize();

// On the consumer side, parse the JWS and verify its RSA signature
signedJWT = SignedJWT.parse(s);

JWSVerifier verifier = new RSASSAVerifier(rsaPublicJWK);
assertTrue(signedJWT.verify(verifier));

// Retrieve / verify the JWT claims according to the app requirements
assertEquals("alice", signedJWT.getJWTClaimsSet().getSubject());
assertEquals("https://c2id.com", signedJWT.getJWTClaimsSet().getIssuer());
assertTrue(new Date().before(signedJWT.getJWTClaimsSet().getExpirationTime()));

Ce que je ferais, c'est d'extraire des fonctionnalités de génération JWT similaires dans une classe dédiée. Ajoutez quelques paramètres de constructeur (ou utilisez un modèle de constructeur) à cela et utilisez-le pour tous mes retours simulés. De cette façon, vous pouvez tester les scénarios corrects, incorrects et inattendus.


0 commentaires

0
votes

J'ai essayé les deux astuces mais sans succès.

Ma configuration de serveur de ressources:

@Configuration
public class ConfiguracaoDeToken {

    @Autowired
    private ConversorDeTokenDeAcessoPersonalizado conversorDeTokenDeAcessoPersonalizado;

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean
    public DefaultTokenServices tokenServices() {
        final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        return defaultTokenServices;
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        final JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setAccessTokenConverter(conversorDeTokenDeAcessoPersonalizado);

        final Resource resource = new ClassPathResource("public.txt");
        String publicKey = null;
        try {
            publicKey = IOUtils.toString(resource.getInputStream());
        } catch (final IOException e) {
            throw new RuntimeException(e);
        }
        converter.setVerifierKey(publicKey);
        return converter;
    }
}

@Component
public class ConversorDeTokenDeAcessoPersonalizado extends DefaultAccessTokenConverter {

    @Override
    public OAuth2Authentication extractAuthentication(Map<String, ?> claims) {
        OAuth2Authentication authentication = super.extractAuthentication(claims);
        authentication.setDetails(claims);
        return authentication;
    }
}

@Component
public class TokenPayload {

    private Map<String, Object> getExtraInfo() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        OAuth2AuthenticationDetails oauthDetails = (OAuth2AuthenticationDetails) auth.getDetails();
        @SuppressWarnings("unchecked")
        var details = (Map<String, Object>) oauthDetails.getDecodedDetails();
        return details;
    }

    public String payloadLogin() {
        return getExtraInfo().get("user_name").toString();
    }

    public Long payloadIdEmpresa() {
        return Long.parseLong(getExtraInfo().get("idEmpresa").toString());
    }

    public Long payloadIdFuncionario() {
        return Long.parseLong(getExtraInfo().get("idFuncionario").toString());
    }

}

Ma configuration de jeton

@Configuration
@EnableResourceServer
public class ServidorDeRecursos extends ResourceServerConfigurerAdapter {

    @Autowired
    private ConfiguracaoDeToken configuracaoDeToken;

    @Override
    public void configure(final HttpSecurity http) throws Exception {
        // @formatter:off
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .and()
                .authorizeRequests().anyRequest().permitAll();
        // @formatter:on
    }

    @Override
    public void configure(final ResourceServerSecurityConfigurer config) {
        config.tokenServices(configuracaoDeToken.tokenServices());
    }
}


0 commentaires