{"action":"closed","issue":{"url":"https://api.github.com/repos/apigee-127/volos/issues/95","repository_url":"https://api.github.com/repos/apigee-127/volos","labels_url":"https://api.github.com/repos/apigee-127/volos/issues/95/labels{/name}","comments_url":"https://api.github.com/repos/apigee-127/volos/issues/95/comments","events_url":"https://api.github.com/repos/apigee-127/volos/issues/95/events","html_url":"https://github.com/apigee-127/volos/issues/95","id":142077877,"number":95,"title":"getIdAndSecret header vs body credentials validation order","user":{"login":"jcferrer","id":4763440,"avatar_url":"https://avatars.githubusercontent.com/u/4763440?v=3","gravatar_id":"","url":"https://api.github.com/users/jcferrer","html_url":"https://github.com/jcferrer","followers_url":"https://api.github.com/users/jcferrer/followers","following_url":"https://api.github.com/users/jcferrer/following{/other_user}","gists_url":"https://api.github.com/users/jcferrer/gists{/gist_id}","starred_url":"https://api.github.com/users/jcferrer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jcferrer/subscriptions","organizations_url":"https://api.github.com/users/jcferrer/orgs","repos_url":"https://api.github.com/users/jcferrer/repos","events_url":"https://api.github.com/users/jcferrer/events{/privacy}","received_events_url":"https://api.github.com/users/jcferrer/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2016-03-19T16:15:01Z","updated_at":"2016-03-29T20:51:23Z","closed_at":"2016-03-29T20:51:23Z","body":"Scott,\r\n\r\nI found this edge case. Let me give some background first (kind of long, but please read).\r\n\r\nI am using a127-magic with volos-oauth-redis and swagger-tools-embedded swagger-ui. I have an oauth2 app, running on this framework that basically exposes the basic oauth operations (authorize, access_token, refresh, invalidate). \r\nThe POST /access_token takes the expected body format:\r\n````\r\n{\r\n  \"grant_type\": \"client_credentials\",\r\n  \"client_id\": \"myId\",\r\n  \"client_secret\": \"mySecret\"\r\n}\r\n````\r\nAll good so far. No issues.\r\n\r\nTo protect this end point from unauthorized external access, I decided to set Basic Authentication challenge using Nginx in front of my app.\r\n\r\nThis is where I found a problem. After passing the Swagger-UI Basic Auth challenge, and trying to POST a client request body to generate a token, I found the UI kept popping up the credentials window, even though I entered them while accessing the UI the first time.\r\n\r\nAfter spending a lot of time looking everywhere without success, I then found that the function ``` getIdAndSecret``` located the ```oauth.js``` file, favors the presence of the Authorization Header for Basic Auth credentials, over the credentials provided in the request body. In my case, this is an issue, since the Authorization Header is already carrying the Basic Auth credentials entered when first landing on the UI, so the ones I provide in the request body are not taken, resulting in an invalid_client error.\r\n\r\nHere's the function:\r\n\r\n```\r\nfunction getIdAndSecret(authorizeHeader, parsedBody) {\r\n  // 2.3.1: Client id and secret may be in Basic format, or in the request body\r\n  var clientId;\r\n  var clientSecret;\r\n  if (authorizeHeader) {\r\n    var parsedHeader = /Basic (.+)/.exec(authorizeHeader);\r\n    if (!parsedHeader) {\r\n      return null;\r\n    }\r\n    if (parsedHeader.length < 2) {\r\n      return null;\r\n    }\r\n\r\n    var decodedHeader = new Buffer(parsedHeader[1], 'base64').toString();\r\n    var decoded = /([^:]+):([^:]+)/.exec(decodedHeader);\r\n    if (!decoded || decoded.length < 3) {\r\n      return null;\r\n    }\r\n\r\n    clientId = decoded[1];\r\n    clientSecret = decoded[2];\r\n  } else {\r\n    clientId = parsedBody.client_id;\r\n    clientSecret = parsedBody.client_secret;\r\n  }\r\n  if (clientId && clientSecret) {\r\n    return [clientId, clientSecret];\r\n  }\r\n  return null;\r\n}\r\n```\r\n\r\nFor now to solve the problem I fixed the condition to be:\r\n\r\n```\r\n if (authorizeHeader && !parsedBody.client_id && !parsedBody.client_secret) {\r\n```\r\n\r\nin order to force using the body credentials if present. I am sure you will find a better way to do it though. \r\n\r\nDo you think you can reverse the order of checking, favoring the body credentials if present?\r\n\r\nLet me know what you think.\r\n\r\nThanks\r\n\r\nJC\r\n\r\n"}}