Весенний тест безопасности: как смоделировать / шпионить класс ключа безопасности, такой как JWK - PullRequest
0 голосов
/ 29 ноября 2018

Я хочу протестировать сервис токенов, но не знаю как.

Это метод проверки сервиса: (служба токена JWT)

...
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JOSEObjectType;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.jwk.JWK;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;

...
/**
 * Service to build tokens (ID Tokens) based on the request, client and user information
 * The result is a serialized token that can be returned directly to the client
 *
 */
 @Service
 @Slf4j
 @RequiredArgsConstructor
 public class TokenService {
     private final JWTSigningService jwtSigningService;
     private final OpenidConfigProperties configProperties;
     private final StaffService staffService;

/**
 * Builds an ID Token including information based on the scopes and authentication
 * The token expiration times must be set from configuration on the Client
 *
 * @param client The client entity, requested in the request and loaded from its repository
 * @param request The request entity received
 * @param user The user loaded from the Authentication filters
 * @return The signed and serialized ID Token
 */
public String buildIdToken(Client client, AuthorizeRequest request, MyCompanyUser user) {
    JWK key = jwtSigningService.getDefaultKey().orElseThrow(
            ()-> new IllegalArgumentException("Default key is missing.")
    );

    JWSAlgorithm jwsAlgorithm = new JWSAlgorithm(key.getAlgorithm().getName());
    JWSHeader jwsHeader = new JWSHeader.Builder(jwsAlgorithm).keyID(key.getKeyID()).type(JOSEObjectType.JWT).build();

    JWTClaimsSet claims = scopeClaimSetMapper(client, request, user);
    SignedJWT jwt = new SignedJWT(jwsHeader, claims);

    // TODO: change log info to debug after making sure it works well on PRO to avoid to much logs
    log.info("JWT Claim set created with JTI: " + claims.getJWTID());
    try {
        return jwtSigningService.signJwt(jwt).serialize();
    } catch (JOSEException e) {
        throw new IllegalArgumentException("Claim set couldn't be signed", e);
    }
}

У меня есть печальная часть пути:

@RunWith(MockitoJUnitRunner.class)
public class TokenServiceTest {
    @Mock
    private JWTSigningService jwtSigningService;

    @Mock
    private OpenidConfigProperties openidConfigProperties;

    @Mock
    private StaffService staffService;

    private TokenService tokenService;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        tokenService = new TokenService(jwtSigningService, openidConfigProperties, staffService);
    }

    @Test
    public void testBuildIdTokenSadPath() {
        // given
        when(jwtSigningService.getDefaultKey()).thenReturn(Optional.empty());
        Client client = new Client();
        AuthorizeRequest authorizeRequest = new AuthorizeRequest();
        MyCompanyUser myCompanyUser = new MyCompanyUser("username", "password", "password_legacy",
                true, new ArrayList<GrantedAuthority>());
        // when

        // then
        Assertions.assertThatThrownBy(() -> tokenService.buildIdToken(client, authorizeRequest, myCompanyUser))
                .isInstanceOf(IllegalArgumentException.class).hasMessage("Default key is missing.");
    }
}

Но как можноЯ высмеиваю всю необходимую часть для счастливого пути теста?Часть jwtSigningService.getDefaultKey() очень трудно смоделировать: она должна возвращать объект Optional<com.nimbusds.jose.jwk.JWK>, тогда как JWK является абстрактным классом, и его реализации также сложны для построения.(com.nimbusds.jose.jwk.RSAKey, например)

В этом случае возможен ли модульный тест?

...