Azure API Management is an API gateway that can be utilized to publish APIs to the Internet. It gives options comparable to per-developer API keys, request throttling and request authentication. One of the way in which requests may be authenticated is thru commonplace OAuth2 bearer tokens. I assume that the commonest situation is to make use of Azure AD to subject these tokens. But if an organisation just isn’t that cloud enabled but and the customers are in an on prem AD, the pure token issuer is to make use of ADFS. And ADFS on Windows Server 2016 helps OpenID Connect, so it ought to work, proper?

Well, it seems it didn’t simply work. The OpenID Connect implementation in ADFS has some quirks that should be dealt with. In the top it labored, however with some limitations.

One of the neat issues with OpenID Connect is that it gives a metadata primarily based conference for configuration. There’s no have to obtain and deal with certificates to register signing keys, it usually simply works. Until it doesn’t. Which was the case right here.

First, the configuration within the Azure API Management Policy was pretty straight ahead. The coverage checks {that a} matched question string parameter color from the general public going through URL can also be current as a declare. This carries all the way in which to the lively listing person object, the place the “different pager” area was used to checklist the colors {that a} sure person is allowed to make use of within the URL to the API.

<insurance policies>
  <inbound>
    <validate-jwt header-name="Authorization">
      <openid-config url=" />
      <required-claims>
        <declare identify="color" match="all">
          <worth>@((string)context.Request.MatchedParameters["colour"])</worth>
        </declare>
      </required-claims>
    </validate-jwt>
    <base />
  </inbound>
  <backend>
    <base />
  </backend>
  <outbound>
    <base />
  </outbound>
  <on-error>
    <base />
  </on-error>
</insurance policies>

This code turned out to work ultimately, after some workarounds had been utilized.

The first downside was apparent after I used jwt.io to examine the entry token I acquired from the ADFS. It didn’t comprise the requested colors scope and didn’t comprise the colors claims.

{
  "aud": "urn:microsoft:userinfo",
  "iss": "
  "iat": 1511714437,
  "exp": 1511718037,
  "apptype": "Public",
  "appid": "8059f5ed-fa9b-4165-815c-663dec49b965",
  "authmethod": "urn:oasis:names:tc:SAML:2.0:ac:lessons:unspecified",
  "auth_time": "2017-11-26T16:40:36.000Z",
  "ver": "1.0",
  "scp": "openid",
  "sub": "r5PvRoaOXFmaJ+q6LyeVslYVXZl38F/UkrBvQNlyoY8="
}

Apparently, ADFS has added a non-standard parameter useful resource that should be provided within the token request to get an entry token aimed for an API. The default entry token as returned above is simply meant for the person information endpoint on the ADFS server. With a useful resource parameter added, I bought a greater entry token. It now contains the colors scope and the ADFS issuance remodel guidelines for the Web API now kicks in and contains the color declare within the entry token. Note that it now additionally has a special viewers – the identifier of the API.

{
  "aud": "
  "iss": "
  "iat": 1511718387,
  "exp": 1511721987,
  "color": "Blue",
  "apptype": "Public",
  "appid": "8059f5ed-fa9b-4165-815c-663dec49b965",
  "authmethod": "urn:oasis:names:tc:SAML:2.0:ac:lessons:unspecified",
  "auth_time": "2017-11-26T17:46:24.000Z",
  "ver": "1.0",
  "scp": "colors"
}

So it seems that ADFS is issuing completely different entry tokens for various APIs and the way in which to request an entry token for a selected API is to make use of the non-standard useful resource parameter. I’ll write some extra on this in one other submit.

For now, simply let’s get on with the work and attempt to use the entry token to entry the API.

At the primary attempt with my new entry token, issues simply didn’t work. Finding out why wasn’t apparent. I copied the entry token I had bought in my shopper utility into the API check instruments within the Azure portal to get a hint. The hint simply reveals that the JWT validation failed. To get the precise JWT validation error, one has to observe the hyperlink that’s listed within the hint. In that log, the error message is obvious (kudos to the Microsoft dev who determined to incorporate the precise values within the exception message).

message: "JWT Validation Failed: IDX10205: Issuer validation failed. Issuer: ' Did not match: validationParameters.LegitimateIssuer: '' or validationParameters.LegitimateIssuers: '

Now what occurred right here? Looks just like the iss area of the JWT doesn’t match the one in listed within the OpenID Connect configuration info. Looking on the ADFS OpenID Connect configuration info out there at confirmed one other non-standard OpenID Connect behaviour of ADFS. At the highest, an issuer worth of is proven. This additionally corresponds to the OpenID Connect commonplace that the configuration doc path is fashioned by concatenating the issuer URL with /.well-known/openid-configuration. The id_token accurately incorporates as issuer.. However, that’s not the issuer discovered within the entry token. The entry token makes use of the ID I’ve arrange in ADFS because the Federation Service Identifier. That’s the worth used because the Entity ID in SAML-based tokens. And that identifier is definitely current within the metadata within the non-standard area access_token_issuer.

{
  "issuer": "",
  "authorization_endpoint": "/oauth2/authorize/",
  "token_endpoint": "/oauth2/token/",
  "jwks_uri": "/discovery/keys",
  "token_endpoint_auth_methods_supported": [
    "client_secret_post",
    "client_secret_basic",
    "private_key_jwt",
    "windows_client_authentication"
  ],
  "response_types_supported": [
    "code",
    "id_token",
    "code id_token",
    "id_token token",
    "code token",
    "code id_token token"
  ],
  "response_modes_supported": [
    "query",
    "fragment",
    "form_post"
  ],
  "grant_types_supported": [
    "authorization_code",
    "refresh_token",
    "client_credentials",
    "urn:ietf:params:oauth:grant-type:jwt-bearer",
    "implicit",
    "password",
    "srv_challenge"
  ],
  "subject_types_supported": [
    "pairwise"
  ],
  "scopes_supported": [
    "aza",
    "logon_cert",
    "user_impersonation",
    "winhello_cert",
    "profile",
    "email",
    "allatclaims",
    "vpn_cert",
    "openid",
    "colours"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "token_endpoint_auth_signing_alg_values_supported": [
    "RS256"
  ],
  "access_token_issuer": "
  "claims_supported": [
    "aud",
    "iss",
    "iat",
    "exp",
    "auth_time",
    "nonce",
    "at_hash",
    "c_hash",
    "sub",
    "upn",
    "unique_name",
    "pwd_url",
    "pwd_exp",
    "sid"
  ],
  "microsoft_multi_refresh_token": true,
  "userinfo_endpoint": "/userinfo",
  "capabilities": [],
  "end_session_endpoint": "/oauth2/logout",
  "as_access_token_token_binding_supported": true,
  "as_refresh_token_token_binding_supported": true,
  "resource_access_token_token_binding_supported": true,
  "op_id_token_token_binding_supported": true,
  "rp_id_token_token_binding_supported": true,
  "frontchannel_logout_supported": true,
  "frontchannel_logout_session_supported": true
}

Apparently not even Microsoft’s personal API Management platform is aware of about that area. So the incoming entry token is rejected by Azure API Management because of issuer names not matching. First I attempted to resolve that by manually including the entry token issuer worth within the API Management coverage, however I by no means bought it working (I feel it was one thing with an incorrect trailing area added). Instead I went again and renamed my ADFS server, in order that the Federation Service Identifier now could be (the ADFS service wants a restart for the rename to take impact). That provides a brand new OpenID Connect configuration doc the place the issuer and access_token_issuer fields are the identical.

Finally my JWT validation works.

Solving this by renaming the ADFS server identifier is nothing that may simply be achieved in an current federation setup. All different purposes (relying events) and upstream identification suppliers (claims suppliers) should in fact be up to date with the brand new federation service ID.

Using ADFS as an OAuth2 token issuer for Azure API Management type of works. A workaround is required to to deal with the issuer vs. access_token_issuer subject. In a recent ADFS setup that’s attainable by a rename. In an current surroundings in all probability not.

What’s extra extreme is that to get the entry token the additional useful resource parameter should be added. Microsoft’s OpenID Connect handler for ASP.NET Core 2 helps that and their ADAL.js library for javascript does. But different standard-conforming libraries comparable to Brock Allen’s oidc-client.js or libaries for non-.NET server aspect purposes gained’t work. And the complete objective of the API Management platform is to publish APIs on the Internet for different builders to make use of. Using an OpenID Connect Provider that requires non-standard behaviour of the shopper will inevitably create compatibility points in such a situation.


Posted in
Azure on 2017-12-06 | Tagged ADFS, OpenID Connect




Source link