Authentication for Azure Functions

后端 未结 3 854
忘掉有多难
忘掉有多难 2020-12-01 12:45

I\'ve spent the past 24 hours reading all about how to create Azure Functions and have successfully converted a MVC WebApi over to a new Function App with multiple functions

相关标签:
3条回答
  • 2020-12-01 12:56

    Once the user authenticates with Azure AD you'll be presented an AppServiceAuthSessoin cookie. It's an opaque cookie but you can exchange it for claims by calling

    https://yourFunctionApp.azurewebsites.net/.auth/me
    

    and passing in the opaque cookie as Cookie header. Moreover, the id_token you get back is good for use as Bearer token.

    Actually it just looks right to me, i haven't really tested it as a Bearer, so a little caution there.

    The mechanism is called Easy Auth, it's easier to Google for that name.

    More on the token store here —
    https://cgillum.tech/2016/03/07/app-service-token-store/

    ...which says you can grab the claims just by reading the HTTP headers coming in from the user's browser:

    Accessing the Tokens

    From within your backend code, accessing these tokens is as easy as reading an HTTP request header. The headers are named like X-MS-TOKEN-{provider}-{type}. The possible token header names are listed below:

    Azure Active Directory Token Request Headers:

    X-MS-TOKEN-AAD-ID-TOKEN
    X-MS-TOKEN-AAD-ACCESS-TOKEN
    X-MS-TOKEN-AAD-EXPIRES-ON
    X-MS-TOKEN-AAD-REFRESH-TOKEN
    

    I actually just found that out right now, so thanks for the question!

    UPDATE:

    My hunch was correct, the id_token is also good as Bearer:

    $ curl -isk https://{funcApp}.azurewebsites.net/api/{someFunc} \
           -H "Authorization: Bearer eyJ0eXAiOi....oEU-Q"
    
    HTTP/1.1 200 OK
    Cache-Control: no-cache
    Server: Microsoft-IIS/8.0
    ...
    

    The main difference between the two ways of reading claims (reading headers vs. calling /.auth/me from the backend with user's Cookie) is the amount of detail you get. There's way more in the latter.

    Here's the set of headers you get from Easy Auth for a Twitter authenticated user:

    {
       "cookie": "AppServiceAuthSession=Lx43...xHDTA==",
       ...
       "x-ms-client-principal-name": "evilSnobu",
       "x-ms-client-principal-id": "35....",
       "x-ms-client-principal-idp": "twitter",
       "x-ms-token-twitter-access-token": "35...Dj",
       "x-ms-token-twitter-access-token-secret": "OK3...Jx",
    }
    

    and the claims you get by calling /.auth/me:

    {
       "access_token": "35...FDj",
       "access_token_secret": "OK3...sJx",
       "provider_name": "twitter",
       "user_claims": [
          {
             "typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
             "val": "352660979"
          },
          {
             "typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn",
             "val": "evilSnobu"
          },
          {
             "typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
             "val": "Safarihat Hacker"
          },
          {
             "typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/webpage",
             "val": "..."
          },
          {
             "typ": "urn:twitter:description",
             "val": "GENIUS. HAVE BRAIN. WILL TRAVEL."
          },
          {
             "typ": "urn:twitter:location",
             "val": ""
          },
          {
             "typ": "urn:twitter:time_zone",
             "val": "London"
          },
          {
             "typ": "urn:twitter:lang",
             "val": "en"
          },
          {
             "typ": "urn:twitter:verified",
             "val": "False"
          },
          {
             "typ": "urn:twitter:profile_image_url_https",
             "val": "https://pbs.twimg.com/profile_images/867473646876545024/1elebfK1_normal.jpg"
          }
       ],
       "user_id": "evilSnobu"
    }
    
    0 讨论(0)
  • 2020-12-01 12:56

    I've created a small extension to Azure Functions v2, that might help you when used with Bearer Tokens.

    For instance, to work with Azure B2C, when you want to allow anonymous requests to the app.

    So you can obtain your ClaimsPrincipal right in the Azure Function without any boilerplate used.

    [FunctionName("Example")]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
        [FunctionToken] FunctionTokenResult token,
        ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");
        return (ActionResult) new OkObjectResult($"Hello, {token}");
    }
    

    Code is posted to Github

    0 讨论(0)
  • 2020-12-01 13:17

    AuthorizationLevel.User isn't currently supported by azure functions see here

    As of December 2017 this isn't fully implemented.

    0 讨论(0)
提交回复
热议问题