Support Questions

Find answers, ask questions, and share your expertise

Apache Nifi Rest Api Authorization

avatar
Contributor

I want to stop a processor on the same machine  with restApi but I get an authorization error when I call the rest api.I can solve this problem with bearer token, but since the token has expired, I need to change the bearer  token manually again.Is there a way I can authorize automatically?

  • I am using the executeScript processor when calling the API.Script engine is Groovy.
  • My Nifi version 1.23.2 and Nifi is secure  and not clustered.I login with ldap on UI.

 

plapla_0-1708509284146.png

This is the part where I call the API in the script:

def post = new URL(NifiBaseUrl.value + NifiComponentId.value).openConnection();
post.setSSLSocketFactory(sslContext.getSocketFactory())
post.setRequestMethod("PUT")
post.setDoOutput(true)
post.setRequestProperty("Content-Type", "application/json")
post.getOutputStream().write(content.getBytes("UTF-8"));
post.getResponseCode()

 

Error:

java.io.IOException: Server returned HTTP response code: 401 for URL

1 ACCEPTED SOLUTION

avatar
Master Mentor

@plapla 

What you have encountered is not an error.  NiFi is telling you that the client/user Identity derived from the clientAuth certificate in your keystore is not authorized for them mentioned NiFi authorization policy that is needed for the specific rest call being made.

You'll need to authorize client/user for "execute code" restricted components policy:
NiFi UI --> global menu --> policies --> access restricted components --> execute code

If you found any of the suggestions/solutions provided helped you with your issue, please take a moment to login and click "Accept as Solution" on one or more of them that helped.

Thank you,
Matt

View solution in original post

11 REPLIES 11

avatar
Super Guru

Hi ,

Have you tried using the InvokeHttp processor for this instead of writing a script ? The thing is if you have nifi secured you have to pass the SSL Context to make an authorized call . I know when I try to call the nifi api to start\stop a processor using the invokehttp I have to pass the SSL Context Service, otherwise I will get the 401 error.

 

If you find this is helpful please accept solution.

Thanks

avatar
Contributor

Hi @SAMSAL ,

Is SSL Context Service alone sufficient or is it necessary to purchase tokens via invokeHttp first?

avatar
Super Guru

If you have your nifi instance secure with truststore & keystore , you can use the same for creating SSL Context Service using StandardSSLContextService or StandardRestrictedSSLContextService . Either services you need to populate the truststore & keystore information that you used to secure nifi, but you have to pass SSL information to the code in your executescript processor. There is a way to access controller services from ExecuteScript, refere to part3 of : https://community.cloudera.com/t5/Community-Articles/ExecuteScript-Cookbook-part-2/ta-p/249018

But then again why not use the out of the box InvokeHttp processor , and pass the created service to the SSL Context Service property.

 

 

 

avatar
Master Mentor

@plapla 

TLS based user/client authentication does not use tokens. You just need to make sure the clientAuth PrivateKey certificate in the keystore used is both trusted by the Nifi's configured truststore in the nifi.properties file and authorized against the NiFi policy(s) required to access the specific rest-api endpoint requested.

If you found any of the suggestions/solutions provided helped you with your issue, please take a moment to login and click "Accept as Solution" on one or more of them that helped.

Thank you,
Matt

avatar
New Contributor

Do not need to SSL Context (in my case Secure Nifi 1.14.0) , i tried it, just put certificate files, where it supposed to stay. U can get Token first within InvokeHttpRequest and set it new Attribute (named accessToken)  on Update Attribute process, then add new attribute to second InvokeHttpRequest (named Authorization --> Bearer ${accessToken}). thats it.

avatar
Master Mentor

@plapla 

A secured NiFi is secured over HTTPS which means a TLS exchange happens to secure the connection with NiFi.  A secured NiFi will always support a mutual TLS exchange.

If no other methods of user authentication are configured, NiFI will "REQUIRE" a clientAuth certificate be presented in the TLS exchange with NiFi.

When NiFi is configured with an additional user authentication method (for example, you have enabled the ldap-provider for user authentication), NiFi will "WANT" a clientAuth certificate in the TLS exchange.  If a clientAuth certificate is not provided in the TLS exchange/handshake, NiFi moves on to the next authentication method configured.

The ldap-provider will require obtaining a user token as you saw that then needs to be included with all subsequent rest-api calls.  And you are correct that the token does expire.  That is why it is easier and a better option to use mutual TLS based authentication when doing automation like this.  The clientAuth certificate is simply included in every rest-api request and there is no token involved.  

About the ClientAuth certificate...  The full DN from the certificate is what is used to identify the user.  The full DN is evaluated against any identity.mapping.pattern.xxx properties configured in the nifi.properties file.  If a configured pattern (java regex) matches against the DN, the identity.mapping.value.xxx and identity.mapping.transform.xxx is applied.  These identity mappings are often used to trim the CN value from the complete DN.  The resulting string after any mappings are applied is what is then used to look up authorizations for that client/user.

If you found any of the suggestions/solutions provided helped you with your issue, please take a moment to login and click "Accept as Solution" on one or more of them that helped.

Thank you,
Matt



avatar
Contributor

Hi @SAMSAL , @MattWho ,

As I said, nifi is secure and authenticates via ldap when logging into the frontend.

I defined StandartRestrictedSslContextService on controller services.StandardRestrictedSslContextService uses the trustStore and keyStore files I created before. The same files are defined in nifi.properties.

When I call the API with invokeHttp using this service, I get the following error:Unable to modify Components requiring additional permission: execute code. Contact the system administrator.

If I send a userToken with the authorization parameter to the invokeHttp processor, I get a successful response.

Since using userToken complicates the flow, it would be better to use SSL service.But I have no idea how to overcome the error I shared above.

plapla_0-1708936559100.pngplapla_1-1708936612014.png

 

avatar
Master Mentor

@plapla 

What you have encountered is not an error.  NiFi is telling you that the client/user Identity derived from the clientAuth certificate in your keystore is not authorized for them mentioned NiFi authorization policy that is needed for the specific rest call being made.

You'll need to authorize client/user for "execute code" restricted components policy:
NiFi UI --> global menu --> policies --> access restricted components --> execute code

If you found any of the suggestions/solutions provided helped you with your issue, please take a moment to login and click "Accept as Solution" on one or more of them that helped.

Thank you,
Matt

avatar
New Contributor

this policy menu itself is not there