[ https://issues.apache.org/jira/browse/NIFI-8406?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Vijay Jammi updated NIFI-8406: ------------------------------ Description: The current oidc client authentication methods (client_secret_post, client_secret_basic) require client credentials (client_secret) to be stored as plain text on the client's filesystem, which could also be inadvertently checked into source control system. Due to these and other security considerations, we should be able to use assertions as client credentials for authenticating against the token endpoint. While using assertions an oidc client will include client_assertion and client_assertion_type parameters instead of passing the client_secret for authentication. For further details can be found within the below OAuth 2.0 Client Authentication specs # [RFC 7523, Section 2.2 (Using JWTs for Client Authentication)|https://tools.ietf.org/html/rfc7523#section-2.2] # [RFC 7521 (Using Assertions for Client Authentication)|https://tools.ietf.org/html/rfc7521#section-4.2]. High level summary of the changes that might need to be made for assertion based client authentication. # Generate a pair of private and public key which can be made available to Nifi via a keystore on the filesystem. # Make the public key or cert available to the Authorization Server. Alternatively to allow key rotations, we could configure a JWKS URL within Nifi to allow the authorization server download the public key using the keyId (kid). # While building the token request against the token endpoint ## Need StandardOidcIdentityProvider to provide a way to build a private_key_jwt based client authentication in addition to the existing client_secret_basic, client_secret_post. {code:java} if (ClientAuthenticationMethod.PRIVATE_KEY_JWT.equals(clientAuthenticationMethod)){ clientAuthentication = new PrivateKeyJWT(clientId, tokenEndpoint, jwsAlgorithm, rsaPrivateKey, keyId, jcaProvider);} else if (ClientAuthenticationMethod.CLIENT_SECRET_POST.equals(clientAuthenticationMethod)) { clientAuthentication = new ClientSecretPost(clientId, clientSecret);} else { clientAuthentication = new ClientSecretBasic(clientId, clientSecret);} {code} ## Encode and sign the JWT token with the private key, conforming to RFC 7523, section 2.2 and pass the signed token within the client_assertion request parameter along with the client_assertion_type. {code:java} POST http://<keycloak-host>:<port>/auth/realms/<keycloak-realm>/protocol/openid-connect/token HTTP/1.1 Content-Type: application/x-www-form-urlencodedclient_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer& client_assertion=eyJraWQiOiJkMlY2LS1OUG....hTMfA& grant_type=authorization_code& code=9ba8d85b-...-c7a6fb6dae55 {code} # The Authorization Server will use the client's public key or cert to verify the signature of the JWT and issues the token was: The current oidc client authentication methods (client_secret_post, client_secret_basic) require client credentials (client_secret) to be stored as plain text on the client's filesystem, which could also be inadvertently checked into source control system. Due to these and other security considerations, we should be able to use assertions as client credentials for authenticating against the token endpoint. While using assertions an oidc client will include client_assertion and client_assertion_type parameters instead of passing the client_secret for authentication. For further details can be found within the below OAuth 2.0 Client Authentication specs # [RFC 7523, Section 2.2 (Using JWTs for Client Authentication)|https://tools.ietf.org/html/rfc7523#section-2.2] # [RFC 7521 (Using Assertions for Client Authentication)|https://tools.ietf.org/html/rfc7521#section-4.2]. Summary of the high level changes we that need to be made for assertion based client authentication. # Generate a pair of private and public key which can be made available to Nifi via a keystore on the filesystem. # Make the public key or cert available to the Authorization Server. Alternatively to allow key rotations, we could configure a JWKS URL within Nifi to allow the authorization server download the public key using the keyId (kid). # While building the token request against the token endpoint ## Need StandardOidcIdentityProvider to provide a way to build a private_key_jwt based client authentication in addition to the existing client_secret_basic, client_secret_post. {color:#4c9aff}if (ClientAuthenticationMethod.PRIVATE_KEY_JWT.equals(clientAuthenticationMethod)){{color} {color:#4c9aff} clientAuthentication = new PrivateKeyJWT(clientId, tokenEndpoint, jwsAlgorithm, rsaPrivateKey, keyId, jcaProvider); {color} {color:#4c9aff}} else if (ClientAuthenticationMethod.CLIENT_SECRET_POST.equals(clientAuthenticationMethod)) {{color} {color:#4c9aff} clientAuthentication = new ClientSecretPost(clientId, clientSecret); {color} {color:#4c9aff}} else { {color} {color:#4c9aff}clientAuthentication = new ClientSecretBasic(clientId, clientSecret); {color} {color:#4c9aff}} {color} # ## Encode and sign the JWT token with the private key, conforming to RFC 7523, section 2.2 and pass the signed token within the client_assertion request parameter along with the client_assertion_type. {color:#4c9aff}POST http://<keycloak-host>:<port>/auth/realms/<keycloak-realm>/protocol/openid-connect/token HTTP/1.1 Content-Type: application/x-www-form-urlencoded{color} {color:#4c9aff} client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer& client_assertion=eyJraWQiOiJkMlY2LS1OUG....hTMfA& grant_type=authorization_code& code=9ba8d85b-...-c7a6fb6dae55 {color} # The Authorization Server will use the client's public key or cert to verify the signature of th JWT and issues the token > Oidc Identity Provider should support assertions as client credentials for > authenticating against the token endpoint > -------------------------------------------------------------------------------------------------------------------- > > Key: NIFI-8406 > URL: https://issues.apache.org/jira/browse/NIFI-8406 > Project: Apache NiFi > Issue Type: Improvement > Components: Core Framework, Security > Affects Versions: 1.11.4 > Reporter: Vijay Jammi > Priority: Major > Labels: OIDC, Security, assertion > > The current oidc client authentication methods (client_secret_post, > client_secret_basic) require client credentials (client_secret) to be stored > as plain text on the client's filesystem, which could also be inadvertently > checked into source control system. > Due to these and other security considerations, we should be able to use > assertions as client credentials for authenticating against the token > endpoint. > While using assertions an oidc client will include client_assertion and > client_assertion_type parameters instead of passing the client_secret for > authentication. > For further details can be found within the below OAuth 2.0 Client > Authentication specs > # [RFC 7523, Section 2.2 (Using JWTs for Client > Authentication)|https://tools.ietf.org/html/rfc7523#section-2.2] > # [RFC 7521 (Using Assertions for Client > Authentication)|https://tools.ietf.org/html/rfc7521#section-4.2]. > > High level summary of the changes that might need to be made for assertion > based client authentication. > # Generate a pair of private and public key which can be made available to > Nifi via a keystore on the filesystem. > # Make the public key or cert available to the Authorization Server. > Alternatively to allow key rotations, we could configure a JWKS URL within > Nifi to allow the authorization server download the public key using the > keyId (kid). > # While building the token request against the token endpoint > ## Need StandardOidcIdentityProvider to provide a way to build a > private_key_jwt based client authentication in addition to the existing > client_secret_basic, client_secret_post. > {code:java} > if > (ClientAuthenticationMethod.PRIVATE_KEY_JWT.equals(clientAuthenticationMethod)){ > clientAuthentication = new PrivateKeyJWT(clientId, tokenEndpoint, > jwsAlgorithm, rsaPrivateKey, keyId, jcaProvider);} else if > (ClientAuthenticationMethod.CLIENT_SECRET_POST.equals(clientAuthenticationMethod)) > { clientAuthentication = new ClientSecretPost(clientId, clientSecret);} else > { clientAuthentication = new ClientSecretBasic(clientId, clientSecret);} > {code} > ## Encode and sign the JWT token with the private key, conforming to RFC > 7523, section 2.2 and pass the signed token within the client_assertion > request parameter along with the client_assertion_type. > {code:java} > POST > http://<keycloak-host>:<port>/auth/realms/<keycloak-realm>/protocol/openid-connect/token > HTTP/1.1 > Content-Type: > application/x-www-form-urlencodedclient_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer& > client_assertion=eyJraWQiOiJkMlY2LS1OUG....hTMfA& > grant_type=authorization_code& > code=9ba8d85b-...-c7a6fb6dae55 > {code} > # The Authorization Server will use the client's public key or cert to > verify the signature of the JWT and issues the token > > > -- This message was sent by Atlassian Jira (v8.3.4#803005)