--- sidebar_label: 'Example code (.NET)' sidebar_position: 2 --- # Example: Authenticating an external user without user interaction in .NET A .NET example generating a signed ID token and using it to initiate a `backchannel_external_token` authentication flow. :::warning This example is intended to illustrate the authentication flow and help you understand how the pieces fit together. It is **not** a recommended, production-ready implementation. When dealing with security-sensitive operations such as token signing, always use well-established, well-maintained libraries rather than building your own. Doing so helps you avoid subtle mistakes that can lead to serious security vulnerabilities. ::: ```csharp #:property TargetFramework=net10.0 #:package System.IdentityModel.Tokens.Jwt@8.22.0 using System.IdentityModel.Tokens.Jwt; using System.Net.Http.Json; using System.Security.Cryptography; using System.Text.Json.Serialization; using Microsoft.IdentityModel.Tokens; const string MyPrivateKeyPEM = "..."; // Your generated private key in PEM format const string MyKeyId = "..."; // The id of your generated private key const string MyClientId = "..."; // Client ID provided by Future Ordering const string MyClientSecret = "..."; // Client secret provided by Future Ordering const string TokenIssuer = "..."; // e.g. `https://myissuer.example.com` const string TokenAudience = "..."; // e.g. `https://.login.futureordering.com` // Prepare signing credentials var ecdsa = ECDsa.Create(); ecdsa.ImportFromPem(MyPrivateKeyPEM); var signingCredentials = new SigningCredentials( new ECDsaSecurityKey(ecdsa) { KeyId = MyKeyId, }, SecurityAlgorithms.EcdsaSha256); // Generate ID token var handler = new JwtSecurityTokenHandler(); var now = DateTime.UtcNow; var token = new JwtSecurityToken( new JwtHeader(signingCredentials), new JwtPayload( issuer: TokenIssuer, audience: TokenAudience, claims: [ new("sub", "my-unique-subject-id"), new("email", "johndoe@example.com"), new("given_name", "John"), new("family_name", "Doe"), ], issuedAt: now, notBefore: now, expires: now.Add(TimeSpan.FromMinutes(5)))); var signedJwt = handler.WriteToken(token); // Send request var httpClient = new HttpClient(); var request = new HttpRequestMessage(HttpMethod.Post, $"{TokenAudience}/connect/token") { Content = new FormUrlEncodedContent( [ new("grant_type", "backchannel_external_token"), new("client_id", MyClientId), new("client_secret", MyClientSecret), new("subject_token", signedJwt), new("subject_token_type", "urn:ietf:params:oauth:token-type:id_token"), new("scope", "fo:auth"), ]) }; var response = await httpClient.SendAsync(request); // Receive and parse request var result = await response.Content.ReadFromJsonAsync(); Console.WriteLine($"Got access token jwt: {result!.AccessToken}"); record TokenResponse( [property: JsonPropertyName("access_token")] string AccessToken, [property: JsonPropertyName("expires_in")] int? ExpiresIn); ```