REST API 토큰 기반 인증
인증이 필요한 REST API를 개발 중입니다. 인증 자체는 HTTP를 통한 외부 웹 서비스를 통해 발생하기 때문에 반복적으로 인증 서비스를 호출하지 않도록 토큰을 분배해야한다고 생각했습니다. 첫 번째 질문에 깔끔하게 전달됩니다.
클라이언트가 각 요청에 대해 HTTP 기본 인증을 사용하고 인증 서비스 서버 측에 대한 호출을 캐싱하는 것보다 실제로 더 낫습니까?
기본 인증 솔루션은 컨텐츠 요청을 시작하기 전에 서버에 대한 전체 왕복을 요구하지 않는 이점이 있습니다. 토큰은 범위가 더 유연 할 수 있지만 (즉, 특정 리소스 나 작업에 대한 권한 만 부여 할 수 있음), 이는 단순한 사용 사례보다 OAuth 컨텍스트에 더 적합한 것으로 보입니다.
현재 토큰은 다음과 같이 획득됩니다 :
curl -X POST localhost/token --data "api_key=81169d80...
&verifier=2f5ae51a...
×tamp=1234567
&user=foo
&pass=bar"
는 api_key
, timestamp
및 verifier
모든 요청에 의해 요구된다. "검증 자"는 다음에 의해 반환됩니다.
sha1(timestamp + api_key + shared_secret)
내 의도는 알려진 당사자의 통화 만 허용하고 통화가 그대로 재사용되는 것을 방지하는 것입니다.
이것으로 충분합니까? 언더 킬? 지나침?
고객은 토큰을 가지고 다음과 같은 리소스를 얻을 수 있습니다.
curl localhost/posts?api_key=81169d80...
&verifier=81169d80...
&token=9fUyas64...
×tamp=1234567
가장 간단한 호출을 위해, 이것은 끔찍한 장황한 것 같습니다. shared_secret
추출 할 수 있다고 생각되는 iOS 응용 프로그램에 (최소한) 내장 될 것이라는 점을 고려할 때 , 이것은 잘못된 보안 감각 이상을 제공합니까?
모든 것을 분리하고 각 문제를 개별적으로 해결해 드리겠습니다.
입증
인증의 경우 baseauth는 프로토콜 수준에서 성숙한 솔루션이라는 이점이 있습니다. 이것은 많은 "나중에 잘릴 것" 문제가 이미 해결 되었음을 의미 합니다. 예를 들어 BaseAuth를 사용하면 사용자 에이전트는 비밀번호가 비밀번호이므로 캐시하지 않습니다.
인증 서버로드
서버에서 인증을 캐싱하는 대신 토큰을 사용자에게 분배하는 경우 여전히 인증 정보 캐싱과 동일한 작업을 수행합니다. 유일한 차이점은 캐싱에 대한 책임을 사용자에게 돌리는 것입니다. 이것은 이득이없는 사용자에게는 불필요한 노력처럼 보이므로 제안한대로 서버에서 투명하게 처리하는 것이 좋습니다.
전송 보안
SSL 연결을 사용할 수 있다면 이것으로 연결이 안전합니다 *. 실수로 여러 번 실행되는 것을 방지하기 위해 여러 URL을 필터링하거나 사용자에게 URL에 임의의 구성 요소 ( "nonce")를 포함하도록 요청할 수 있습니다.
url = username:key@myhost.com/api/call/nonce
이것이 가능하지 않고 전송 된 정보가 비밀이 아닌 경우 토큰 접근 방식에서 제안한대로 요청을 해시로 보호하는 것이 좋습니다. 해시는 보안을 제공하므로 사용자에게 해시를 baseauth 암호로 제공하도록 지시 할 수 있습니다. 견고성을 높이려면 타임 스탬프 대신 임의의 문자열을 "nonce"로 사용하여 재생 공격을 방지하는 것이 좋습니다 (동일한 시간 동안 두 개의 합법적 인 요청을 할 수 있음). 별도의 "공유 비밀"및 "api 키"필드를 제공하는 대신 단순히 api 키를 공유 비밀로 사용한 다음 레인보우 테이블 공격을 방지하기 위해 변경되지 않는 소금을 사용할 수 있습니다. 사용자 이름 필드는 인증의 일부이기 때문에 nonce도 넣을 수있는 좋은 장소처럼 보입니다. 이제 다음과 같이 깨끗한 호출이 있습니다.
nonce = generate_secure_password(length: 16);
one_time_key = nonce + '-' + sha1(nonce+salt+shared_key);
url = username:one_time_key@myhost.com/api/call
이것이 조금 힘들다는 것은 사실입니다. 이는 SSL과 같은 프로토콜 수준 솔루션을 사용하지 않기 때문입니다. 따라서 사용자에게 일종의 SDK를 제공하여 최소한 스스로 처리 할 필요는없는 것이 좋습니다. 당신이 이런 식으로해야한다면, 나는 보안 수준이 적절하다고 생각합니다.
안전한 비밀 저장
그것은 당신이 방해하려는 사람에 달려 있습니다. 사용자의 전화에 액세스하는 사람들이 사용자 이름으로 REST 서비스를 사용하지 못하게하려면 대상 OS에서 일종의 키링 API를 찾아 SDK (또는 구현 자)에 저장하는 것이 좋습니다. 열쇠가 있습니다. 그것이 가능하지 않다면 적어도 비밀을 암호화하고 암호화 된 데이터와 암호화 키를 별도의 장소에 저장하여 비밀을 얻는 것이 조금 더 어려워 질 수 있습니다.
대체 소프트웨어의 개발을 막기 위해 다른 소프트웨어 공급 업체가 API 키를 얻지 못하게하려는 경우 암호화 및 저장에 따로 따로 만 접근하는 것이 거의 효과가 있습니다. 이것은 화이트 박스 암호화이며 현재까지이 클래스의 문제에 대한 진정한 보안 솔루션을 제시 한 사람은 없습니다. 최소한 사용자마다 단일 키를 발급하여 악용 된 키를 금지 할 수 있습니다.
(*) 편집 : SSL 연결 을 확인하기 위해 추가 단계를 수행 하지 않아도 더 이상 안전한 것으로 간주해서는 안됩니다 .
순수한 RESTful API는 기본 프로토콜 표준 기능을 사용해야합니다.
For HTTP, the RESTful API should comply with existing HTTP standard headers. Adding a new HTTP header violates the REST principles. Do not re-invent the wheel, use all the standard features in HTTP/1.1 standards - including status response codes, headers, and so on. RESTFul web services should leverage and rely upon the HTTP standards.
RESTful services MUST be STATELESS. Any tricks, such as token based authentication that attempts to remember the state of previous REST requests on the server violates the REST principles. Again, this is a MUST; that is, if you web server saves any request/response context related information on the server in attempt to establish any sort of session on the server, then your web service is NOT Stateless. And if it is NOT stateless it is NOT RESTFul.
Bottom-line: For authentication/authorization purposes you should use HTTP standard authorization header. That is, you should add the HTTP authorization / authentication header in each subsequent request that needs to be authenticated. The REST API should follow the HTTP Authentication Scheme standards.The specifics of how this header should be formatted are defined in the RFC 2616 HTTP 1.1 standards – section 14.8 Authorization of RFC 2616, and in the RFC 2617 HTTP Authentication: Basic and Digest Access Authentication.
I have developed a RESTful service for the Cisco Prime Performance Manager application. Search Google for the REST API document that I wrote for that application for more details about RESTFul API compliance here. In that implementation, I have chosen to use HTTP "Basic" Authorization scheme. - check out version 1.5 or above of that REST API document, and search for authorization in the document.
In the web a stateful protocol is based on having a temporary token that is exchanged between a browser and a server (via cookie header or URI rewriting) on every request. That token is usually created on the server end, and it is a piece of opaque data that has a certain time-to-live, and it has the sole purpose of identifying a specific web user agent. That is, the token is temporary, and becomes a STATE that the web server has to maintain on behalf of a client user agent during the duration of that conversation. Therefore, the communication using a token in this way is STATEFUL. And if the conversation between client and server is STATEFUL it is not RESTful.
The username/password (sent on the Authorization header) is usually persisted on the database with the intent of identifying a user. Sometimes the user could mean another application; however, the username/password is NEVER intended to identify a specific web client user agent. The conversation between a web agent and server based on using the username/password in the Authorization header (following the HTTP Basic Authorization) is STATELESS because the web server front-end is not creating or maintaining any STATE information whatsoever on behalf of a specific web client user agent. And based on my understanding of REST, the protocol states clearly that the conversation between clients and server should be STATELESS. Therefore, if we want to have a true RESTful service we should use username/password (Refer to RFC mentioned in my previous post) in the Authorization header for every single call, NOT a sension kind of token (e.g. Session tokens created in web servers, OAuth tokens created in authorization servers, and so on).
I understand that several called REST providers are using tokens like OAuth1 or OAuth2 accept-tokens to be be passed as "Authorization: Bearer " in HTTP headers. However, it appears to me that using those tokens for RESTful services would violate the true STATELESS meaning that REST embraces; because those tokens are temporary piece of data created/maintained on the server side to identify a specific web client user agent for the valid duration of a that web client/server conversation. Therefore, any service that is using those OAuth1/2 tokens should not be called REST if we want to stick to the TRUE meaning of a STATELESS protocol.
Rubens
참고URL : https://stackoverflow.com/questions/9773664/rest-api-token-based-authentication
'Programming' 카테고리의 다른 글
FIND_IN_SET () 대 IN () (0) | 2020.07.14 |
---|---|
명령 프롬프트에서 응용 프로그램을“관리자 권한으로 실행”하는 방법은 무엇입니까? (0) | 2020.07.14 |
Python 3의 Concurrent.futures vs 멀티 프로세싱 (0) | 2020.07.14 |
인라인 자바 스크립트 (HTML)는 어떻게 작동합니까? (0) | 2020.07.14 |
안드로이드에서 파일을 만드는 방법? (0) | 2020.07.14 |