{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Sample C# Application","description":"Accelerate E&P application development and protect your innovation by consuming our Data and Domain APIs / Platform APIs.","lang":"en-US","meta":[{"name":"robots","content":"noindex"}],"llmstxt":{"hide":true,"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"sample-c-application","__idx":0},"children":["Sample C# Application"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"introduction","__idx":1},"children":["Introduction"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This tutorial illustrates how to use SLB Authenticator in your C# application. It demonstrates how to implement the OpenID Connect (OIDC) Authorization Code flow with Proof Key for Code Exchange (",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://oauth.net/2/pkce/"},"children":["PKCE"]},"). Instead of building the implementation from scratch, we'll use the proven Duende IdentityModel.OidcClient library, which provides a robust and well-tested OIDC client implementation."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://oauth.net/2/pkce/"},"children":["PKCE"]}," flow is the recommended approach for public clients (such as mobile apps, SPAs, and native desktop applications) as it provides additional security by eliminating the need to store client secrets and mitigates authorization code interception attacks.In this tutorial we will use ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://github.com/DuendeSoftware/foss/tree/main/identity-model-oidc-client/samples/NetCoreConsoleClient"},"children":["Cross Platform Console Applications Sample"]},". Refer to the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://docs.duendesoftware.com/identitymodel-oidcclient/samples/"},"children":["Duende IdentityModel OIDC Client Samples"]}," if you want to explore more samples."]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Note"]},": This tutorial was prepared and tested using ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["IdentityModel.OidcClient version 6.0.0"]},". While newer versions should work, we recommend using this specific version to ensure compatibility with the provided examples."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"prerequisites","__idx":2},"children":["Prerequisites"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Before starting this tutorial, ensure you have the following:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[".NET 9.0 SDK"]}," or later installed on your development machine."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Git"]}," installed for cloning the repository."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Visual Studio 2022"]},", ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Visual Studio Code"]},", or your preferred .NET IDE."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Access to ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://developer.delfi.slb.com/"},"children":["SLB Developer Portal"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["You need to be a member of a Team on SLB Developer."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"register-your-application-and-client","__idx":3},"children":["Register Your application and client"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Before implementing the OIDC flow, you need to register your application in the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://developer.delfi.slb.com/"},"children":["SLB Developer Portal"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Next you will need to register client. Refer to ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/create-client#create-clients-for-desktop/mobile-apps"},"children":["Create Clients for Desktop/Mobile Apps"]}," to know details on how to create client."]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Note"]}," During client creation add ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["http:/127.0.0.1"]}," as a redirect URI. Do not specify port as sample application will use dynamic port."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"clone-the-sample-repository","__idx":4},"children":["Clone the Sample Repository"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Clone the Duende IdentityModel sample repository that contains the OIDC client implementation:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"git clone https://github.com/DuendeSoftware/foss.git\ncd foss/identity-model-oidc-client/samples/NetCoreConsoleClient\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"examine-the-sample-structure","__idx":5},"children":["Examine the Sample Structure"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The sample application contains the following key files:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["NetCoreConsoleClient.sln"]}," - Solution file."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["src/NetCoreConsoleClient/Program.cs"]}," - Main application entry point with OIDC client configuration."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["src/NetCoreConsoleClient/NetCoreConsoleClient.csproj"]}," - Project file with required NuGet packages."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["src/NetCoreConsoleClient/SystemBrowser.cs"]}," - Helper class for launching system browser for authentication."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"configure-the-sample-for-slb-authenticator","__idx":6},"children":["Configure the Sample for SLB Authenticator"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Open ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Program.cs"]}," and locate declaration of the field ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["_authority"]}," of the class ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Program"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"csharp","header":{"controls":{"copy":{}}},"source":"    public class Program\n    {\n        static string _authority = \"https://demo.duendesoftware.com\";\n        ...\n","lang":"csharp"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["By default this sample code uses ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://demo.duendesoftware.com"]}," as OIDC provider authority. Replace ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["_authority"]}," field value URI with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://csi.slb.com/v2"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"csharp","header":{"controls":{"copy":{}}},"source":"    public class Program\n    {\n        static string _authority = \"https://csi.slb.com/v2\";\n        ...\n\n","lang":"csharp"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["In the same file locate initialization of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["OidcClientOptions"]}," class inside ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Login"]}," method:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"csharp","header":{"controls":{"copy":{}}},"source":"        private static async Task Login()\n        {\n            ...\n            var options = new OidcClientOptions\n            {\n                Authority = _authority,\n                ClientId = \"interactive.public\",\n                RedirectUri = redirectUri,\n                Scope = \"openid profile api\",\n                FilterClaims = false,\n                Browser = browser,\n            };\n            ...\n","lang":"csharp"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Replace ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ClientId"]}," property with your Client ID. Replace value of the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Scope"]}," property with \"openid profile\". Or you can replace \"api\" with any APIs allowed for your application:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"csharp","header":{"controls":{"copy":{}}},"source":"        private static async Task Login()\n        {\n            ...\n            var options = new OidcClientOptions\n            {\n                Authority = _authority,\n                ClientId = \"<<your clientId>>\",\n                RedirectUri = redirectUri,\n                Scope = \"openid profile\",\n                FilterClaims = false,\n                Browser = browser,\n            };\n            ...\n","lang":"csharp"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["At the end of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Login"]}," method locate and comment next line:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"csharp","header":{"controls":{"copy":{}}},"source":"            await NextSteps(result, oidcClient);\n","lang":"csharp"},"children":[]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Note"]},": By default this example can demonstrate how to refresh token or how to implement API call using acquired Access Token. Fill free to update this sample code to use any Slb Digital APIs allowed for your application. You would need to:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Keep call of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["NextSteps"]}," method uncommented ."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Replace field  ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["_api"]},"  value with the API base URI of the Delfi API you are planning to use."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Add API client Id to the scope (space separated) in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["OidcClientOptions"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Update ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CallApi"]}," method to make a call to specific endpoint."]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"test-modified-sample-application","__idx":7},"children":["Test modified sample application"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"install-required-dependencies","__idx":8},"children":["Install Required Dependencies"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Restore the packages:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"dotnet restore\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Note"]}," You can restore the packages from your IDE as well"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"build-and-run","__idx":9},"children":["Build and Run"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Build and run the sample application:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"dotnet build\ndotnet run\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When you run the application:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The application will open your default browser."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["You'll be redirected to the SLB Authenticator login page."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Enter your Delfi credentials."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["After successful authentication, you'll be redirected back to the application."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The application will display the received tokens and user claims."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"verify-token-content","__idx":10},"children":["Verify Token Content"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The sample application should output:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Access Token"]},": Used for API calls to Digital Platform services."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Identity Token"]},": Contains user identity information."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Refresh Token"]},": Used to obtain new access tokens."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["User Claims"]},": Information about the authenticated user."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"disclaimer","__idx":11},"children":["Disclaimer"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["These instructions work with Duende Software Cross Platform Console Applications Sample as of June 4th, 2025, but this public sample is constantly being updated. The detailed instructions are provided as a convenience for new web developers and are only to be used as a guide. The documentation in Cross Platform Console Applications Sample take precedence."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"recommended-further-reading","__idx":12},"children":["Recommended further Reading"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/solutions/ccm/tutorial/user-context-service"},"children":["User context"]}," in SLB Digital platform"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/solutions/sauth/tutorial/secret-management-service"},"children":["Secret management"]}," on SLB Digital platform"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/cloud-apis/references/api-lifecycle"},"children":["API Maturity"]}," of cloud APIs"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Refer tutorial of various solutions (e.g. ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/solutions/fdplan/tutorial/about"},"children":["FDPlan"]},", ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/solutions/drillplan/docs/tutorials/tutorial"},"children":["DrillPlan"]},", ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/solutions/core-service/tutorial/osdu-core-services-about"},"children":["MPDF"]}," etc.) to learn more about their extensibility and how to integrate with APIs offered by these solutions into your application."]}]}]},"headings":[{"value":"Sample C# Application","id":"sample-c-application","depth":1},{"value":"Introduction","id":"introduction","depth":2},{"value":"Prerequisites","id":"prerequisites","depth":2},{"value":"Register Your application and client","id":"register-your-application-and-client","depth":2},{"value":"Clone the Sample Repository","id":"clone-the-sample-repository","depth":2},{"value":"Examine the Sample Structure","id":"examine-the-sample-structure","depth":2},{"value":"Configure the Sample for SLB Authenticator","id":"configure-the-sample-for-slb-authenticator","depth":2},{"value":"Test modified sample application","id":"test-modified-sample-application","depth":2},{"value":"Install Required Dependencies","id":"install-required-dependencies","depth":3},{"value":"Build and Run","id":"build-and-run","depth":3},{"value":"Verify Token Content","id":"verify-token-content","depth":3},{"value":"Disclaimer","id":"disclaimer","depth":2},{"value":"Recommended further Reading","id":"recommended-further-reading","depth":2}],"frontmatter":{"seo":{"title":"Sample C# Application"}},"lastModified":"2025-06-11T17:11:47.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/cloud-apis/create-first-app/csharp-code-sample","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}