operations |
comment | "parent_author":"",<br>"parent_permlink":"kibana",<br>"author":"r351574nc3",<br>"permlink":"effing-better-auth-with-oauth2-for-elk",<br>"title":"Effing Better Auth with Oauth2 for\u00a0ELK",<br>"body":"Don\u2019t be misled by the title. You may be thinking,<br> \u201cFinally! Instructions on how to implement Oauth2 with X-pack.\u201d Ok,<br> it is about that,<br> but first you should know that there is no support for Oauth2 with X-pack. Stop looking for it. This is about how you implement it yourself the hard way. Strap in folks. This is going to be a ride for the ages.\n\nI encountered this problem personally and I could not find any solution in forums,<br> documentation (Ha!),<br> or blogs. I really \nlooked a lot and hard. The best I could find are some forum posts that were closed with no resolution and \n[X-Pack with OAuth Authentication (https:\/\/discuss.elastic.co\/t\/x-pack-with-oauth-authentication\/72015\/2) which led me to this\ngem [Integrating with Other Authentication Systems (https:\/\/www.elastic.co\/guide\/en\/x-pack\/current\/custom-realms.html)\n\nThose are just for reference. Observe and familiarize yourselves with the contents,<br> but believe me when I say,<br> \n> These are not the droids you are looking for\n\nSome of you may be reading this and hadn't yet come across the links given above. Some of you already have and arrived at the\nsame conclusion as I have. If you are already familiar with the problem,<br> just skip to [the answer (#the-answer). If you are new\nthis issue and need some explanation or at least some convincing about the solution,<br> read on.\n\n## Oauth2 Refresher\n\nBefore getting to the real meat of things,<br> we first need to understand (big picture) how OAuth2 works and how it fits in with X-Pack and the ELK stack.\n\nRather than get into technical details an history of what OAuth2 is and why to use it,<br> I'm going to go straight into the flow to illustrate what exactly is happening during OAuth2 authentication process.\n\n### OAuth2 is *Not* Authentication\n\nOAuth2 flow is actually what occurs after authentication. Authentication is the process of being challenged for credentials (a login screen),<br> then verifying those credentials. Oauth2 does not use standard credentials. Access is managed through a session token.\n\n### OAuth2 Flow\n\nDue to the nature of the web OAuth2 is connection-less. That is,<br> it isn't something that just stays open like a VPN. Instead,<br> numerous requests and responses are made for verification. This is referred to as the *oauth2 flow*. \n\n![Oauth2-flow.png (https:\/\/steemitimages.com\/DQmUDbhMQUxSrsVXWJ6RYX6gpTZAfdVW878oghPmthforCQ\/Oauth2-flow.png)\n\n1. **Auth Initialization** request an oauth2 auth from the application to be accessed. The auth request usually consists of (grant type,<br> code,<br> and request uri)\n1. **Authentication** this is actually outside of the Oauth2 flow,<br> but we are going to start here. Normally,<br> you authenticate some way (Oauth2 is not authentication,<br> it's for authorization).\n1. **Start flow** now that authentication is complete flow begins.\n1. **Client Verification Request** is what the application will now try to do. It will actually send a request back to the client (*Note: Remember this part. It will be important later.*). The request contains a *code* (the same one sent from the client originally to the oauth2 provider.)\n1. **Client Verification Response** will now take the same *code* given in the previous step and compare it against the code that was sent.\n1. **Token Request** once the code is verified and everyone agrees they are who they say they are (sounds like some shady backroom deal),<br> the application will request a token from the Oauth2 provider. It will make a request with the client id,<br> client secret,<br> credentials type,<br> and scope as parameters for the token. The client id and client secret are specific to the application. The user has no notions about what this is or what it's for. It is kept hidden from the user.\n1. **Token Response** the Oauth2 provider will not respond back to the client with an access token as part of the response payload. This token can be used within a `Authorization: Bearer` HTTP header to whatever service within the Oauth2 domain that it needs access to. This token can be saved to the client session,<br> and reused as long as the user remains logged in.\n\n## X-Pack: How it works\n\nNow that we understand a bit how OAuth2 works,<br> let's have a look into X-Pack and see exactly why these two are in conflict.\n\n### X-Pack Resides in Elasticsearch\n\nX-Pack is actually a plugin for Elasticsearch. X-Pack has its own set of extensions that can be installed; however,<br> it is basically just Elasticsearch. That means it runs within Netty and produces\/consumes HTTP requests.\n\nFor reference,<br> here is a link to the [X-Pack Security API (https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/6.0\/security-api-authenticate.html). From the examples,<br> you can see that logging in with X-Pack is as simple as `_xpack\/security\/_authenticate`. Unlike OAuth2,<br> it is only one request. X-Pack only supports Basic Authorization which means you simply make a `GET` request with the `Authorization: Basic` header. If your response is anything other than status `200`,<br> it failed authentication. Pretty simple.\n\n### Too Simple\n\nThis is exactly why it cannot work with Oauth2. The normal login process for kibana is a user provides Username\/Password credentials at a login screen. Instead of `POST` of this information to a form\n\n1. A REST request is sent to (not X-Pack) Kibana containing the Username\/Password credentials\n1. Kibana's builtin X-Pack client then sends a request to X-Pack for authentication at `_xpack\/security\/_authenticate`\n1. The response is handled and authz details are then stored in session state\n1. Kibana then re-requests the `\/` main page which loads session data and skips the login\n\n> **To recap** The login page doesn't make a `POST`. Instead it makes a REST call,<br> then reloads the main page. This is important because it does not follow a flow. It just loops itself. It's also important to note that a REST call is what's actually authorizing. This means,<br> the login page basically throws auth over a wall and waits to see if anything gets thrown back.\n\n![ (https:\/\/memegenerator.net\/img\/images\/600x600\/2726051\/face-palm.jpg)\n\n^^ **EXACTLY WHY OAUTH2 CAN'T WORK**\n\n> Read on for more details.\n\n### OAuth2 is for Client\/User Authorization\n\nThat is,<br> it requires a user on one end to provide information. You can do just server-to-server authorization; however,<br> we are trying to add OAuth2 to kibana. It will not serve use to user server-to-server. \n\n[Some solutions (https:\/\/www.elastic.co\/blog\/user-impersonation-with-x-pack-integrating-third-party-auth-with-kibana) actually suggest this as an answer by layering *impersonation* on top of that. How does server-to-server authz with user impersonation not sound like absolute h4x0ry? It's just silly. Let's pretend we didn't hear that silliness and try to do things correctly just this once.\n\n### X-pack is for Service Authentication and Authorization\n\nX-Pack handles simple credentials over HTTP because it's assuming communication from another service (like the X-pack client embedded into kibana).\n\nIt can't work because \n1. X-pack is Authentication and Authorization (Oauth2 is just Authorization)\n1. Kibana has no way to get a response from X-pack other than the session. \n1. Third-party auth providers (SSO for example) cannot gain access to X-pack\n1. OAuth2 flow requires redirect to the Authentication provider for user input\n1. OAuth2 flow requires client verification by sending a request back to a redirect uri\n1. OAuth2 flow returns an authorization token in the HTTP response (not a cookie)\n\n## The Answer\n\nOk,<br> now that we're all familiar with the problem... It seems hopeless,<br> right? It's not. The solution is actually very simple. Here's why:\n\n### Kibana is built on HapiJS\n\n[HapiJS (https:\/\/github.com\/hapijs\/hapi) is a web application toolkit created by the folks at Walmart Labs. It comes with a plugin (Kibana is actually using it for auth) called [Bell (https:\/\/github.com\/hapijs\/bell) for Authorization and Authentication. It's rather brilliant. Most importantly,<br> it supports OAuth2 out-of-the box. This is great because you can write a plugin for Kibana that instantly will hook you up with Oauth2.\n\n### What about X-pack? \n\nThis is actually very simple. We just make our Oauth2 plugin an X-pack client. Now upon completing the Oauth2 flow,<br> we can authenticate with X-pack. I will explain how,<br> but first we will tackle the Kibana Plugin.\n\n**Here it is**\n\n![plugin-flow.png (https:\/\/steemitimages.com\/DQmV55h6jQ4o76HW3Ni7R5oi1jcoBQ4szaG8d7eqJXf2dz1\/plugin-flow.png)\n\n### Custom Kibana OAuth2 Plugin\n\nHere is the [Example Project Source (https:\/\/github.com\/r351574nc3\/sample-kibana-oauth-plugin). \n\n> I'll update this when I get the source up. I'm going to sleep right now.\n\n\n### Custom X-Pack Realm Extension\n\nHere is the [Example Project Source (https:\/\/github.com\/r351574nc3\/sample-xpack-oauth-plugin)\n\n\n> I'll update this when I get the source up. I'm going to sleep right now.",<br>"json_metadata":" \"tags\":[\"kibana\",<br>\"software\",<br>\"elasticsearch\",<br>\"oauth2\",<br>\"authorization\" ,<br>\"image\":[\"https:\/\/steemitimages.com\/DQmUDbhMQUxSrsVXWJ6RYX6gpTZAfdVW878oghPmthforCQ\/Oauth2-flow.png\",<br>\"https:\/\/memegenerator.net\/img\/images\/600x600\/2726051\/face-palm.jpg\",<br>\"https:\/\/steemitimages.com\/DQmV55h6jQ4o76HW3Ni7R5oi1jcoBQ4szaG8d7eqJXf2dz1\/plugin-flow.png\" ,<br>\"links\":[\"https:\/\/discuss.elastic.co\/t\/x-pack-with-oauth-authentication\/72015\/2\",<br>\"https:\/\/www.elastic.co\/guide\/en\/x-pack\/current\/custom-realms.html\",<br>\"#the-answer\",<br>\"https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/6.0\/security-api-authenticate.html\",<br>\"https:\/\/www.elastic.co\/blog\/user-impersonation-with-x-pack-integrating-third-party-auth-with-kibana\",<br>\"https:\/\/github.com\/hapijs\/hapi\",<br>\"https:\/\/github.com\/hapijs\/bell\",<br>\"https:\/\/github.com\/r351574nc3\/sample-kibana-oauth-plugin\",<br>\"https:\/\/github.com\/r351574nc3\/sample-xpack-oauth-plugin\" ,<br>\"app\":\"steemit\/0.1\",<br>\"format\":\"markdown\" " |
|