Mercurial > hg > orthanc
comparison OrthancFramework/Sources/HttpServer/HttpServer.cpp @ 4343:e1e918e790e8
New function in the SDK: OrthancPluginGenerateRestApiAuthorizationToken()
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 04 Dec 2020 18:28:23 +0100 |
parents | a01b1c9cbef4 |
children | df313e410f0c |
comparison
equal
deleted
inserted
replaced
4342:52166629239f | 4343:e1e918e790e8 |
---|---|
543 | 543 |
544 return PostDataStatus_Pending; | 544 return PostDataStatus_Pending; |
545 } | 545 } |
546 | 546 |
547 | 547 |
548 static bool IsAccessGranted(const HttpServer& that, | 548 enum AccessMode |
549 const HttpToolbox::Arguments& headers) | 549 { |
550 { | 550 AccessMode_Forbidden, |
551 bool granted = false; | 551 AccessMode_AuthorizationToken, |
552 AccessMode_RegisteredUser | |
553 }; | |
554 | |
555 | |
556 static AccessMode IsAccessGranted(const HttpServer& that, | |
557 const HttpToolbox::Arguments& headers) | |
558 { | |
559 static const std::string BASIC = "Basic "; | |
560 static const std::string BEARER = "Bearer "; | |
552 | 561 |
553 HttpToolbox::Arguments::const_iterator auth = headers.find("authorization"); | 562 HttpToolbox::Arguments::const_iterator auth = headers.find("authorization"); |
554 if (auth != headers.end()) | 563 if (auth != headers.end()) |
555 { | 564 { |
556 std::string s = auth->second; | 565 std::string s = auth->second; |
557 if (s.size() > 6 && | 566 if (boost::starts_with(s, BASIC)) |
558 s.substr(0, 6) == "Basic ") | 567 { |
559 { | 568 std::string b64 = s.substr(BASIC.length()); |
560 std::string b64 = s.substr(6); | 569 if (that.IsValidBasicHttpAuthentication(b64)) |
561 granted = that.IsValidBasicHttpAuthentication(b64); | 570 { |
562 } | 571 return AccessMode_RegisteredUser; |
563 } | 572 } |
564 | 573 } |
565 return granted; | 574 else if (boost::starts_with(s, BEARER) && |
575 that.GetIncomingHttpRequestFilter() != NULL) | |
576 { | |
577 // New in Orthanc 1.8.1 | |
578 std::string token = s.substr(BEARER.length()); | |
579 if (that.GetIncomingHttpRequestFilter()->IsValidBearerToken(token)) | |
580 { | |
581 return AccessMode_AuthorizationToken; | |
582 } | |
583 } | |
584 } | |
585 | |
586 return AccessMode_Forbidden; | |
566 } | 587 } |
567 | 588 |
568 | 589 |
569 static std::string GetAuthenticatedUsername(const HttpToolbox::Arguments& headers) | 590 static std::string GetAuthenticatedUsername(const HttpToolbox::Arguments& headers) |
570 { | 591 { |
1073 | 1094 |
1074 // Check remote calls | 1095 // Check remote calls |
1075 if (!server.IsRemoteAccessAllowed() && | 1096 if (!server.IsRemoteAccessAllowed() && |
1076 !localhost) | 1097 !localhost) |
1077 { | 1098 { |
1078 output.SendUnauthorized(server.GetRealm()); | 1099 output.SendUnauthorized(server.GetRealm()); // 401 error |
1079 return; | 1100 return; |
1080 } | 1101 } |
1081 | 1102 |
1082 | 1103 |
1083 // Extract the HTTP headers | 1104 // Extract the HTTP headers |
1103 if (!strcmp(request->request_method, "GET")) | 1124 if (!strcmp(request->request_method, "GET")) |
1104 { | 1125 { |
1105 HttpToolbox::ParseGetArguments(argumentsGET, request->query_string); | 1126 HttpToolbox::ParseGetArguments(argumentsGET, request->query_string); |
1106 } | 1127 } |
1107 | 1128 |
1129 | |
1130 AccessMode accessMode = IsAccessGranted(server, headers); | |
1108 | 1131 |
1109 // Authenticate this connection | 1132 // Authenticate this connection |
1110 if (server.IsAuthenticationEnabled() && | 1133 if (server.IsAuthenticationEnabled() && |
1111 !IsAccessGranted(server, headers)) | 1134 accessMode == AccessMode_Forbidden) |
1112 { | 1135 { |
1113 output.SendUnauthorized(server.GetRealm()); | 1136 output.SendUnauthorized(server.GetRealm()); // 401 error |
1114 return; | 1137 return; |
1115 } | 1138 } |
1116 | 1139 |
1117 | 1140 |
1118 #if ORTHANC_ENABLE_MONGOOSE == 1 | 1141 #if ORTHANC_ENABLE_MONGOOSE == 1 |
1193 output.SendStatus(HttpStatus_400_BadRequest); | 1216 output.SendStatus(HttpStatus_400_BadRequest); |
1194 return; | 1217 return; |
1195 } | 1218 } |
1196 | 1219 |
1197 | 1220 |
1198 // Check that this connection is allowed by the user's authentication filter | |
1199 const std::string username = GetAuthenticatedUsername(headers); | 1221 const std::string username = GetAuthenticatedUsername(headers); |
1200 | 1222 |
1201 IIncomingHttpRequestFilter *filter = server.GetIncomingHttpRequestFilter(); | 1223 if (accessMode != AccessMode_AuthorizationToken) |
1202 if (filter != NULL) | 1224 { |
1203 { | 1225 // Check that this access is granted by the user's authorization |
1204 if (!filter->IsAllowed(filterMethod, requestUri, remoteIp, | 1226 // filter. In the case of an authorization bearer token, grant |
1227 // full access to the API. | |
1228 | |
1229 assert(accessMode == AccessMode_Forbidden || // Could be the case if "!server.IsAuthenticationEnabled()" | |
1230 accessMode == AccessMode_RegisteredUser); | |
1231 | |
1232 IIncomingHttpRequestFilter *filter = server.GetIncomingHttpRequestFilter(); | |
1233 if (filter != NULL && | |
1234 !filter->IsAllowed(filterMethod, requestUri, remoteIp, | |
1205 username.c_str(), headers, argumentsGET)) | 1235 username.c_str(), headers, argumentsGET)) |
1206 { | 1236 { |
1207 //output.SendUnauthorized(server.GetRealm()); | |
1208 output.SendStatus(HttpStatus_403_Forbidden); | 1237 output.SendStatus(HttpStatus_403_Forbidden); |
1209 return; | 1238 return; |
1210 } | 1239 } |
1211 } | 1240 } |
1212 | 1241 |