Coder Social home page Coder Social logo

azure-samples / active-directory-dotnetcore-devicecodeflow-v2 Goto Github PK

View Code? Open in Web Editor NEW
46.0 45.0 26.0 271 KB

.NET Core console application letting a user acquire a token for the Microsoft Graph by signing in through another device having a Web browser, with the Azure AD v2.0 endpoint

Home Page: https://aka.ms/msal-net-device-code-flow

License: MIT License

C# 61.78% PowerShell 38.22%
dotnetcore aadv2

active-directory-dotnetcore-devicecodeflow-v2's Introduction

page_type languages products description urlFragment
sample
csharp
powershell
azure-active-directory
This sample demonstrates how to leverage MSAL.NET from apps that do not have the capability of offering an interactive authentication experience.
invoke-protected-api-text

Invoking an API protected by Microsoft identity platform from a text-only device

Build status

We have renamed the default branch to main. To rename your local repo follow the directions here.

About this sample

Overview

This sample demonstrates how to leverage MSAL.NET from apps that do not have the capability of offering an interactive authentication experience. It enables these apps to:

  • authenticate a user
  • and call to a web API (in this case, the Microsoft Graph)

The sample uses the OAuth2 device code flow. The app is built entirely on .NET Core, hence it can be ran as-is on Windows (including Nano Server), OSX, and Linux machines.

To emulate a device not capable of showing UX, the sample is packaged as a .NET Core console application. The application signs users in with Azure Active Directory (Azure AD), using the Microsoft Authentication Library for .NET (MSAL.NET) to obtain a JWT access token through the OAuth 2.0 protocol. The access token is then used to call the Microsoft Graph API to obtain information about the user who signed-in. The sample is structured so that you can call your own API

Topology

If you would like to get started immediately, skip this section and jump to How To Run The Sample.

Scenario

The application obtains tokens through a two steps process especially designed for devices and operating systems that cannot display any UX. Examples of such applications are applications running on iOT, or Command-Line tools (CLI). The idea is that:

  1. whenever a user authentication is required, the command-line app provides a code and asks the user to use another device (such as an internet-connected smartphone) to navigate to https://microsoft.com/devicelogin, where the user will be prompted to enter the code. That done, the web page will lead the user through a normal authentication experience, including consent prompts and multi factor authentication if necessary.

UI

  1. Upon successful authentication, the command-line app will receive the required tokens through a back channel and will use it to perform the web API calls it needs. In this case, the sample displays information about the user who signed-in and their manager.

About the code

The code for handling the token acquisition process is simple, as it boils down to calling the AcquireTokenWithDeviceCodeAsync method of PublicClientApplication to which you pass a callback that will display information to the user about where they should navigate to, and which code to enter to initiate a sign-in. See the GetTokenForWebApiUsingDeviceCodeFlowAsync method in device-code-flow-console\PublicAppUsingDeviceCodeFlow.cs.

async Task<AuthenticationResult> GetTokenForWebApiUsingDeviceCodeFlowAsync()

    AuthenticationResult result;
    try
    {
        result = await app.AcquireTokenWithDeviceCodeAsync(Scopes,
            deviceCodeCallback =>
            {
                Console.WriteLine(deviceCodeCallback.Message);
                return Task.FromResult(0);
                });
            }
        
        ...
        // error handling omitted here (see sample for details)
        return result;
    }

How to run this sample

To run this sample, you'll need:

  • Visual Studio 2019 or just the .NET Core SDK. You will need the .NET Core 3.1 SDK. If you don't have it already, you can download from Visual Studio SDKs
  • An Internet connection
  • A Windows machine (necessary if you want to run the app on Windows)
  • An OS X machine (necessary if you want to run the app on Mac)
  • A Linux machine (necessary if you want to run the app on Linux)
  • An Azure Active Directory (Azure AD) tenant. For more information on how to get an Azure AD tenant, see How to get an Azure AD tenant
  • A user account in your Azure AD tenant. This sample will not work with a Microsoft account (formerly Windows Live account). Therefore, if you signed in to the Azure portal with a Microsoft account and have never created a user account in your directory before, you need to do that now.

Step 1: Clone or download this repository

From your shell or command line:

git clone https://github.com/Azure-Samples/active-directory-dotnetcore-devicecodeflow-v2.git

or download and extract the repository .zip file.

Given that the name of the sample is pretty long, and so are the name of the referenced NuGet packages, you might want to clone it in a folder close to the root of your hard drive, to avoid file size limitations on Windows.

Step 2: Setup .NET Core

The .NET Core documentation pages provide step by step instructions for installing .NET Core (the .NET Execution Environment) for your platform of choice.

Step 3: Run the sample

If you prefer to use Visual Studio

Open the solution in Visual Studio, restore the NuGet packages, select the project, and start it in the debugger.

(otherwise) on any platform

Open a terminal and navigate to the project folder (device-code-flow-console). Restore the packages with the following command:

    dotnet restore

Launch the app by entering the following command:

    dotnet run

Operating the sample

When you run the sample, you will be presented with a prompt telling you

To sign in, use a web browser to open the page https://microsoft.com/devicelogin. Enter the code B7D3SVXHV to authenticate.

Then:

  1. Open a browser on any device. For instance, the browser can be on the computer on which you are running the sample, or even your smartphone. Then navigate, as instructed, to https://microsoft.com/devicelogin

  2. Once there, type in the code provided by the app (in this sample, I am typing B7D3SVXHV) and hit enter. The web page will proceed to prompt you for authentication: please authenticate as a user (native or guest) in the tenant that you specified in the application. Note that, thanks to the fact that you are using an external browser or a different, browser capable device, you can authenticate without restrictions: for example, if your tenant requires you to authenticate using MFA, you are able to do so. That experience would not have been possible if you had to drive the authentication operations exclusively in the console.

  3. Once you successfully authenticate, go back to the console app. You'll see that the app has now access to the token it needs to query the Microsoft Graph API and display information about the signed-in user.

Optional: configure the sample as an app in your directory tenant

The instructions so far leveraged the Azure AD entry for the app in a Microsoft test tenant: given that the app is multi-tenant, anybody can run the sample against that app entry. To register your project in your own Azure AD tenant, you can find instructions to manually provision the sample in your own tenant, so that you can exercise complete control on the app settings and behavior.

  • either follow the manual steps
  • or use PowerShell scripts that:
    • automatically creates the Azure AD applications and related objects (passwords, permissions, dependencies) for you
    • modify the Visual Studio projects' configuration files.

If you want to use this automation:

  1. On Windows run PowerShell and navigate to the root of the cloned directory

  2. In PowerShell run:

    Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force
  3. Run the script to create your Azure AD application and configure the code of the sample application accordingly.

    .\AppCreationScripts\Configure.ps1

    Other ways of running the scripts are described in App Creation Scripts

  4. Open the Visual Studio solution and click start

If you don't want to use this automation, follow the steps below

First step: choose the Azure AD tenant where you want to create your applications

As a first step you'll need to:

  1. Sign in to the Azure portal using either a work or school account or a personal Microsoft account.
  2. If your account is present in more than one Azure AD tenant, select Directory + Subscription at the top right corner in the menu on top of the page, and switch your portal session to the desired Azure AD tenant.
  3. In the left-hand navigation pane, select the Azure Active Directory service, and then select App registrations.

In the next steps, you might need the tenant name (or directory name) or the tenant ID (or directory ID). These are presented in the Properties of the Azure Active Directory window respectively as Name and Directory ID

Register the client app (active-directory-dotnet-deviceprofile)

  1. In App registrations page, select New registration.
  2. When the Register an application page appears, enter your application's registration information:
    • In the Name section, enter a meaningful application name that will be displayed to users of the app, for example active-directory-dotnet-deviceprofile.
    • In the Supported account types section, select Accounts in any organizational directory.
  3. Select Register to create the application.
  4. On the app Overview page, find the Application (client) ID value and record it for later. You'll need it to configure the Visual Studio configuration file for this project.
  5. In the list of pages for the app, select Manifest, and:
    • In the manifest editor, set the allowPublicClient property to true
    • Select Save in the bar above the manifest editor.
  6. In the list of pages for the app, select API permissions
    • Click the Add a permission button and then,
    • Ensure that the Microsoft APIs tab is selected
    • In the Commonly used Microsoft APIs section, click on Microsoft Graph
    • In the Delegated permissions section, ensure that the right permissions are checked: User.Read, User.ReadBasic.All. Use the search box if necessary.
    • Select the Add permissions button

Configure the sample to use your Azure AD tenant

In the steps below, ClientID is the same as Application ID or AppId.

Open the solution in Visual Studio to configure the projects

Configure the client project

Note: if you used the setup scripts, the changes below will have been applied for you

  1. Open the device-code-flow-console\appsettings.json file
  2. Find the app key ClientId and replace the existing value with the application ID (clientId) of the active-directory-dotnet-deviceprofile application copied from the Azure portal.
  3. (Optional) If you created a single tenant application, find the line where TenantId is set and replace the existing value with your tenant ID.

Community Help and Support

Use Stack Overflow to get support from the community. Ask your questions on Stack Overflow first and browse existing issues to see if someone has asked your question before. Make sure that your questions or comments are tagged with [msal dotnet].

If you find a bug in the sample, please raise the issue on GitHub Issues.

To provide a recommendation, visit the following User Voice page.

Contributing

If you'd like to contribute to this sample, see CONTRIBUTING.MD.

This project has adopted the Microsoft Open Source Code of Conduct. For more information, see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

More information

For more information, see MSAL.NET's conceptual documentation:

For more information about the Microsoft identity platform, see:

active-directory-dotnetcore-devicecodeflow-v2's People

Contributors

bgavrilms avatar briantjackett avatar dependabot[bot] avatar gladjohn avatar gladwinjohnson avatar henrik-me avatar jennyf19 avatar jmprieur avatar markzuber avatar microsoftopensource avatar msftgits avatar neha-bhargava avatar pmaytak avatar ramya25 avatar rwike77 avatar sameerk-msft avatar supernova-eng avatar trwalke avatar v-hearya avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

active-directory-dotnetcore-devicecodeflow-v2's Issues

This sample will not work with a Microsoft account

This issue is for a: (mark with an x)

- [ ] bug report -> please search issues before submitting
- [X ] feature request
- [ ] documentation issue or request
- [ ] regression (a behavior that used to work and stopped in a new release)

Minimal steps to reproduce

Log in with a Microsoft account

Any log messages given by the failure

AADSTS500201: We are unable to issue tokens from this API version for a Microsoft account. Please contact the application vendor as they need to use version 2.0 of the protocol to support this.

Expected/desired behavior

Successful login

OS and Version?

Windows 10

Versions

Windows 10

Mention any other details that might be useful

I know the readme/writeup says that this sample will not work with a Microsoft account. Is there anything I can do to make this work with a Microsoft account?


Thanks! We'll be in touch soon.

MSA Support

I am interested in this scenario for accessing my personal OneDrive through the Graph. This is the closest method I have seen to working for .net core. Are there plans to make this work with MSA as well? What about providing an api function that takes a username and password so that information can be read in any manner desired by the developer?

Token cache serialization with Devicecode flow

Please provide us with the following information:

This issue is for a: (mark with an x)

- [ ] bug report -> please search issues before submitting
- [x] feature request
- [ ] documentation issue or request
- [ ] regression (a behavior that used to work and stopped in a new release)

Expected/desired behavior

Token cache serialization with Devicecode flow

Mention any other details that might be useful

I want to get token with Devicecode flow, and save token in SQL server or Redis.
You say
"Customizing Token cache serialization (was not done in this sample, but you might want to add a serialized cache)"
in readme, but I cannot do well.

To use SQL server, I Think using this method.
AddDistributedSqlServerCache()

I reserched serialized cache samples, I found Web application method or ConfidentialClientApplication method.
But I cannnot find using Public Client Application method.

Using Devicecode flow and serialzation, I want to use Graph API on serverless application.

Do you have the sample of saving token in database using public client application?
If not, Could you guid me the points?


Thanks! We'll be in touch soon.

How to configure the service app (not .net core, but .net 4.7 framework)?

In my current project I have the case very familiar that you have implemented in this repository, but in my case service application (TodoList-webAPI) should be implemented using .Net framework 4.7. I understand, that it's not really related to your implementation, but still could you please help me with that?

This issue is for a: (mark with an x)

- [ ] bug report -> please search issues before submitting
- [ ] feature request
- [x ] documentation issue or request
- [ ] regression (a behavior that used to work and stopped in a new release)

Minimal steps to reproduce

1). Run 2-Call-OwnApi Configure.ps1
2). Grant admin consent.
3). Run applications (Daemon-Console and origin TodoList-WebAPI) and ensure that the solution works perfectly.
4). Add a new TodoList-Web app based on ASP.NET project (4.7 .NET Framework) to the solution.
5). Add AAD configuration code:

public void ConfigureAuth(IAppBuilder app)
{
    app.UseWindowsAzureActiveDirectoryBearerAuthentication(
        new WindowsAzureActiveDirectoryBearerAuthenticationOptions
        {
            Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
            TokenValidationParameters = new TokenValidationParameters
            {
                ValidAudience = ConfigurationManager.AppSettings["ida:Audience"]
            },
        });
}

6). Add to web.config:

    <add key="ida:Tenant" value="<tenantName>.onmicrosoft.com" />
    <add key="ida:Audience" value="<service app Application ID URI>" />
    <add key="ida:ClientID" value="<service app Application (client) ID>" />

7). Change original TodoList-WebApi url port to another.
8). Change new TodoList-Web url port to correct.
9). Run applications (Daemon-Console and new TodoList-Web) doesn't work.

Any log messages given by the failure

Error message in the console app:
Failed to call the Web Api: Unauthorized
Content: {"Message":"Authorization has been denied for this request."}

Expected/desired behavior

Daemon-Console and new TodoList-Web works, console app shows items from new TodoList-Web app.

OS and Version?

Windows 10

Versions

Visual Studio 2019, Version 16.4.5

Mention any other details that might be useful


Thanks! We'll be in touch soon.

This repo is a horror story of OOP

Just feedback.

As a starter, this is one horror of a repo to read.

I cannot detemine which is worse, lack of clarity or overuse of patterns. This ought to be a straight foreward example for setting up device authentication, but turns out to be an obfuscated mess filled with the boileplate to fetch /me from graph api.

If you want people to hate OOP, this is the way you write code. As a dev using OOP for 10+ years, I never understood the hate it recieves. But I do now. Your code simply suck.

Unable to login. Getting error: AADSTS7000218 The request body must contain the following parameter...

Please provide us with the following information:

This issue is for a: (mark with an x)

- [x] bug report -> please search issues before submitting
- [ ] feature request
- [ ] documentation issue or request
- [ ] regression (a behavior that used to work and stopped in a new release)

Minimal steps to reproduce

Login specifying TenantId

Any log messages given by the failure

AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'

Expected/desired behavior

Show user logged in info

OS and Version?

Windows 10

Versions

Mention any other details that might be useful

This is the modified appsettings.json that I'm using. Note that I've created a User and I've registered the application.
{
"Authentication": {
"AzureCloudInstance": "AzurePublic",
"Tenant": "organizations",
"TenantId": "5b31a837-fb9b-47cd-82cd-d99eede0dc64",
"ClientId": "482783e9-f148-452c-ab61-90d6ffc009f7"
},
"WebAPI": {
"MicrosoftGraphBaseEndpoint": "https://graph.microsoft.com"
}
}


Thanks! We'll be in touch soon.

Instructions in Readme.md are incorrect in section "Configure the client project"

Following instruction in section "Configure the client project" I get an error:

AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials.

The step 3 should instruct to add "TenantId" key with value copied from the overview tab in Azure portal application registration page. Adding this fixed the error

AADSTS900144: The request body must contain the following parameter: 'client_id'

Please provide us with the following information:

This issue is for a: (mark with an x)

- [X ] bug report -> please search issues before submitting
- [ ] feature request
- [ ] documentation issue or request
- [ ] regression (a behavior that used to work and stopped in a new release)

Minimal steps to reproduce

Login specifying TenantId

Any log messages given by the failure

AADSTS900144: The request body must contain the following parameter: 'client_id'

Expected/desired behavior

OS and Version?

Windows 10.

Versions

Mention any other details that might be useful

My application was working initially, but when users want to Login this error message comes up:

AADSTS900144: The request body must contain the following parameter: 'client_id'

The current .NET SDK does not support targeting .NET Core 2.2

I have Visual Studio Commnity 2017 latest installed,
Microsoft Visual Studio Community 2017
Version 15.9.11
VisualStudio.15.Release/15.9.11+28307.586
Microsoft .NET Framework
Version 4.7.03190

When I attempt to build I'm getting an error that I did not have .NET Core 2.2 installed:

Severity Code Description Project File Line Suppression State
Error NETSDK1045 The current .NET SDK does not support targeting .NET Core 2.2. Either target .NET Core 2.1 or lower, or use a version of the .NET SDK that supports .NET Core 2.2. device-code-flow-console C:\Program Files\dotnet\sdk\2.1.505\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.TargetFrameworkInference.targets 137

Double check what sdks I had, and sure enough .NET Core 2.2 isn't there:

C:\Users\saeeda>dotnet --list-sdks
2.1.401 [C:\Program Files\dotnet\sdk]
2.1.505 [C:\Program Files\dotnet\sdk]

Found the download page for .NET Core here:

https://dotnet.microsoft.com/download/dotnet-core/2.2

Ran the .NET Core installer for 2.2.203 (which is the latest as of the time of writing this) Output of the installer:
The following were installed at C:\Program Files\dotnet
• .NET Core SDK 2.2.203
• .NET Core Runtime 2.2.4
• ASP.NET Core Runtime 2.2.4

C:\Users\saeeda>dotnet --list-sdks
2.1.401 [C:\Program Files\dotnet\sdk]
2.1.505 [C:\Program Files\dotnet\sdk]
2.2.203 [C:\Program Files\dotnet\sdk]

Run the sample again same error:

Severity Code Description Project File Line Suppression State
Error NETSDK1045 The current .NET SDK does not support targeting .NET Core 2.2. Either target .NET Core 2.1 or lower, or use a version of the .NET SDK that supports .NET Core 2.2. device-code-flow-console C:\Program Files\dotnet\sdk\2.1.505\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.TargetFrameworkInference.targets 137

Found another link, this one appears to have a chart showing which .NET Core is needed for which Visual Studio, it says to install v2.2.106 for VS 2019

https://dotnet.microsoft.com/download/visual-studio-sdks

Ran the installer for 2.2.106, output:
The following were installed at C:\Program Files\dotnet
• .NET Core SDK 2.2.106
• .NET Core Runtime 2.2.4
• ASP.NET Core Runtime 2.2.4

Finally I was able to build and run.

I was able to figure it out, but I wasted 20mins searching for the right SDK to install. Let's add a step in the pre-requisites with a link to the .NET Core SDK to install?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.