@@ -11,16 +11,13 @@ defmodule Console.Chat.Teams.Auth do
1111 to discover the metadata, load + cache the JWKS, and validate the signature/issuer/audience/lifetime. The
1212 Teams-specific `serviceurl` claim is checked separately.
1313 """
14- use Nebulex.Caching
15- require Logger
14+ alias Console.OIDC.ProviderConfiguration
1615
1716 # The connector publishes its metadata here. Two quirks are needed to consume it via oidcc:
1817 # * the document's declared issuer is `https://api.botframework.com` (not this url) -> allow_issuer_mismatch
1918 # * the document omits several oidc-required fields (scopes/response_types/subject_types), so we backfill
2019 # them via document_overrides purely to satisfy the parser - they do not affect token validation.
2120 @ config_issuer "https://login.botframework.com/v1"
22- @ cache_adapter Console . conf ( :cache_adapter )
23- @ ttl :timer . hours ( 1 )
2421
2522 @ quirks % {
2623 quirks: % {
@@ -43,7 +40,7 @@ defmodule Console.Chat.Teams.Auth do
4340 def verify ( token , audience , opts \\ [ ] )
4441 def verify ( token , audience , opts ) when is_binary ( token ) and is_binary ( audience ) do
4542 with { :ok , _ } <- peek ( token ) ,
46- { :ok , { conf , jwks } } <- provider_configuration ( ) ,
43+ { :ok , { conf , jwks } } <- ProviderConfiguration . fetch ( @ config_issuer , @ quirks ) ,
4744 ctx = Oidcc.ClientContext . from_manual ( conf , jwks , audience , "dummy_secret" , % { client_jwks: JOSE.JWK . generate_key ( 16 ) } ) ,
4845 validate_opts = % { signing_algs: ctx . provider_configuration . id_token_signing_alg_values_supported } ,
4946 { :ok , claims } <- validate_jwt ( token , ctx , validate_opts ) ,
@@ -53,22 +50,6 @@ defmodule Console.Chat.Teams.Auth do
5350 end
5451 def verify ( _ , _ , _ ) , do: { :error , "missing teams bot token or audience" }
5552
56- @ doc """
57- Loads and caches the Bot Framework provider configuration + JWKS. Cached so we don't round-trip Microsoft on
58- every webhook; the ttl also bounds how stale the signing keys can get across a key rotation.
59- """
60- @ decorate cacheable ( cache: @ cache_adapter , key: :teams_bf_oidc_config , opts: [ ttl: @ ttl ] , match: & ok? / 1 )
61- def provider_configuration ( ) do
62- with { :ok , { conf , _ } } <- Oidcc.ProviderConfiguration . load_configuration ( @ config_issuer , @ quirks ) ,
63- { :ok , { jwks , _ } } <- Oidcc.ProviderConfiguration . load_jwks ( conf . jwks_uri ) do
64- { :ok , { conf , jwks } }
65- else
66- err ->
67- Logger . warning ( "failed to load teams bot framework oidc configuration: #{ inspect ( err ) } " )
68- { :error , "could not load teams bot framework configuration" }
69- end
70- end
71-
7253 # cheap, network-free rejection of obviously malformed tokens before we touch the provider config
7354 defp peek ( token ) do
7455 case Joken . peek_header ( token ) do
@@ -90,9 +71,6 @@ defmodule Console.Chat.Teams.Auth do
9071 do: check ( String . trim_trailing ( claim , "/" ) == String . trim_trailing ( url , "/" ) , "teams jwt serviceUrl mismatch" )
9172 defp validate_service_url ( _claims , _url ) , do: { :error , "teams jwt is missing the serviceUrl claim" }
9273
93- defp ok? ( { :ok , _ } ) , do: true
94- defp ok? ( _ ) , do: false
95-
9674 defp check ( true , _ ) , do: :ok
9775 defp check ( _ , msg ) , do: { :error , msg }
9876end
0 commit comments