Receiving 204 response but no cookie with the /api/security/v1/login endpoint

When making a post request to /api/security/v1/login with valid credentials, I get a 204 (empty response), and no cookie :cookie: However, when I send invalid credentials, I get a 401 response.

Request
POST /api/security/v1/login HTTP/1.1
Host: DOMAN:5601
kbn-version: 6.5.4
Content-Type: application/json
Cache-Control: no-cache
{
"password": "validPassword",
"username": "validUsername"
}

Response
Status: 204 (No Content)

cache-control → no-cache
connection → close
date → Thu, 07 Feb 2019 19:45:47 GMT
kbn-name → kibana
kbn-xpack-sig → 3d56ded3222e4719c85f75a592fb4375
vary → accept-encoding

If I send incorrect credentials (password or username), I get a 401 response, which is exactly what you'd expect. If Kibana is correctly recognising credentials, I can only assume that our environment is configured correctly?

Request
POST /api/security/v1/login HTTP/1.1
Host: DOMAN:5601
kbn-version: 6.5.4
Content-Type: application/json
Cache-Control: no-cache
{
"password": "invalidPassword",
"username": "invalidUsername"
}

Response
{
"statusCode": 401,
"error": "Unauthorized",
"message": "[security_exception] unable to authenticate user [invalidUsername] for REST request [/_xpack/security/_authenticate], with { header={ WWW-Authenticate="Basic realm=\"security\" charset=\"UTF-8\"" } } :: {"path":"/_xpack/security/_authenticate","query":{},"statusCode":401,"response":"{\"error\":{\"root_cause\":[{\"type\":\"security_exception\",\"reason\":\"unable to authenticate user [invalidUsername] for REST request [/_xpack/security/_authenticate]\",\"header\":{\"WWW-Authenticate\":\"Basic realm=\\\"security\\\" charset=\\\"UTF-8\\\"\"}}],\"type\":\"security_exception\",\"reason\":\"unable to authenticate user [invalidUsername] for REST request [/_xpack/security/_authenticate]\",\"header\":{\"WWW-Authenticate\":\"Basic realm=\\\"security\\\" charset=\\\"UTF-8\\\"\"}},\"status\":401}","wwwAuthenticateDirective":"Basic realm=\"security\" charset=\"UTF-8\""}"
}

QUESTION
Do you have to configure the Kibana API in some way to respond with a cookie when using this endpoint? And if so... could someone please provide an example to achieve this?

Thanks in advance :+1:t2:

Current approach is based off of this answer...

UPDATE ONE

Have been digging around the Kibana src code and found the file that processed authentication requests to the endpoint mentioned above. Here'e the route that handles it... and I can't find any reference to a cookie being created and sent back. Am I missing something here?!

server.route({
    method: 'POST',
    path: '/api/security/v1/login',
    config: {
      auth: false,
      validate: {
        payload: {
          username: Joi.string().required(),
          password: Joi.string().required()
        }
      },
      response: {
        emptyStatusCode: 204,
      }
    },
    async handler(request, reply) {
      const { username, password } = request.payload;

      try {
        console.log('MY DEBUG', username, password)
        const authenticationResult = await server.plugins.security.authenticate(
          BasicCredentials.decorateRequest(request, username, password)
        );

        if (!authenticationResult.succeeded()) {
          return reply(Boom.unauthorized(authenticationResult.error));
        }

        console.log('AUTHENTICATION SUCCEEDED, WHERES MY DAMN COOKIE?!')

        const { authorization } = server.plugins.security;
        if (!authorization.mode.useRbacForRequest(request)) {
          const msg = `${username} relies on index privileges on the Kibana index. This is deprecated and will be removed in Kibana 7.0`;
          server.log(['warning', 'deprecated', 'security'], msg);
        }

        return reply.continue({ credentials: authenticationResult.user });
      } catch(err) {
        return reply(wrapError(err));
      }
    }
  });

I haven't looked at the security code in a while, and it's changed a ton since I was last in there. I'm not sure why you get an empty 204 response with no header information... as far as I know we still use cookies to handle the session.

Here'e the route that handles it... and I can't find any reference to a cookie being created and sent back. Am I missing something here?!

It's a bit tricky to follow how this works. Since our server uses Hapi (node framework), we use the routing hooks available there to deal with the auth part of handling the request. This uses a library called hapi-auth-cookie, and the code that sets that up is right here.

I'll try digging into the route stuff a little and follow up with what I find.

I just tried this locally, and it works as expected. The 204 response includes a set-cookie header that contains the session information. This happens both in the browser and also while using curl.

curl -XPOST -H "Content-Type: application/json" -H "kbn-xsrf: hello" localhost:5601/api/security/v1/login --data '{"username":"validUsername","password":"validPassword"}' -D -

That sends the header information to stdout, and you'll see the set-cookie parameter.

HTTP/1.1 204 No Content
kbn-name: kibana
kbn-xpack-sig: ce28f[..snip..]
vary: origin
cache-control: no-cache
set-cookie: sid=Fe26.2**b68af5[..snip..]; HttpOnly; Path=/
date: Tue, 12 Feb 2019 18:29:52 GMT
Connection: keep-alive

Maybe whatever tool you're using to set the request is hiding the set-cookie header from the response output?

Hi @Joe_Fleming

Thanks for getting back to me, I came back online to update the post because I was getting the cookie, but PostMan was stripping the response headers out! Agghh! So you were right :slight_smile:

However, I do now have a separate issue, now I have the cookie set on the client, I am getting the TOO_MANY_REDIRECTS error. I raised this question on StackOverflow as I wasn't sure if I would get a response on Elastic forum... I need to be more patient :wink:

Would you mind taking a look and let me know what you think? I can recreate the question as a Topic on here if you'd prefer though?

Thanks again

Hrm, I'm not sure what's causing the redirect issue. For what it's worth, I was seeing something similar locally, just using Kibana. I would log in, Kibana would take me to the app I was trying to load, it would flash up briefly, redirect again, and then send me back to the login page. But I'm not familiar enough with how everything works to know what's causing that to happen without diving deep into the code to figure it out, and what I was seeing might be totally different from the issue you are seeing.

@Brandon_Kobel maybe you can shed a little light on what's causing the redirect here?

@an0nc0d3r the login endpoint isn't intended to be used in this manner, and it's definitely "unsupported". Generally, our lack of CORS support prevents this behavior, but you've overcoming it by your use of sub-domains. The cookie which Kibana replies with generally sets the httpOnly flag, and the secure flag (when hosted over https), in addition to the domain. If any of the settings differ for the cookie which you're trying to force Kibana to use, you'll see 2 cookies being submitted and behavior similar to what you're seeing.

2 Likes

@Brandon_Kobel... Got it one you absolute star! I was setting the Path to /, which mustn't of been set on the cookie coming out of Kibana.

As this approach is unsupported, though, can you suggest a supported way to achieve the desired goal?

Thanks again.

@an0nc0d3r if you're looking to do SSO, using SAML with an IdP is the best answer we currently have.

Would you mind elaborating on what you're trying to accomplish at a high level?

@Brandon_Kobel My previous response was premature :frowning:

I think I had a fluke occurrence of it working as I am now seeing the same thing occurring after clearing cookies and refreshing the page.

I'm attempting to embed customer specific Kibana dashboards inside an iFrame in an Express application. Customers dashboards are created inside their individual spaces and have a user set up with appropriate permissions/role for viewing dashboards. Kibana is protected using X-Pack, requiring users to login.

This would require the user to log in twice, once to login into the application and again to access their Kibana dashboards, however, logging in just once to our application is the goal.

Looks like I'll be taking a closer look at SAML.

@an0nc0d3r SAML should do exactly what you're looking for. The ES docs for getting started using SAML are really good: https://www.elastic.co/guide/en/elasticsearch/reference/current/configuring-saml-realm.html

The other option, which has it's limitations, is to use a reverse-proxy like NGINX to hard-code the credentials that are passed to Elasticsearch. This isn't great because anyone who can access the reverse proxy can automatically get access to Kibana, so it's really only good for providing the equivalent of "anonymous access".

There is one other option at the moment, and that's to use something like an OAuth2 proxy to do impersonation: https://www.elastic.co/blog/user-impersonation-with-x-pack-integrating-third-party-auth-with-kibana

We're working on additional auth providers for ES/Kibana, so if none of this satisfies your needs, please let me know and I can direct you towards our feature requests which helps us prioritize the addition of these providers.

Thanks the info @Brandon_Kobel.

I'll start making my way through the docs!

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.