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