1

I have a solution where the design is like this:

Azure API Management --> JWT Policy applied on the endpoint ---> Functions stored on Azure Functions.

I need to find a way to retrieve the ObjectID of the caller contained on Azure AD B2C. There is one api where the username and password is supplied and as result, the caller will receive tokens.

Then with the token I need to call another API and the JWT will be sent via header and validated by Azure API management. Ok, this works fine so good. But inside the function I need to find a way to know who is the person by extracting the ObjectId.

Many examples I found looks deprecated or made for traditional dotnet or is not completed and missing vital details.

This is my code :

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using endpoints3t.Utils.AccessTokens;
using System.Collections.Generic;
using JWT.Builder;

namespace endpoints3t.Routes
{
    public class Test
    {
        [FunctionName("Test")]

        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "v1/Test")] HttpRequest req,
            ILogger log, Microsoft.Azure.WebJobs.ExecutionContext context)
        {
            log.LogInformation("Processing: Test");
            string authorizationHeader = req.Headers["Authorization"];
            IDictionary<string, object> claims = null;
            claims = new JwtBuilder().Decode<IDictionary<string, object>>(authorizationHeader);
            // Since Azure ApiM already validated the token via policy, I don't need
            // to concern if the token is valid or not, so I can read it directly.
            string adObjectId = claims["oid"].ToString();
            return new OkResult(adObjectId);
        }
    }
}

It works good as well, but I am convinced that this is not the best way to do the things, based on many deprecated and incompleted examples or made for non openId or different kind of flow. So, anyone know how to perform the right implementation?

Besworks
  • 4,123
  • 1
  • 18
  • 34
Marco Jr
  • 6,496
  • 11
  • 47
  • 86

1 Answers1

0

In my project, I have a similar requirement.
I modified the code for ObjectId (oid):

public static string ReadObjectId(HttpRequest req, IConfiguration configuration, ILogger log)
{
    var token = req.Headers.FirstOrDefault(f => f.Key == "Authorization").Value.ToArray<string>()[0].Split(' ')[1].Trim();

    var handler = new JwtSecurityTokenHandler();
    var validations = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = false,
        IssuerSigningKeys = oAuthConfig.SigningKeys,
        ValidateIssuer = true,
        ValidIssuer = oAuthConfig.Issuer,
        ValidateAudience = true,
        ValidateLifetime = true,
        ClockSkew = new TimeSpan(0, 10, 0)
    };

    var identity = handler.ValidateToken(token, validations, out var tokenSecure).Identity as ClaimsIdentity;
    var oid = identity.FindFirst("oid").Value.ToString();
    return oid;
}

Only if the token is valid, the identity will be returned.
The identity has a collection of Claims, and the oid should return your wanted value.

Markus Meyer
  • 3,327
  • 10
  • 22
  • 35