Skip to content

Commit ba31ab9

Browse files

File tree

405 files changed

+52911
-35
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

405 files changed

+52911
-35
lines changed

Diff for: .bowerrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"directory": "wwwroot/lib"
3+
}

Diff for: Controllers/AccountController.cs

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using Microsoft.AspNetCore.Authentication;
6+
using Microsoft.AspNetCore.Authentication.Cookies;
7+
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
8+
using Microsoft.AspNetCore.Mvc;
9+
10+
namespace WebApp_OpenIDConnect_DotNet.Controllers
11+
{
12+
[Route("[controller]/[action]")]
13+
public class AccountController : Controller
14+
{
15+
[HttpGet]
16+
public IActionResult SignIn()
17+
{
18+
var redirectUrl = Url.Action(nameof(HomeController.Index), "Home");
19+
return Challenge(
20+
new AuthenticationProperties { RedirectUri = redirectUrl },
21+
OpenIdConnectDefaults.AuthenticationScheme);
22+
}
23+
24+
[HttpGet]
25+
public IActionResult SignOut()
26+
{
27+
var callbackUrl = Url.Action(nameof(SignedOut), "Account", values: null, protocol: Request.Scheme);
28+
return SignOut(
29+
new AuthenticationProperties { RedirectUri = callbackUrl },
30+
CookieAuthenticationDefaults.AuthenticationScheme,
31+
OpenIdConnectDefaults.AuthenticationScheme);
32+
}
33+
34+
[HttpGet]
35+
public IActionResult SignedOut()
36+
{
37+
if (User.Identity.IsAuthenticated)
38+
{
39+
// Redirect to home page if the user is authenticated.
40+
return RedirectToAction(nameof(HomeController.Index), "Home");
41+
}
42+
43+
return View();
44+
}
45+
46+
[HttpGet]
47+
public IActionResult AccessDenied()
48+
{
49+
return View();
50+
}
51+
}
52+
}

Diff for: Controllers/HomeController.cs

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
using Microsoft.AspNetCore.Authorization;
7+
using Microsoft.AspNetCore.Mvc;
8+
using WebApp_OpenIDConnect_DotNet.Models;
9+
10+
namespace WebApp_OpenIDConnect_DotNet.Controllers
11+
{
12+
[Authorize]
13+
public class HomeController : Controller
14+
{
15+
public IActionResult Index()
16+
{
17+
return View();
18+
}
19+
20+
public IActionResult About()
21+
{
22+
ViewData["Message"] = "Your application description page.";
23+
24+
return View();
25+
}
26+
27+
public IActionResult Contact()
28+
{
29+
ViewData["Message"] = "Your contact page.";
30+
31+
return View();
32+
}
33+
34+
[AllowAnonymous]
35+
public IActionResult Error()
36+
{
37+
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
38+
}
39+
}
40+
}

Diff for: Extensions/AzureAdAuthenticationBuilderExtensions.cs

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
3+
using Microsoft.Extensions.Configuration;
4+
using Microsoft.Extensions.DependencyInjection;
5+
using Microsoft.Extensions.Options;
6+
7+
namespace Microsoft.AspNetCore.Authentication
8+
{
9+
public static class AzureAdAuthenticationBuilderExtensions
10+
{
11+
public static AuthenticationBuilder AddAzureAd(this AuthenticationBuilder builder)
12+
=> builder.AddAzureAd(_ => { });
13+
14+
public static AuthenticationBuilder AddAzureAd(this AuthenticationBuilder builder, Action<AzureAdOptions> configureOptions)
15+
{
16+
builder.Services.Configure(configureOptions);
17+
builder.Services.AddSingleton<IConfigureOptions<OpenIdConnectOptions>, ConfigureAzureOptions>();
18+
builder.AddOpenIdConnect();
19+
return builder;
20+
}
21+
22+
private class ConfigureAzureOptions: IConfigureNamedOptions<OpenIdConnectOptions>
23+
{
24+
private readonly AzureAdOptions _azureOptions;
25+
26+
public ConfigureAzureOptions(IOptions<AzureAdOptions> azureOptions)
27+
{
28+
_azureOptions = azureOptions.Value;
29+
}
30+
31+
public void Configure(string name, OpenIdConnectOptions options)
32+
{
33+
options.ClientId = _azureOptions.ClientId;
34+
options.Authority = $"{_azureOptions.Instance}{_azureOptions.TenantId}";
35+
options.UseTokenLifetime = true;
36+
options.CallbackPath = _azureOptions.CallbackPath;
37+
options.RequireHttpsMetadata = false;
38+
}
39+
40+
public void Configure(OpenIdConnectOptions options)
41+
{
42+
Configure(Options.DefaultName, options);
43+
}
44+
}
45+
}
46+
}

Diff for: Extensions/AzureAdOptions.cs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace Microsoft.AspNetCore.Authentication
2+
{
3+
public class AzureAdOptions
4+
{
5+
public string ClientId { get; set; }
6+
7+
public string ClientSecret { get; set; }
8+
9+
public string Instance { get; set; }
10+
11+
public string Domain { get; set; }
12+
13+
public string TenantId { get; set; }
14+
15+
public string CallbackPath { get; set; }
16+
}
17+
}

Diff for: LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2015 Microsoft Corporation
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Diff for: Models/ErrorViewModel.cs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System;
2+
3+
namespace WebApp_OpenIDConnect_DotNet.Models
4+
{
5+
public class ErrorViewModel
6+
{
7+
public string RequestId { get; set; }
8+
9+
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
10+
}
11+
}

Diff for: Program.cs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using Microsoft.AspNetCore;
2+
using Microsoft.AspNetCore.Hosting;
3+
4+
namespace WebApp_OpenIDConnect_DotNet
5+
{
6+
public class Program
7+
{
8+
public static void Main(string[] args)
9+
{
10+
BuildWebHost(args).Run();
11+
}
12+
13+
public static IWebHost BuildWebHost(string[] args) =>
14+
WebHost.CreateDefaultBuilder(args)
15+
.UseStartup<Startup>()
16+
.Build();
17+
}
18+
}

Diff for: README.md

+77-35
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,99 @@
1-
# Project Name
1+
---
2+
services: active-directory
3+
platforms: dotnet
4+
author: jmprieur
5+
---
26

3-
(short, 1-3 sentenced, description of the project)
7+
# Integrating Azure AD into an ASP.NET Core web app
48

5-
## Features
9+
This sample shows how to build a .NET MVC web app that uses OpenID Connect to sign-in users from a single Azure Active Directory (Azure AD) tenant using the ASP.NET Core OpenID Connect middleware.
610

7-
This project framework provides the following features:
11+
For more information on how the protocols work in this scenario and other scenarios, see [Authentication Scenarios for Azure AD](http://go.microsoft.com/fwlink/?LinkId=394414).
812

9-
* Feature 1
10-
* Feature 2
11-
* ...
13+
## How to run this sample
1214

13-
## Getting Started
15+
If you are interested in ASP.NET Core 1.1, please look at branch [aspnet_core_1_1](https://github.com/Azure-Samples/active-directory-dotnet-webapp-openidconnect-aspnetcore/tree/aspnet_core_1_1).
1416

15-
### Prerequisites
17+
To run this sample:
18+
- Install .NET Core for Windows by following the instructions at [.NET and C# - Get Started in 10 Minutes](https://www.microsoft.com/net/core). In addition to developing on Windows, you can develop on [Linux](https://www.microsoft.com/net/core#linuxredhat), [Mac](https://www.microsoft.com/net/core#macos), or [Docker](https://www.microsoft.com/net/core#dockercmd).
19+
- An Azure AD tenant. For more information on how to obtain an Azure AD tenant, see [How to get an Azure AD tenant](https://azure.microsoft.com/documentation/articles/active-directory-howto-tenant/).
1620

17-
(ideally very short, if any)
21+
### Step 1: Register the sample with your Azure AD tenant
1822

19-
- OS
20-
- Library version
21-
- ...
23+
1. Sign in to the [Azure portal](https://portal.azure.com).
2224

23-
### Installation
25+
2. On the top bar, select your account. Under the **DIRECTORY** list, choose the Active Directory tenant where you wish to register your app. If there isn't a **DIRECTORY** list in the drop down menu, skip this step, as you only have a single tenant associated with your Azure account. For more information, see [How to get an Azure Active Directory tenant](https://docs.microsoft.com/azure/active-directory/develop/active-directory-howto-tenant).
2426

25-
(ideally very short)
27+
3. In the left navigation sidebar, select **Azure Active Directory**. If you don't see **Azure Active Directory** in the list, select **More Services** and choose **Azure Active Directory** in the **SECURITY + IDENTITY** section of the service list.
2628

27-
- npm install [package name]
28-
- mvn install
29-
- ...
29+
4. From the sidebar, select **App registrations**.
3030

31-
### Quickstart
32-
(Add steps to get up and running quickly)
31+
5. Select **New application registration** and provide a friendly name for the app, app type, and sign-on URL:
32+
**Name**: **WebApp-OpenIDConnect-DotNet**
33+
**Application Type**: **Web app / API**
34+
**Sign-on URL**: `http://localhost:5000/signin-oidc`
35+
Select **Create** to register the app.
3336

34-
1. git clone [repository clone url]
35-
2. cd [respository name]
36-
3. ...
37+
6. On the **Properties** blade, set the **Logout URL** to `http://localhost:5000/signout-oidc` and select **Save**.
3738

39+
7. From the Azure portal, note the following information:
3840

39-
## Demo
41+
**The Tenant domain:** See the **App ID URI** base URL. For example: `contoso.onmicrosoft.com`
42+
43+
**The Tenant ID:** See the **Endpoints** blade. Record the GUID from any of the endpoint URLs. For example: `da41245a5-11b3-996c-00a8-4d99re19f292`
44+
45+
**The Application ID (Client ID):** See the **Properties** blade. For example: `ba74781c2-53c2-442a-97c2-3d60re42f403`
4046

41-
A demo app is included to show how to use the project.
47+
> [!NOTE]
48+
> The base address in the **Sign-on URL** and **Logout URL** settings is `http://localhost:5000`. This localhost address allows the sample app to run insecurely from your local system. Port 5000 is the default port for the [Kestrel server](https://docs.microsoft.com/aspnet/core/fundamentals/servers/kestrel). Update these URLs if you configure the app for production use (for example, `https://www.contoso.com/signin-oidc` and `https://www.contoso.com/signout-oidc`).
4249
43-
To run the demo, follow these steps:
50+
### Step 2: Create the sample
4451

45-
(Add steps to start up the demo)
52+
This sample was created from the 2.0 [dotnet new mvc](https://docs.microsoft.com/dotnet/core/tools/dotnet-new?tabs=netcore2x) template with `SingleOrg` authentication. You can create the sample from the command line or clone/download this repository:
4653

47-
1.
48-
2.
49-
3.
54+
- To create the sample from the command line, execute the following command:
5055

51-
## Resources
56+
```console
57+
dotnet new mvc --auth SingleOrg --client-id <CLIENT_ID_(APP_ID)> --tenant-id <TENANT_ID> --domain <TENANT_DOMAIN>
58+
```
59+
Use the values that you recorded from the Azure portal for \<CLIENT\_ID\_(APP\_ID)>, \<TENANT\_ID>, and \<TENANT\_DOMAIN>.
5260

53-
(Any additional resources or related projects)
61+
- To clone/download this sample, execute the following command from your shell or command line:
5462

55-
- Link to supporting information
56-
- Link to similar sample
57-
- ...
63+
```console
64+
git clone https://github.com/Azure-Samples/active-directory-dotnet-webapp-openidconnect-aspnetcore.git
65+
```
66+
67+
In the **appsettings.json* file, provide values for the `Domain`, `TenantId`, and `ClientID` that you recorded earlier from the Azure portal.
68+
69+
### Step 3: Run the sample
70+
71+
Build the solution and run it.
72+
73+
Make a request to the app. The app immediately attempts to authenticate you via Azure AD. Sign in with the username and password of a user account that is in your Azure AD tenant. You can also use your tenant's Global Administrator account. If you wish to create a user in the tenant, select **Add a user** from the **Quick tasks** panel. The **Quick tasks** panel is found on the Azure AD tenant's blade in the portal.
74+
75+
## About The code
76+
77+
This sample shows how to use the OpenID Connect ASP.NET Core middleware to sign-in users from a single Azure AD tenant. The middleware is initialized in the `Startup.cs` file by passing it the Client ID of the app and the URL of the Azure AD tenant where the app is registered, which is read from the `appsettings.json` file. The middleware takes care of:
78+
- Downloading the Azure AD metadata, finding the signing keys, and finding the issuer name for the tenant.
79+
- Processing OpenID Connect sign-in responses by validating the signature and issuer in an incoming JWT, extracting the user's claims, and putting the claims in `ClaimsPrincipal.Current`.
80+
- Integrating with the session cookie ASP.NET Core middleware to establish a session for the user.
81+
82+
You can trigger the middleware to send an OpenID Connect sign-in request by decorating a class or method with the `[Authorize]` attribute or by issuing a challenge (see the `AccountController.cs` file):
83+
84+
```csharp
85+
return Challenge(
86+
new AuthenticationProperties { RedirectUri = redirectUrl },
87+
OpenIdConnectDefaults.AuthenticationScheme);
88+
```
89+
90+
Similarly, you can send a signout request:
91+
92+
```csharp
93+
return SignOut(
94+
new AuthenticationProperties { RedirectUri = callbackUrl },
95+
CookieAuthenticationDefaults.AuthenticationScheme,
96+
OpenIdConnectDefaults.AuthenticationScheme);
97+
```
98+
99+
The middleware in this project is created as a part of the open source [ASP.NET Security](https://github.com/aspnet/Security) project.

0 commit comments

Comments
 (0)