Examples
Talk is cheap. Show me the code!
Below there are some implementation examples
[HttpPost] public HttpResponseMessage V3([FromBody] dynamic json) // Do not use dynamic type, this is for example purposes only { var containers = new List<object> { new { Type = "MESSAGE", Phrase = json.value, }, };
var response = new HttpResponseMessage(HttpStatusCode.OK); response.Headers.Add("Authorization", Request.Headers.Authorization.ToString());
var responseContent = new { success = true, message = "", containers };
response.Content = new StringContent(JsonConvert.SerializeObject(responseContent), Encoding.UTF8, "text/plain");
return response; }
[HttpPost] public IActionResult V3(dynamic json) { HttpContext.Response.Headers.Authorization = HttpContext.Request.Headers.Authorization;
var containers = new List<object> { new { Type = "MESSAGE", Phrase = json.value } };
return Ok(new { success = true, message = "", containers }); }
@RestController@RequestMapping("/api/anna-ws")public class AnnAWebServiceController { @PostMapping("v3") public ResponseEntity<Object> v3(@RequestHeader("Authorization") String authorization, @RequestBody HashMap<String, Object> json) { ArrayList<Object> containersList = new ArrayList<>(); containersList.add(new Object() { public final String Type = "MESSAGE"; public final String Phrase = json.get("value").toString(); });
Object response = new Object() { public final boolean success = true; public final String message = ""; public final ArrayList<Object> containers = containersList; };
HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setBearerAuth(authorization); httpHeaders.setContentType(new MediaType("application", "json", StandardCharsets.UTF_8));
return new ResponseEntity<Object>(response, httpHeaders, HttpStatus.OK); }}
Http.GetJwtToken
// Considerations:// Optionally, you can adapt the following HTTP procedure and use it as a Restful API. Check the GeneXus documentation if necessary.//// SDT: Sample_SDT_GetJwtToken// - success (Boolean)// - message (VarChar(4K))// SDT: data// - token (VarChar(1K))// - expiresIn (VarChar(40))//// Procedure propeties definitions:// Main program=true// Call protocol=HTTP//// Procedure Rules:// Exception_Handler('AbortEx');// Error_Handler('AbortEr');//// Procedure Variables:// - &JWTCreator : JWTCreator, GeneXusJWT// - &JWTOptions : JWTOptions, GeneXusJWT// - &PrivateClaims : PrivateClaims, GeneXusJWT// - &ExpiresIn : VarChar(40)// - &AuxVarchar : VarChar(40)// - &ExpDatetime : DateTime// - &errorCode : Numeric(4)// - &HttpRequest : HttpRequest// - &HttpResponse : HttpResponse// - &IsValid : Boolean// - &Json : VarChar(2M)// - &message : VarChar(4K)// - &Payload : VarChar(4K)// - &symmetricKey : VarChar(4K)// - &SymmetricKeyGenerator : SymmetricKeyGenerator, SecurityAPICommons// - &Properties : Properties// - &Token : VarChar(4K)// - &ResponseToken : Sample_SDT_GetJwtToken// - &UserGUID : GUID
// Procedure source: (bellow)
// Example&HttpRequest.GetVariable(!'user')&HttpRequest.GetVariable(!'password')// Check user password&IsValid = trueif &IsValid //******HEADER******// //{ // "alg": "HS256", // "typ": "JWT" //} //******PAYLOAD******// //{ // "jti": "0696bb20-6223-4a1c-9ebf-e15c74387b9c", // "iss": "example.com", // "exp" : 1909649720, // "company": "Example", //}
// Obtaining an hexadecimal key for a symmetric encryption algorithm since it is what we are using (HS256) &symmetricKey = &SymmetricKeyGenerator.DoGenerateKey(SymmetricKeyType.GENERICRANDOM, 256)
// [OPTIONAL] iss claim, it is a registered claim // Registered claims are not mandatory therefore are added on JWTOptions SDT // Documentation: https://wiki.genexus.com/commwiki/servlet/wiki?43983,JWT+Optional+Data // For more information about JWT claim types https://wiki.genexus.com/commwiki/servlet/wiki?43981,JSON+Web+Token+Standard+%28JWT%29 &JWTOptions.AddRegisteredClaim(RegisteredClaim.iss, "example.com")
// [OPTIONAL] exp claim, it is a registered claim that validates time. // Therefore AddCustomTimeValidationClaim is the method to use with a time with "yyyy/MM/dd HH:mm:ss" picture &ExpDatetime = now() &ExpDatetime = &ExpDatetime.AddHours(6) &AuxVarchar = &ExpDatetime.Year().ToString().Trim() + !'/' + &ExpDatetime.Month().ToString().Trim().PadLeft(2, !'0') &AuxVarchar += !'/' + &ExpDatetime.Day().ToString().Trim().PadLeft(2, !'0') + !' ' + &ExpDatetime.Hour().ToString().Trim().PadLeft(2, !'0') &AuxVarchar += !':' + &ExpDatetime.Minute().ToString().Trim().PadLeft(2, !'0') + !':' + &ExpDatetime.Second().ToString().Trim().PadLeft(2, !'0') //&JWTOptions.AddCustomTimeValidationClaim(RegisteredClaim.exp, "2030/07/07 10:15:20", "0") &JWTOptions.AddCustomTimeValidationClaim(RegisteredClaim.exp, &AuxVarchar, !"0")
// [OPTIONAL] jti claim is a unique identifier for the JWT. This can be used to prevent JWT token abuse, and to ensure the uniqueness of the JWT &UserGUID = GUID.NewGuid() &AuxVarchar = &UserGUID.ToString().Trim() // UserID Example //&JWTOptions.AddRegisteredClaim(RegisteredClaim.jti, "0696bb20-6223-4a1c-9ebf-e15c74387b9c") &JWTOptions.AddRegisteredClaim(RegisteredClaim.jti, &AuxVarchar)
//Adding the key to use for the signature &JWTOptions.SetSecret(!'4A04A81A3F99B462FA8CA65BE81C75D8FEACCE50AA99A4BF980CBA99A0B6CBD8') // Fixed for tests //&JWTOptions.SetSecret(&symmetricKey)
// [OPTIONAL] Private claims are additional pieces of information that are specific to an application or organization. // They are not standardized by the JWT specification &PrivateClaims.SetClaim(!"role",!"user_role_example")
// Use DoCreate to sign and encode the token // Documentation: https://wiki.genexus.com/commwiki/servlet/wiki?43989,JWT+Creator &Token = &JWTCreator.DoCreate(JWTAlgorithm.HS256, &PrivateClaims, &JWTOptions)
if &JWTCreator.HasError() // 500 - !"Internal Error" &errorCode = 500 &message = !"Internal Error" Do 'Error' else &payload = &JWTCreator.GetPayload(&token) //Payload: {"role":"user","iss":"example.com","exp":1653421785,"jti":"3eb86fa7-8283-44e2-b6f3-1cebee877a49"} &ExpiresIn = &ExpDatetime.Difference(now()).ToString().Trim() &ResponseToken.success = true &ResponseToken.message = !'' &ResponseToken.data.token = &Token &ResponseToken.data.expiresIn = &ExpiresIn &HttpResponse.AddString(&ResponseToken.ToJson()) endifelse // 400 - !"Authorization missing or malformed" &errorCode = 400 &message = !"Authorization header missing or malformed" Do 'Error'endif
Sub 'AbortEx' // https://wiki.genexus.com/commwiki/wiki?44808,Exception_Handler+rule &errorCode = 500 &message = !'Internal Error' Do 'Error'EndSubSub 'AbortEr' // https://wiki.genexus.com/commwiki/wiki?6853,Error_Handler+rule &message = !'Internal Error' Do 'Error'EndSubSub 'Error' &Properties.Clear() &Properties.Set(!'success', !'false') &Properties.Set(!'message', &errorCode.ToString().Trim() + !': ' + &message.Trim()) &Json = &Properties.ToJson() &HttpResponse.AddString(&Json) returnEndSub
Http.WSAnnAV3
// Considerations:// Optionally, you can adapt the following HTTP procedure and use it as a Restful API. Check the GeneXus documentation if necessary.//// SDT: Sample_SDT_WSV3_Message// - success (Boolean)// - message (VarChar(4K))// - containers (Collection) // containersItem elements// SDT: containersItem// - Type (VarChar(50))// - Alias (VarChar(50))// - Phrase (VarChar(2M))// - Active (Character(1))//// Procedure propeties definitions:// Main program=true// Call protocol=HTTP//// Procedure Rules:// Exception_Handler('AbortEx');// Error_Handler('AbortEr');//// Procedure Variables:// - &JWTCreator : JWTCreator, GeneXusJWT// - &JWTOptions : JWTOptions, GeneXusJWT// - &ExpiresIn : VarChar(40)// - &ExpDatetime : DateTime// - &errorCode : Numeric(4)// - &HttpRequest : HttpRequest// - &HttpResponse : HttpResponse// - &IsValid : Boolean// - &Json : JSON// - &messages : Messages, GeneXusCommon// - &message : VarChar(4K)// - &Payload : VarChar(4K)// - &Properties : Properties// - &Token : VarChar(4K)// - &ResponseMessage : Sample_SDT_WSV3_Message// - &ContainerItem : Sample_SDT_WSV3_Message.containersItem// Procedure source: (bellow)
// First, you need to validate the request credentials.// Example: simple JWT authentication using a Bearer Token.&Token = &HttpRequest.GetHeader(!"Authorization")if &Token.ToLower().StartsWith(!"bearer ") &Token = &Token.Substring(8) // Remove "Bearer "
// [OPTIONAL] Do not mandatory to check signature https://wiki.genexus.com/commwiki/wiki?43989,JWT+Creator &JWTOptions.SetSecret(!'4A04A81A3F99B462FA8CA65BE81C75D8FEACCE50AA99A4BF980CBA99A0B6CBD8') // Fixed for tests &IsValid = &JWTCreator.DoVerifyJustSignature(&Token, JWTAlgorithm.HS256, &JWTOptions) if &IsValid and not &JWTCreator.HasError() &Payload = &JWTCreator.GetPayload(&Token) &Properties.FromJson(&Payload, &messages)
// [OPTIONAL] Manually claims verifications (iss, exp, role) if &Properties.Get(!'role') = !'user_role_example' and &Properties.Get(!'iss') = !'example.com' &ExpiresIn = &Properties.Get(!'exp') // You can to verify other claims
// Convert exp (Unix timestamp) to DateTime &ExpDatetime = ymdtoD(1970, 1, 1) &ExpDatetime = &ExpDatetime.AddSeconds(&ExpiresIn.Trim().ToNumeric())
if &ExpDatetime > Now() // Check if token is not expired // OK // Additional verifications? // You can do additional checks if necessary. else // 401 - !"Token expired" &errorCode = 401 &message = !"Token expired" Do 'Error' endif else // 401 - !"Invalid token" &errorCode = 401 &message = !"Invalid token" Do 'Error' endif else // 401 - !"Invalid signature" &errorCode = 401 &message = !"Invalid token error: " + &JWTCreator.GetErrorDescription() Do 'Error' endifelse // 400 - !"Authorization header missing or malformed" &errorCode = 400 &message = !"Authorization header missing or malformed" Do 'Error'endif
// Create response JSON&ResponseMessage = new()&ContainerItem = new()&ContainerItem.Type = !"MESSAGE"&ContainerItem.Alias = !"MSG01"&ContainerItem.Phrase = !"Request Success"&ContainerItem.Active = !"S"&ResponseMessage.containers.Add(&ContainerItem)&ResponseMessage.success = true&ResponseMessage.message = !""
// Converter para JSON&Json = &ResponseMessage.ToJson()&HttpResponse.AddString(&Json)
Sub 'AbortEx' // https://wiki.genexus.com/commwiki/wiki?44808,Exception_Handler+rule &errorCode = 500 &message = !'Internal Error' Do 'Error'EndSubSub 'AbortEr' // https://wiki.genexus.com/commwiki/wiki?6853,Error_Handler+rule &message = !'Internal Error' Do 'Error'EndSubSub 'Error' &Properties.Clear() &Properties.Set(!'success', !'false') &Properties.Set(!'message', &errorCode.ToString().Trim() + !': ' + &message.Trim()) &Json = &Properties.ToJson() &HttpResponse.AddString(&Json) returnEndSub