Reputation: 508
I'm using azure keyvault to store the application secrets. I would like to use them in spring managed component class. When, I'm trying to access it. Its throwing null pointer exception. Can someone suggest what would be the ideal way to access the properties in spring boot.
@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;
}
I'm getting null pointer exception at log.info("Issuer is Valid:{}",jwtClaimsSet.getIssuer().equals(keyVaultProperties.getAuthIssuer()));
. Can someone help me on this, I can be able to access the same property in postconstruct
method setup
Upvotes: 0
Views: 849
Reputation: 15906
I think the easiest way to obtain key vault secret is using managed identity, and certainly it provides solution for java, here's description on azure idenetity client library for java. I've tested one of the credential which generated from client credential flow. Here's also some other options and you can choose to use others. And pls note, you need to grant access policy in azure key vault for the target azure-ad-app or some other service principle.
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);
}
Upvotes: 1