ASP.Net Core AzureAD authentication works but the SignIn and SignOut don’t

I hope that I’ve got the right corner for my question.
If not i will delete it and post it in the right place.

Well after fighting for hours I’m asking you guys….

I’m playing a little bit around with asp.net core and the AzureAD authentication with a microsoft account.
I’ve created a demo project with VS2019 and followed everything in this example:
(I didn’t change anything on the project except installing Microsoft.Identity.Web and Microsoft.Identity.Web.UI via NuGet; and making those changes in the tutorial).

https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-web-app-sign-user-app-configuration?tabs=aspnetcore

I’ve registered the app on the azure portal
When im running the app everything is working.
I’ve been redirected to microsoft; typed in my credentials and i was logged in.
worked like a charm.

The only thing that i’m facing:
the SignIn and SignOut buttons aren’t working.

When i run the app and looked at the raw html source i’ve noticed that

<a class="nav-link text-dark" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignOut">Sign Out</a>

resulted in:

<li class="nav-item">
            <a class="nav-link text-dark" href="">Sign out</a>
</li>

When i run the project and type: https://localhost:44311/signout-oidc i’m directed to a blank page.
When i hit the return button of the browser I’ve noticed that im logged-out.
So i think it’s generally working but the MicrosoftIdentity isn’t creating the links as expected.

Maybe I’m missing some hint…
Any ideas? Thanks in Advance!

appsettings.json

{
  "AzureAd": {
    // Azure cloud instance among:
    // - "https://login.microsoftonline.com/" for Azure public cloud
    // - "https://login.microsoftonline.us/" for Azure US government
    // - "https://login.microsoftonline.de/" for Azure AD Germany
    // - "https://login.chinacloudapi.cn/" for Azure AD China operated by 21Vianet
    "Instance": "https://login.microsoftonline.com/",

    // Azure AD audience among:
    // - "TenantId" as a GUID obtained from the Azure portal to sign in users in your organization
    // - "organizations" to sign in users in any work or school account
    // - "common" to sign in users with any work or school account or Microsoft personal account
    // - "consumers" to sign in users with a Microsoft personal account only
    "TenantId": "*******************************",

    // Client ID (application ID) obtained from the Azure portal
    "ClientId": "*******************************",
    "CallbackPath": "/signin-oidc",
    "SignedOutCallbackPath": "/signout-oidc"
  },

  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Identity;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;

namespace WebApplication2
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();

            services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAd");

            services.AddRazorPages().AddMvcOptions(options =>
            {
                var policy = new AuthorizationPolicyBuilder()
                              .RequireAuthenticatedUser()
                              .Build();
                options.Filters.Add(new AuthorizeFilter(policy));
            }).AddMicrosoftIdentityUI();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
            });
        }
    }
}

_Layout.cshtml

@using Microsoft.Identity;
@using Microsoft.Identity.Web;
@using Microsoft.Identity.Web.UI;
@using Microsoft.AspNetCore.Authorization;
@using Microsoft.AspNetCore.Mvc.Authorization;
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - WebApplication2</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-page="/Index">WebApplication2</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
                        </li>
                    </ul>
                <partial name="_LoginPartial" />
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2021 - WebApplication2 - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>

    @RenderSection("Scripts", required: false)
</body>
</html>

_LoginPartial.cshtml

<ul class="navbar-nav">
    @if (User.Identity.IsAuthenticated)
    {
        <li class="nav-item">
            <span class="navbar-text text-dark">Hello!</span>
        </li>
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignOut">Sign out</a>
        </li>
    }
    else
    {
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignIn">Sign in</a>
        </li>
    }
</ul>

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Try to enable MVC endpoint route.

ConfigureService:

services.AddControllersWithViews(options =>
{
    var policy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
    options.Filters.Add(new AuthorizeFilter(policy));
}).AddMicrosoftIdentityUI();

Configure:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
    endpoints.MapRazorPages();
});

Method 2

I had the same issue for a new Razor Pages project (.NET5).

Fixed after I add endpoints.MapControllers() to app.UseEndpoints in Startup.cs.

In Configure:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers(); // line to add
    endpoints.MapRazorPages();
});

In ConfigureService:

services.AddRazorPages().AddMvcOptions(options => {
    var policy = new AuthorizationPolicyBuilder()
                    .RequireAuthenticatedUser()
                    .Build();

    options.Filters.Add(new AuthorizeFilter(policy));
}).AddMicrosoftIdentityUI();

Method 3

Since you are using ASP.NET Core Identity with external Azure AD login

  • Setup/Double-check the correct version
    Ensure you setup your CookieSchemeName to Identity.External in services, this tells asp.net core identity to get the external user profile from external identity provider like Azure AD
    services.AddDbContext<ApplicationDbContext>(options =>
         options.UseSqlServer(
             Configuration.GetConnectionString("DefaultConnection")));
     services.AddDefaultIdentity<IdentityUser>()
         .AddEntityFrameworkStores<ApplicationDbContext>();
    
     services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
              .AddAzureAD(options => Configuration.Bind("AzureAd", options));
    
     services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
     {
         //double check your version here
         options.Authority = options.Authority + "/v2.0/";
         options.TokenValidationParameters.ValidateIssuer = false;
    
     });
  • Azure AD application setting :
     "AzureAd": {
         "Instance": "https://login.microsoftonline.com/",
         "Domain": "xxx.onmicrosoft.com",
         "TenantId": "xxxxxx-xxxxx-yyy-b544-TYKT.org.asset",
         "ClientId": "xxxxx-xxxxx-TYKT-xxx-vvyy",
         "CallbackPath": "/signin-oidc",
         "CookieSchemeName": "Identity.External"
     },

Method 4

Do you have a controller like this? – Following this part of the tutorial.

It is the address account/signout that is supposed to handle the sign out for you.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x