dotnet의 ID 토큰 유효성 검사

11050 단어 dotnetopenid
오늘은 도전 과제가 있습니다.
내가 작업하고 있는 프로젝트 중 하나에서 비즈니스상의 이유로 사용자가 사용자 3번째 IDP에 로그인하는 것을 원하지 않습니다.
그러나 BankID을 통해 criipto.com으로 사용자의 신원을 확인해야 한다는 요구 사항이 있습니다.
OpenID를 통해 통합을 제공합니다.

사용자가 criipto.com에 등록된 당사의 권한으로 인증해야 함을 의미합니다.
발급된 ID-Token을 신원 증명으로 백엔드에 전달합니다.
dotnet 인증 파이프라인에 OpenID 지원을 추가하는 많은 도구가 있습니다.
그러나 ID-Token을 구체적으로 검증하는 도구를 찾는 데 시간이 걸렸습니다.

그것이 당신이 필요로 한 것이라면, 아래는 몇 가지 설명과 함께 예가 될 것입니다.

TLDR



You'll need IdentityModel.OidcClient.IdentityTokenValidator package.



using System.Net.Http;
using System.Threading.Tasks;
using IdentityModel.Client;
using IdentityModel.OidcClient;
using Xunit;

namespace IdTokenValidation;

public class ValidateTokenExample
{
    // Obviously constant values must be replaced for test to pass

    const string Authority = "AUTHORITY";
    const string ClientId = "CLIENT-ID";

    const string IdToken = "ID-TOKEN";

    [Fact]
    public async Task Validate()
    {
        // GetDiscoveryDocumentAsync extension comes from IdentityModel.OidcClient namespace
        // from IdentityModel.OidcClient package.
        DiscoveryDocumentResponse? doc = await new HttpClient().GetDiscoveryDocumentAsync(Authority);
        Assert.False(doc!.IsError);

        var validator = new JwtHandlerIdentityTokenValidator();
        var options = new OidcClientOptions
        {
            ClientId = ClientId,
            ProviderInformation = new ProviderInformation
            {
                IssuerName = doc.Issuer,
                KeySet = doc.KeySet
            }
        };

        IdentityTokenValidationResult? result = await validator.ValidateAsync(IdToken, options);

        Assert.False(result.IsError);
    }
}


여기에 작은 참고 사항이 있습니다. 일반적으로 검색 문서를 캐시하지만 여기서는 단순성을 위해 수행되지 않았습니다.

주의 사항



심지어 ValidateAsync 메서드에도 비동기 서명이 있습니다.OidcClientOptions에 권한을 부여하는 것으로 충분하다고 가정했습니다.
검색 문서를 가져오고 거기에서 키를 가져올 것이라고 가정했습니다.
불행히도 비동기 서명에도 불구하고 그렇게 하지 않습니다.
전달된 데이터를 기반으로 동기 유효성 검사를 수행합니다.
따라서 원하는 문서를 직접 가져오고 KeySet을 공급자 정보에 전달해야 합니다.
위의 예처럼.

엔드포인트가 기관과 다른 호스트에 있음



기본적으로GetDiscoveryDocumentAsync 권한이 일치하지 않는 도메인의 검색 문서 세그먼트를 허용하지 않습니다.
예를 들어 구글의 경우 (Authority: https://accounts.google.com/ )
검색 문서 루트https://accounts.google.com/.well-known/openid-configuration를 열면 일부 엔드포인트가
서로 다른 도메인을 가지고 있습니다. token_endpoint와 같이 https://oauth2.googleapis.com/token에 있고 jwks_urihttps://www.googleapis.com/oauth2/v3/certs에 있습니다.

따라서 유효성 검사 정책을 지정할 수 있는 GetDiscoveryDocumentAsync에 대한 오버로드가 있습니다.
허용된 도메인을 허용 목록에 추가하거나 아래 예와 같이 엔드포인트 유효성 검사를 전혀 비활성화합니다.

using System.Net.Http;
using System.Threading.Tasks;
using IdentityModel.Client;
using Xunit;

namespace IdTokenValidation;

public class FetchGoogleDocumentExample
{
    [Fact]
    public async Task UsingWhitelist()
    {
        var opt = new DiscoveryDocumentRequest
        {
            Address = "https://accounts.google.com/",
            Policy =
            {
                AdditionalEndpointBaseAddresses =
                {
                    "https://oauth2.googleapis.com/",
                    "https://www.googleapis.com/",
                    "https://openidconnect.googleapis.com/"
                }
            }
        };

        DiscoveryDocumentResponse? doc = await new HttpClient().GetDiscoveryDocumentAsync(opt);
        Assert.False(doc!.IsError);
    }

    [Fact]
    public async Task WithEndpointValidationDisabled()
    {
        var opt = new DiscoveryDocumentRequest
        {
            Address = "https://accounts.google.com/",
            Policy =
            {
                 ValidateEndpoints = false
            }
        };
        var http = new HttpClient();

        DiscoveryDocumentResponse? doc = await http.GetDiscoveryDocumentAsync(opt);
        Assert.False(doc!.IsError);
    }
}


문제가 있는 경우 https://github.com/tretyakov-d/playground-id-token-validation에서 예제 리포지토리를 확인하는 것이 좋습니다.

도움이 되었길 바랍니다

좋은 웹페이지 즐겨찾기