Hashicorp Vault: 400 Bad Request Accept header is missing - jwt

I have enabled jwt auth on my dev vault instance
vault auth enable jwt
Success! Enabled jwt auth method at: jwt/
However, when I try to configure the jwks_url for the jwt auth I get the following error
➜ vault write auth/jwt/config jwks_url="<jwks_url>"
Error writing data to auth/jwt/config: Error making API request.
URL: PUT http://127.0.0.1:8200/v1/auth/jwt/config
Code: 400. Errors:
* error checking jwks URL: fetching keys oidc: get keys failed: 400 Bad Request Accept header is missing
Any idea what might I be doing wrong?

Related

Using Keycloak for defining subjects in policies in Eclispe Ditto

My current use case is: I have a frontend application where a user is logged in via Keycloak. I would like to implement some parts of the Ditto HTTP API in this frontend (https://www.eclipse.org/ditto/http-api-doc.html).
For example I want to create policies (https://www.eclipse.org/ditto/basic-policy.html) for authorization. I've read in the documentation that one can use an OpenID Connect compliant provider and the form is : (https://www.eclipse.org/ditto/basic-policy.html#who-can-be-addressed).
There's basic auth example at the bottom of the page, it seems to use the username in this case.
{
"policyId": "my.namespace:policy-a",
"entries": {
"owner": {
"subjects": {
"nginx:ditto": {
"type": "nginx basic auth user"
}
},
...
}
My question is: What exactly would be the sub-claim if I want to use Keycloak? Is it also the username of the user I want to grant rights to? And how would I get this in my frontend where I want to specify the policy for sending it to Ditto afterwards?
UPDATE 1:
I tried to enable keycloak authentication in Ditto like suggested below and as stated here: https://www.eclipse.org/ditto/installation-operating.html#openid-connect
Because I'm running Ditto with Docker Compose, I added the following line as an environment variable in ditto/deployment/docker/docker-compose.yml in line 136: - Dditto.gateway.authentication.oauth.openid-connect-issuers.keycloak=http://localhost:8090/auth/realms/twin
This URL is the same as in the issuer claim of my token which I'm receiving from keycloak.
Now if I try to make for example a post request with Postman to {{basePath}}/things I get the following error:
<html>
<head>
<title>401 Authorization Required</title>
</head>
<body bgcolor="white">
<center>
<h1>401 Authorization Required</h1>
</center>
<hr>
<center>nginx/1.13.12</center>
</body>
</html>
I chose Bearer Token as Auth in Postman and pasted a fresh token. Basic Auth with the default ditto user is still working.
Do I have to specify the new subject/my user in Ditto before?
UPDATE 2:
I managed to turn basic auth in nginx off by commenting out "auth_basic" and "auth_basic_user_file" in nginx.conf!
It seems to be forwarded to Ditto now, because now I get the following error with Postman:
{
"status": 401,
"error": "gateway:jwt.issuer.notsupported",
"message": "The JWT issuer 'localhost:8090/auth/realms/twin' is not supported.",
"description": "Check if your JWT is correct."
}
UPDATE 3:
My configuration in gateway.conf looks now like this:
oauth {
protocol = "http"
openid-connect-issuers = {
keycloak = "localhost:8090/auth/realms/twin"
}
}
I also tried to add these two lines in the docker-compose.yml:
- Dditto.gateway.authentication.oauth.protocol=http
- Dditto.gateway.authentication.oauth.openid-connect-issuers.keycloak=localhost:8090/auth/realms/twin
Unfortunately I still had no luck, same error as above :/ It seems like an user had a similar problem with keycloak before (https://gitter.im/eclipse/ditto?at=5de3ff186a85195b9edcb1a6), but sadly he mentioned no solution.
EDIT: It turns out that I specified these variables in the wrong way, the correct solution is to add them as part of command: java ... more info here
UPDATE 4:
I tried to build Ditto locally instead of using the latest docker images and I think I might be one step further now, it seems like my oauth config is working. I get now:
{
"status": 503,
"error": "gateway:publickey.provider.unavailable",
"message": "The public key provider is not available.",
"description": "If after retry it is still unavailable, please contact the service team."
}
The error message from the log is:
gateway_1 | 2020-11-05 15:33:18,669 WARN [] o.e.d.s.g.s.a.j.DittoPublicKeyProvider - Got Exception from discovery endpoint <http://localhost:8090/auth/realms/twin/.well-known/openid-configuration>.
gateway_1 | akka.stream.StreamTcpException: Tcp command [Connect(localhost:8090,None,List(),Some(10 seconds),true)] failed because of java.net.ConnectException: Connection refused
gateway_1 | Caused by: java.net.ConnectException: Connection refused
...
gateway_1 | java.util.concurrent.CompletionException: org.eclipse.ditto.services.gateway.security.authentication.jwt.PublicKeyProviderUnavailableException [message='The public key provider is not available.', errorCode=gateway:publickey.provider.unavailable, statusCode=SERVICE_UNAVAILABLE, description='If after retry it is still unavailable, please contact the service team.', href=null, dittoHeaders=ImmutableDittoHeaders [{}]]
...
gateway_1 | Caused by: org.eclipse.ditto.services.gateway.security.authentication.jwt.PublicKeyProviderUnavailableException [message='The public key provider is not available.', errorCode=gateway:publickey.provider.unavailable, statusCode=SERVICE_UNAVAILABLE, description='If after retry it is still unavailable, please contact the service team.', href=null, dittoHeaders=ImmutableDittoHeaders [{}]]
...
gateway_1 | Caused by: akka.stream.StreamTcpException: Tcp command [Connect(localhost:8090,None,List(),Some(10 seconds),true)] failed because of java.net.ConnectException: Connection refused
gateway_1 | Caused by: java.net.ConnectException: Connection refused
My keyloak is definitely running, I'm able to get tokens. If I'm opening http://localhost:8090/auth/realms/twin/.well-known/openid-configuration which is in the first error message, I'm able to see my openid-configuration from keycloak config.
Edit: It seems that my gateway container cannot reach my keycloak container, will try to figure this out.
FINAL UPDATE:
Unreachable keycloak docker container from the gateway docker container was the issue. I'm now using traefik:
Keycloak container has the following alias: keycloak.localhost
Oauth configuration in the gateway looks like this:
oauth {
protocol = "http"
openid-connect-issuers = {
keycloak = "keycloak.localhost/auth/realms/twin"
}
}
Now the gateway can find the keycloak container via the alias and I can still use the keycloak admin ui from my localhoast: http://keycloak.localhost:8090/auth/admin/
Additional info: Traefic Blog
What exactly would be the sub-claim if I want to use Keycloak?
Keycloak provides you a JWT.
A JWT is an encrypted JSON which contains multiple fields called "claims". You can check how your token looks like by visiting https://jwt.io and pasting your token there. One of those fields is called sub. This is the sub claim.
To enable your keycloak authentication in eclipse ditto you need to add the issuer to the ditto configuration.
An example can be founde here.
The address must match the URL in the issuer claim of your JWT token.
ditto.gateway.authentication {
oauth {
protocol = "http"
openid-connect-issuers = {
some-name = "localhost:8090/auth/realms/twin"
}
}
}
Is it also the username of the user I want to grant rights to?
In eclipse ditto there is not really a concept of "user names". Eclipse ditto authentication is based on authorization subjects. For the basic authentication example you provided, the authorization subject which is generated within ditto is nginx:ditto.
For JWT authentication the authorization subject is generated as a combination of the name for the open id connect issuer which you configured (in my case some-name) and the value of the sub claim. An authorization subject could look like this: some-name:8d078113-3ee5-4dbf-8db1-eb1a6cf0fe81.
And how would I get this in my frontend where I want to specify the policy for sending it to Ditto afterwards?
I'm not sure if I understand the question correctly. If you mean how to authenticate your frontend HTTP requests to eclipse ditto, you need to provide the JWT to eclipse ditto by adding it to the authorization header of your HTTP requests in the following form:
authorization: Bearer yourJWT
If you mean how you would know the sub claim of a JWT, you need to parse the JWT to a JSON object and then read the sub claim out of the payload section.

Oracle Integration Cloud: https://outlook.office.com/api/v2.0/me/sendmail returned a response status of 403 Forbidden

Tried configuring MS outlook adapter in Oracle Integration Cloud (OIC) Env.
The connection was successful. But when testing the complete implementation getting below error.
https://outlook.office.com/api/v2.0/me/sendmail returned a response status of 403 Forbidden
"error":{"code":"ErrorAccessDenied","message":"Access is denied. Check credentials and try again."
<genericRestFault><errorCode>403</errorCode><errorPath><![CDATA[POST https://outlook.office.com/api/v2.0/me/sendmail returned a response status of 403 Forbidden]]></errorPath><instance><![CDATA[{"error":{"code":"ErrorAccessDenied","message":"Access is denied. Check credentials and try again."}}]]></instance></genericRestFault>
:Application Error
I am successfully able to test the OIC Microsoft Outlook adapter to send email with attachment.When you configure the Adapter,please make sure that you have correctly set the followings.
Client Id:
Client Secret:
Scope: https://outlook.office.com/mail.send offline_access

Getting HTTP 400 when requesting access token

I am trying link Actions on Google with a 3rd party service (non-Google). I am using Google Oauth 2.0 Playground to check if I am getting the auth code and the access token. I successfully received the auth code but when requesting the access token I am receiving the following result from the response.
HTTP/1.1 400 Bad Request
Content-length: 16
Content-type: text/plain
WWW-Authenticate
I am not sure when I am doing wrong here. What does WWW-Authenticate mean?
Thanks in advance.

VK Api - Application authorization failed: refresh service token

When backend server call /method/secure.checkToken Api, it return a error message.
{
"error_code":28,
"error_msg":"Application authorization failed: refresh service token"....
}
What's mean about error_code 28?
is it mean my service token error?
This means that your application's access key is invalid
https://vk.com/dev/errors
This April VK changed access to the API. Now all requests must be signed with an application access key.

Robot Framework api test with OAUTH2 Authorization Request Header

I am trying to use the RequestsLibrary on an api thats using the OAUTH2 authentication.
Authentication is via OAUTH2 with credentials being supplied to the /v1/authtoken endpoint.
Subsequent calls to the APÍ need to have the token included as a ‘bearer’ in the ‘Authorization’ header of the http requests.
So below is the test case. The error I am getting is:
401 != 200
The credentials work ok in jmeter and a list of accounts is returned. However, I am not able to get the RF script work. Any help will be appreciated.
In the script,
Log to Console ${accessToken} returns the access token: 8ETFXTZOWQLrgsMj7c_KuCEeypdj-eO1r...
Log to Console ${token} returns: Bearer 8ETFXTZOWQLrgsMj7c_KuCEeypdj-eO1r...
*** Test Cases ***
Get authToken
Create Session hook http://xxxx.azurewebsites.net verify=${True}
${data}= Create Dictionary grant_type=client_credentials client_id=yyy-zzzz client_secret=xxxxxxxxxxxxxxx
${headers}= Create Dictionary Content-Type=application/x-www-form-urlencoded
${resp}= post request hook /v1/authtoken data=${data} headers=${headers}
Should Be Equal As Strings ${resp.status_code} 200
Dictionary Should Contain Value ${resp.json()} bearer
${accessToken}= evaluate $resp.json().get("access_token")
Log to Console ${accessToken}
${Bearer}= Set Variable Bearer
${token}= catenate Bearer ${accessToken}
Log to Console ${token}
${headers}= Create Dictionary Authorization=${token}
${resp1}= get request hook /v1/integration/accounts headers=${headers}
Should Be Equal As Strings ${resp1.status_code} 200
#Log to Console ${resp1.json()}
I am using OAuth 2.0 authentication as well for my salesforce automation.
My first answer would be to skip client based authentication and switch to username/password based authentication
Get authToken by Password Authentication
RequestsLibrary.Create Session hook https://<url>/services/oauth2 verify=${True}
${data}= Create Dictionary grant_type=password client_id=1abc client_secret=2abc username=test#test.com password=keypass
${headers}= Create Dictionary Content-Type=application/x-www-form-urlencoded
${resp}= RequestsLibrary.Post Request hook /token data=${data} headers=${headers}
Should Be Equal As Strings ${resp.status_code} 200
${accessToken}= evaluate $resp.json().get("access_token")
Log to Console ${accessToken}
If you are using client based or web based authentication, there will be a login screen that will be used by the user to enter their username/password to authorise the app to send requests on its behalf. Have a look at these pages for more information as they primarily discuss about using either refresh tokens or skipping the user prompt altogether.
Why does Google OAuth2 re-ask user for permission when i send them to auth url again
https://salesforce.stackexchange.com/questions/785/authenticate-3rd-party-application-with-oauth2
I have added the new answer for this question.
RequestsLibrary.Create Session OA2 <Your Server URL> verify=${True}
${data}= Create Dictionary Token_Name=TestTokenname grant_type=<grant type> client_Id=<your Id> Client_Secret=<Your client secret> scope=<your scpe>
${headers}= Create Dictionary Content-Type=application/x-www-form-urlencoded
${resp}= RequestsLibrary.Post Request OA2 identity/connect/token data=${data} headers=${headers}
BuiltIn.Log To Console ${resp}
BuiltIn.Log To Console ${resp.status_code}
Should Be Equal As Strings ${resp.status_code} 200
Dictionary Should Contain Value ${resp.json()} Testtokenname
${accessToken}= evaluate $resp.json().get("access_token")
BuiltIn.Log to Console ${accessToken}
${token}= catenate Bearer ${accessToken}
BuiltIn.Log to Console ${token}
${headers1}= Create Dictionary Authorization=${token}
RequestsLibrary.Create Session GT <Your Server URL> verify=${True}
${resp}= RequestsLibrary.Get Request GT <Your API URL> headers=${headers1}
Should Be Equal As Strings ${resp.status_code} 200