В учетных данных отсутствует обязательное поле nonce. Убедитесь, что у вас есть все необходимые параметры для запроса на вход. [Открытый идентификатор Azure]

Я пытаюсь реализовать аутентификацию Azure AD в проекте .NET 4.8, разработанном на платформе NopCommerce 3.8.

Но я получаю эту ошибку, когда происходит обратный вызов:

OpenIdConnectMessage.Error не было нулевым, что указывает на ошибку.
Ошибка: «недействительный_запрос». Error_Description (может быть пустым): «AADSTS90014: в учетных данных отсутствует обязательное поле «nonce». Убедитесь, что у вас есть все необходимые параметры для запроса на вход.
Идентификатор трассировки: ef6427f0b00
Идентификатор корреляции: 0311700e-cadc-506e764
Временная метка: 2024-08-29 03:51:08Z'.
Error_Uri (может быть пустым): «https://login.microsoftonline.com/error?code=90014»

Это моя конфигурация Azure:

И это мой код:

using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Owin;
using Microsoft.Owin.Host.SystemWeb;
using Microsoft.Owin.Logging;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;
using System;
using System.Configuration;
using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using System.Web.Helpers;

[assembly: OwinStartup(typeof(Nop.Web.OwinStartup))]

namespace Nop.Web
{
    public class OwinStartup
    {
        public void Configuration(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            //app.UseCookieAuthentication(new CookieAuthenticationOptions());
            app.UseCookieAuthentication(new CookieAuthenticationOptions()
            {
                CookieSameSite = Microsoft.Owin.SameSiteMode.None,
                CookieSecure = CookieSecureOption.Always,
                CookieHttpOnly = true,
                CookieManager =new Microsoft.Owin.Host.SystemWeb.SystemWebCookieManager()
            });

            AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;

            var openIdOptions = new OpenIdConnectAuthenticationOptions
            {
                ClientId = ConfigurationManager.AppSettings["ClientId"],
                Authority = ConfigurationManager.AppSettings["Authority"],
                PostLogoutRedirectUri = ConfigurationManager.AppSettings["RedirectUri"],
                RedirectUri = ConfigurationManager.AppSettings["RedirectUri"],
                Scope = "openid email profile offline_access",
                ClientSecret = ConfigurationManager.AppSettings["ClientSecret"],
                ResponseType = OpenIdConnectResponseType.IdToken,
                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = false,
                },
                ProtocolValidator = new OpenIdConnectProtocolValidator
                {
                    RequireNonce = false
                },
                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    AuthorizationCodeReceived = async (context) =>
                    {
                        var claim = ClaimsPrincipal.Current;
                        var code = context.Code;

                        string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;

                    },
                    AuthenticationFailed = (context) =>
                    {
                        context.HandleResponse();
                        context.Response.Redirect("/Error?message = " + context.Exception.Message);
                        return Task.FromResult(0);
                    }
                }
            };

            app.UseOpenIdConnectAuthentication(openIdOptions);
        }
    }
}

Контроллер входа

public partial class CustomerController : BasePublicController
        {
    
    
     [NopHttpsRequirement(SslRequirement.Yes)]
     //available even when a store is closed
     [StoreClosed(true)]
     //available even when navigation is not allowed
     [PublicStoreAllowNavigation(true)]
     public ActionResult Login(bool? checkoutAsGuest)
     {
    
         if (!Request.IsAuthenticated)
         { 
             var redirectUri = ConfigurationManager.AppSettings["RedirectUri"];
             HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties
             {
                 //RedirectUri = Url.Action("ExternalLoginCallback", "Account")
                  RedirectUri = redirectUri
             }, OpenIdConnectAuthenticationDefaults.AuthenticationType);
         }
         //return View();
    
         var model = new LoginModel();
         model.UsernamesEnabled = _customerSettings.UsernamesEnabled;
         model.CheckoutAsGuest = checkoutAsGuest.GetValueOrDefault();
         model.DisplayCaptcha = _captchaSettings.Enabled && _captchaSettings.ShowOnLoginPage;
         return View(model);
     }      
    
    
     [AllowAnonymous]
     [Route("signin-oidc")]
     public ActionResult ExternalLoginCallback()
     {
         // This will return the result of the authentication
         var authResult = HttpContext.GetOwinContext().Authentication.AuthenticateAsync("ExternalCookie").Result;
    
         if (authResult != null)
         {
             // Extract the claims from the external login
             var claimsIdentity = authResult.Identity;
    
             // Optionally, you can extract specific claims like name, email, etc.
             var userName = claimsIdentity.FindFirst(ClaimTypes.Name)?.Value;
             var email = claimsIdentity.FindFirst(ClaimTypes.Email)?.Value;
    
             // Sign the user in with a new identity based on the claims from the external login
             var identity = new ClaimsIdentity(claimsIdentity.Claims, "ApplicationCookie");
             HttpContext.GetOwinContext().Authentication.SignIn(new AuthenticationProperties { IsPersistent = true }, identity);
    
             // Redirect to the home page or wherever you want the user to go after a successful login
             return RedirectToAction("Index", "Home");
         }
    
         // If we got here, something went wrong with the authentication process
         return RedirectToAction("Login", "Account");
     }
    
    }

Веб-конфигурация

  <add key = "owin:AutomaticAppStartup" value = "true" />
  <add key = "ClientId" value = "a403fdgdfg-gdfgdfg-897e-c3d" />
  <add key = "Authority" value = "https://login.microsoftonline.com/33dffdf8-dere-4079-afa8-7567hghf8f5fba/v2.0" /> 
  <add key = "RedirectUri" value = "https://localhost:44396/signin-oidc" />
  <add key = "PostLogoutRedirectUri" value = "https://localhost:44396/" />
  <add key = "ClientSecret" value = "PaR8Q~IU1-K3TnyBshBYNyXRqjzOmlwGT6CAtca3" />

60
1

Ответ:

Решено

Это рабочий код.

public class OwinStartup
 {
     public void Configuration(IAppBuilder app)
     {

         app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
         app.UseKentorOwinCookieSaver();

         app.UseCookieAuthentication(new CookieAuthenticationOptions()
         {
             CookieSameSite = Microsoft.Owin.SameSiteMode.None,
             CookieSecure = CookieSecureOption.Always,
             CookieHttpOnly = true,
             CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebCookieManager()
         });

         AntiForgeryConfig.UniqueClaimTypeIdentifier = "preferred_username"; //ClaimTypes.NameIdentifier;
         app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
         {
             ClientId = ConfigurationManager.AppSettings["ClientId"],
             Authority = ConfigurationManager.AppSettings["Authority"],
             RedirectUri = ConfigurationManager.AppSettings["RedirectUri"],
             ResponseType = OpenIdConnectResponseType.IdToken,//Code,//IdToken,
             PostLogoutRedirectUri = ConfigurationManager.AppSettings["RedirectUri"],
             Scope = "openid email profile offline_access",
             TokenValidationParameters = new TokenValidationParameters
             {
                 ValidateIssuer = true
             },
             Notifications = new OpenIdConnectAuthenticationNotifications
             {
                 AuthenticationFailed = context =>
                 {
                     context.HandleResponse();
                     context.Response.Redirect("/Home/Error?message = " + context.Exception.Message);
                     return Task.FromResult(0);
                 }
             }
         });    
     }
 }