java—如何访问spring托管类中的keyvault属性?

goucqfw6  于 2021-07-13  发布在  Java
关注(0)|答案(1)|浏览(360)

我正在使用azure keyvault存储应用程序机密。我想在spring托管组件类中使用它们。什么时候,我正在尝试访问它。它引发空指针异常。有人能建议什么是访问springboot属性的理想方法吗。

@Slf4j
@Component
public class AuthConfiguration extends HandlerInterceptorAdapter {

    private static final String CORRELATION_ID_LOG_VAR_NAME = "correlationId";
    private static final String CORRELATION_ID_HEADER_NAME = "Correlation-Id";

    @Autowired
    KeyVaultProperties keyVaultProperties;    

    @Value("${private-key-alias-name}")
    private String KeyAliasName;

    @Value("${auth-cert-password}")
    private String AuthCertPassword;

    @PostConstruct
    public void setup(){
        ClassLoader classLoader = AuthConfiguration.class.getClassLoader();
        File file = new File(
                Objects.requireNonNull(
                        classLoader.getResource(AppConstants.JKS_FILE_NAME))
                        .getFile());
        KeyStore keystore = null;
        try {
            InputStream is = new FileInputStream(file);
            keystore = KeyStore.getInstance(KeyStore.getDefaultType());
            keystore.load(is, AuthCertPassword.toCharArray());
            key = (PrivateKey)keystore.getKey(KeyAliasName, AuthCertPassword.toCharArray());
        } catch (UnrecoverableKeyException | KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException  e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler)
            throws Exception {
        final Boolean isValidToken;
        final String correlationId = getCorrelationIdFromHeader(request);
            isValidToken = validateAuthTokenFromRequestHeader(request);
            log.info("correlationId:{}",correlationId);
            MDC.put(CORRELATION_ID_LOG_VAR_NAME, correlationId);
            log.info("Token is Valid:{}",isValidToken);
            if(!isValidToken)
                throw new AuthenticationException("Invalid Authentication");
        return isValidToken;
    }

    @Override
    public void afterCompletion(final HttpServletRequest request, final HttpServletResponse response,
                                final Object handler, final Exception ex) throws Exception {
        MDC.remove(CORRELATION_ID_LOG_VAR_NAME);
    }

    private String getCorrelationIdFromHeader(final HttpServletRequest request) {
        String correlationId = request.getHeader(CORRELATION_ID_HEADER_NAME);
        if (correlationId == null) {
            correlationId = generateUniqueCorrelationId();
        }
        return correlationId;
    }

    private Boolean byPassToken(final HttpServletRequest request){
        String byPassToken =  request.getHeader(BY_PASS_TOKEN);
        return (byPassToken != null) && byPassToken.equals("true");
    }

    private String generateUniqueCorrelationId() {
        return UUID.randomUUID().toString();
    }

    private Boolean validateAuthTokenFromRequestHeader(final HttpServletRequest request)
            throws ParseException, ValidationException{
        String authToken = request.getHeader(AUTH_TOKEN_HEADER_NAME);
        if(authToken == null){
            log.info("Token is Empty for this request, correlation Id: {}",request.getHeader(CORRELATION_ID_HEADER_NAME));
            throw new ValidationException(Error.MISSING_AUTH_TOKEN.getCode(),Error.MISSING_AUTH_TOKEN.getErrorMsg());
        }
        JWTClaimsSet claimsSet = decryption(authToken);
        return 
                isValidIssuer(claimsSet);
    }

    private JWTClaimsSet decryption(String encryptedJWTString)
            throws ParseException, AuthenticationException {
        EncryptedJWT jwt = null;
        try{
            jwt = EncryptedJWT.parse(encryptedJWTString);
            RSADecrypter decrypter = new RSADecrypter(key);
            jwt.decrypt(decrypter);
        }catch (ParseException  exception){
            throw new AuthenticationException(Error.MISSING_AUTH_TOKEN.getErrorMsg());
        }catch (Exception e){
            e.printStackTrace();
        }
        return jwt.getJWTClaimsSet();
    }

    // Check if token issuer is valid
    private Boolean isValidIssuer(JWTClaimsSet jwtClaimsSet){
        log.info("Issuer is Valid:{}",jwtClaimsSet.getIssuer().equals(keyVaultProperties.getAuthIssuer()));
        return jwtClaimsSet.getIssuer().equals(issuer);
    }

}
@Data
public class KeyVaultProperties {

    @Value("${auth-by-pass-token}")
    private String AuthByPassToken;

    @Value("${auth-clients}")
    private String authClients;

    @Value("${auth-cert-password}")
    private String AuthCertPassword;

    @Value("${auth-issuer}")
    private String AuthIssuer;

}

我在上得到空指针异常 log.info("Issuer is Valid:{}",jwtClaimsSet.getIssuer().equals(keyVaultProperties.getAuthIssuer())); . 有人能帮我一下吗,我可以进入同一个地方 postconstruct 方法设置

vuktfyat

vuktfyat1#

我认为获取密钥库机密的最简单方法是使用托管标识,当然它提供了针对java的解决方案,下面是对azure idenetity client library for java的描述。我已经测试了一个从客户端凭证流生成的凭证。这里还有一些其他选项,您可以选择使用其他选项。请注意,您需要在azure密钥库中为目标azure ad应用程序或其他服务原则授予访问策略。

public static void main(String args[]) {            
        ClientSecretCredential clientSecretCredential = new ClientSecretCredentialBuilder()
                .clientId("azure ad application client id")
                .clientSecret("client secret")
                .tenantId("xxx.onmicrosoft.com")
                .build();

        // Azure SDK client builders accept the credential as a parameter
        SecretClient client = new SecretClientBuilder()
            .vaultUrl("https://{YOUR_VAULT_NAME}.vault.azure.net")
            .credential(clientSecretCredential)
            .buildClient();

        String a = client.getSecret("cosmosdbScanWithwrongkey").getValue();
        System.out.print(a);
    }

相关问题