source

Azure AD 보안 토큰의 유효성을 확인하는 방법은 무엇입니까?

bestscript 2023. 5. 20. 22:47

Azure AD 보안 토큰의 유효성을 확인하는 방법은 무엇입니까?

다음 코드는 나에게 줍니다.Azure AD security token토큰이 유효한지 여부를 확인해야 합니다.어떻게 이를 달성할 수 있습니까?

// Get OAuth token using client credentials 
string tenantName = "mytest.onmicrosoft.com";
string authString = "https://login.microsoftonline.com/" + tenantName;

AuthenticationContext authenticationContext = new AuthenticationContext(authString, false);

// Config for OAuth client credentials  
string clientId = "fffff33-6666-4888-a4tt-fbttt44444";
string key = "123v47o=";
ClientCredential clientCred = new ClientCredential(clientId, key);
string resource = "http://mytest.westus.cloudapp.azure.com";
string token;

Task<AuthenticationResult> authenticationResult = authenticationContext.AcquireTokenAsync(resource, clientCred);
token = authenticationResult.Result.AccessToken;
Console.WriteLine(token);
// How can I validate this token inside my service?                

토큰을 확인하는 두 단계가 있습니다.먼저 토큰 서명을 확인하여 토큰이 Azure Active Directory에서 발급되었는지 확인합니다.둘째, 비즈니스 로직을 기반으로 토큰의 클레임을 확인합니다.

예를 들어, 우리는 다음을 확인해야 합니다.iss그리고.aud단일 테넌트 앱을 개발하는 경우 클레임이 발생합니다.그리고 당신은 또한 확인할 필요가 있습니다.nbf토큰이 만료되지 않도록 합니다.더 많은 청구에 대해서는 여기를 참조하십시오.

서명 확인에 대한 자세한 내용은 아래에서 설명합니다. (참고:아래 예제에서는 Azure AD v2 끝점을 사용합니다.클라이언트 앱이 사용 중인 엔드포인트에 해당하는 엔드포인트를 사용해야 합니다.)

Azure AD의 액세스 토큰이 JSON 웹 토큰(J)입니다.WT) - 보안 토큰 서비스에서 개인 키로 서명합니다.

JWT에는 헤더, 데이터 및 서명의 세 부분이 포함됩니다.기술적으로 공개 키를 사용하여 액세스 토큰의 유효성을 검사할 수 있습니다.

첫 번째 단계 – 서명 토큰(공개 키) 검색 및 캐시

엔드포인트: https://login.microsoftonline.com/common/v2.0/ .well-known/openid-configuration

그러면 우리는 그것을 사용할 수 있습니다.JwtSecurityTokenHandler아래 샘플 코드를 사용하여 토큰을 확인합니다.

 public JwtSecurityToken Validate(string token)
 {
     string stsDiscoveryEndpoint = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration";

     ConfigurationManager<OpenIdConnectConfiguration> configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint);

     OpenIdConnectConfiguration config = configManager.GetConfigurationAsync().Result;

     TokenValidationParameters validationParameters = new TokenValidationParameters
     {
         ValidateAudience = false,
         ValidateIssuer = false,
         IssuerSigningTokens = config.SigningTokens,
         ValidateLifetime = false
     };

     JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();

     SecurityToken jwt;

     var result = tokenHandler.ValidateToken(token, validationParameters, out jwt);

     return jwt as JwtSecurityToken;
 }

또한 프로젝트에서 OWIN 구성 요소를 사용하는 경우 토큰을 보다 쉽게 확인할 수 있습니다.아래 코드를 사용하여 토큰을 확인할 수 있습니다.

app.UseWindowsAzureActiveDirectoryBearerAuthentication(
            new WindowsAzureActiveDirectoryBearerAuthenticationOptions
            {
                Audience = ConfigurationManager.AppSettings["ida:Audience"],
                Tenant = ConfigurationManager.AppSettings["ida:Tenant"]
            });

그런 다음 아래 코드를 사용하여 토큰의 '범위'를 확인할 수 있습니다.

public IEnumerable<TodoItem> Get()
{
    // user_impersonation is the default permission exposed by applications in AAD
    if (ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/scope").Value != "user_impersonation")
    {
        throw new HttpResponseException(new HttpResponseMessage {
          StatusCode = HttpStatusCode.Unauthorized,
          ReasonPhrase = "The Scope claim does not contain 'user_impersonation' or scope claim not found"
        });
    }
    ...
}

다음은 Azure AD로 웹 API를 보호한 코드 샘플입니다.

Azure AD의 베어러 토큰을 사용하여 웹 API 보호

.net Core 2.0을 사용하는 사람들을 위한 Fei의 답변에 추가하고 싶었습니다.

당신은 두 줄을 수정해야 할 것입니다.Validate(string token)방법.

 var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(
        stsDiscoveryEndpoint,
        new OpenIdConnectConfigurationRetriever()); //1. need the 'new OpenIdConnect...'

 OpenIdConnectConfiguration config = configManager.GetConfigurationAsync().Result;
 TokenValidationParameters validationParameters = new TokenValidationParameters
 {
     //decode the JWT to see what these values should be
     ValidAudience = "some audience",
     ValidIssuer = "some issuer",

     ValidateAudience = true,
     ValidateIssuer = true,
     IssuerSigningKeys = config.SigningKeys, //2. .NET Core equivalent is "IssuerSigningKeys" and "SigningKeys"
     ValidateLifetime = true
 };

하지만 OWIN을 프로젝트에 사용하지 않으면 조금 어렵거나 최소한 시간이 소요됩니다.이 기사여기에 훌륭한 자원이 있습니다.

그리고 위에 추가할 내용이 별로 없어서 세부코드만 빼고..다음은 유용한 기능입니다.

 public async Task<ClaimsPrincipal> CreatePrincipleAsync()
    {
        AzureActiveDirectoryToken azureToken = Token.FromJsonString<AzureActiveDirectoryToken>();
        var allParts = azureToken.IdToken.Split(".");
        var header = allParts[0];
        var payload = allParts[1];
        var idToken = payload.ToBytesFromBase64URLString().ToAscii().FromJsonString<AzureActiveDirectoryIdToken>();

        allParts = azureToken.AccessToken.Split(".");
        header = allParts[0];
        payload = allParts[1];
        var signature = allParts[2];
        var accessToken = payload.ToBytesFromBase64URLString().ToAscii().FromJsonString<AzureActiveDirectoryAccessToken>();

        var accessTokenHeader = header.ToBytesFromBase64URLString().ToAscii().FromJsonString<AzureTokenHeader>();
        var isValid = await ValidateToken(accessTokenHeader.kid, header, payload, signature);
        if (!isValid)
        {
            throw new SecurityException("Token can not be validated");
        }
        var principal = await CreatePrincipalAsync(accessToken, idToken);
        return principal;
    }



    private async Task<bool> ValidateToken(string kid, string header, string payload, string signature)
    {
        string keysAsString = null;
        const string microsoftKeysUrl = "https://login.microsoftonline.com/common/discovery/keys";

        using (var client = new HttpClient())
        {
            keysAsString = await client.GetStringAsync(microsoftKeysUrl);
        }
        var azureKeys = keysAsString.FromJsonString<MicrosoftConfigurationKeys>();
        var signatureKeyIdentifier = azureKeys.Keys.FirstOrDefault(key => key.kid.Equals(kid));
        if (signatureKeyIdentifier.IsNotNull())
        {
            var signatureKey = signatureKeyIdentifier.x5c.First();
            var certificate = new X509Certificate2(signatureKey.ToBytesFromBase64URLString());
            var rsa = certificate.GetRSAPublicKey();
            var data = string.Format("{0}.{1}", header, payload).ToBytes();

            var isValidSignature = rsa.VerifyData(data, signature.ToBytesFromBase64URLString(), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
            return isValidSignature;
        }

        return false;
    }

여기서 사용하는 기능 중에는 사용할 수 없는 기능도 있습니다. 자체적으로 설명할 수 있습니다.

언급URL : https://stackoverflow.com/questions/39866513/how-to-validate-azure-ad-security-token