diff --git a/samples/IdentityOIDCWebApplicationSample/Areas/IdentityService/Controllers/AccountController.cs b/samples/IdentityOIDCWebApplicationSample/Areas/IdentityService/Controllers/AccountController.cs index a1f81c853d..5f724c48c6 100644 --- a/samples/IdentityOIDCWebApplicationSample/Areas/IdentityService/Controllers/AccountController.cs +++ b/samples/IdentityOIDCWebApplicationSample/Areas/IdentityService/Controllers/AccountController.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using IdentityOIDCWebApplicationSample.Identity.Models; @@ -9,8 +10,10 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.Service; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.Extensions.Logging; +using Microsoft.Net.Http.Headers; namespace IdentityOIDCWebApplicationSample.Identity.Controllers { @@ -41,6 +44,7 @@ namespace IdentityOIDCWebApplicationSample.Identity.Controllers } [HttpGet] + [MsalFilter] public async Task Login(string returnUrl = null) { // Clear the existing external cookie to ensure a clean login process @@ -50,6 +54,25 @@ namespace IdentityOIDCWebApplicationSample.Identity.Controllers return View(); } + [AttributeUsage(System.AttributeTargets.Method, Inherited = false, AllowMultiple = false)] + sealed class MsalFilterAttribute : Attribute, IResultFilter + { + public void OnResultExecuted(ResultExecutedContext context) + { + } + + public void OnResultExecuting(ResultExecutingContext context) + { + if(context.HttpContext.Request.Headers.TryGetValue(HeaderNames.UserAgent, out var header) && + header.Equals("Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; Tablet PC 2.0)") && + context.Result is ViewResult view && + view.ViewName == null) + { + view.ViewName = "Login.MSAL"; + } + } + } + [HttpPost] [ValidateAntiForgeryToken] public async Task Login(LoginViewModel model, string returnUrl = null) diff --git a/samples/IdentityOIDCWebApplicationSample/Areas/IdentityService/Views/Account/Login.MSAL.cshtml b/samples/IdentityOIDCWebApplicationSample/Areas/IdentityService/Views/Account/Login.MSAL.cshtml new file mode 100644 index 0000000000..e36496b539 --- /dev/null +++ b/samples/IdentityOIDCWebApplicationSample/Areas/IdentityService/Views/Account/Login.MSAL.cshtml @@ -0,0 +1,169 @@ +@using System.Collections.Generic +@using System.Linq +@using Microsoft.AspNetCore.Http +@using Microsoft.AspNetCore.Authentication +@using Microsoft.AspNetCore.Authentication.OpenIdConnect +@model LoginViewModel +@inject SignInManager SignInManager + +@{ + ViewData["Title"] = "Log in"; + Layout = null; +} + + + + @ViewData["Title"] + + + + +
+

@ViewData["Title"].

+ +
+ + +@*
+
+
+
+

Use a local account to log in.

+
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+
+ +
+
+
+
+
+ +
+
+

+ Register as a new user? +

+

+ Forgot your password? +

+
+
+
+
+
+

Use another service to log in.

+
+ @{ + var schemes = await SignInManager.GetExternalAuthenticationSchemesAsync(); + var loginProviders = schemes.Where(scheme => scheme.DisplayName != OpenIdConnectDefaults.AuthenticationScheme).ToList(); + if (loginProviders.Count == 0) + { +
+

+ There are no external authentication services configured. See this article + for details on setting up this ASP.NET application to support logging in via external services. +

+
+ } + else + { +
+
+

+ @foreach (var provider in loginProviders) + { + + } +

+
+
+ } + } +
+
+
*@ diff --git a/samples/IdentityOIDCWebApplicationSample/Controllers/HomeController.cs b/samples/IdentityOIDCWebApplicationSample/Controllers/HomeController.cs index c508c1d629..5615e6f0a0 100644 --- a/samples/IdentityOIDCWebApplicationSample/Controllers/HomeController.cs +++ b/samples/IdentityOIDCWebApplicationSample/Controllers/HomeController.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using IdentityOIDCWebApplicationSample.Models; +using Microsoft.Net.Http.Headers; namespace IdentityOIDCWebApplicationSample.Controllers { @@ -24,9 +25,7 @@ namespace IdentityOIDCWebApplicationSample.Controllers public IActionResult Contact() { - ViewData["Message"] = "Your contact page."; - - return View(); + return Ok(new { Message = $"API Called with token {HttpContext.Request.Headers[HeaderNames.Authorization]}" }); } public IActionResult Error() diff --git a/samples/IdentityOIDCWebApplicationSample/wwwroot/Spa.html b/samples/IdentityOIDCWebApplicationSample/wwwroot/Spa.html new file mode 100644 index 0000000000..29ab466c81 --- /dev/null +++ b/samples/IdentityOIDCWebApplicationSample/wwwroot/Spa.html @@ -0,0 +1,119 @@ + + + Calling a Web API as a user authenticated with Msal.js app + + + + + + + + +

Getting an access token with Azure AD B2C and calling a Web API

+
+
Sign-in with Microsoft Azure AD B2C
+ + +
+ +

+
+    
+
+    
+
+
\ No newline at end of file