我正在尝试使用 Identity Server 6 在 .NET 6 中的 MVC 项目中进行身份验证和授权。我还使用 Identity Server 来限制对与我的 MVC 项目通信的 API 的访问。 当我启动我的解决方案时,我启动了解决方案下的所有 3 个项目 - 带有 swagger UI 的 Web MVC 项目、产品 API 和身份服务器 API 项目。当我尝试登录我的 MVC api 项目时,在后台运行的控制台中,出现以下错误 -
Duende.IdentityServer.Events.DefaultEventService[0]
{
"ClientId": "mango",
"Endpoint": "Authorize",
"Scopes": "",
"Error": "invalid_request",
"ErrorDescription": "Invalid redirect_uri",
"Category": "Token",
"Name": "Token Issued Failure",
"EventType": "Failure",
"Id": 2001,
"ActivityId": "0HMH1EO8KTSBE:00000003",
"TimeStamp": "2022-04-18T20:00:33Z",
"ProcessId": 41032,
"LocalIpAddress": "::1:7270",
"RemoteIpAddress": "::1"
}
这是我的 MVC 项目的 HomeController 代码 -
using Mango.Web.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
namespace Mango.Web.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
[Authorize]
public async Task<IActionResult> Login()
{
return RedirectToAction(nameof(Index));
}
public IActionResult Logout()
{
return SignOut("Cookies", "oidc");
}
}
}
下面是我的 MVC 项目的 Program.cs 代码 -
using Mango.Web;
using Mango.Web.Services;
using Mango.Web.Services.IServices;
using Microsoft.AspNetCore.Authentication;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddHttpClient<IProductService, ProductService>();
Constants.ProductAPIBase = builder.Configuration["ServiceUrls:ProductAPI"];
builder.Services.AddScoped<IProductService, ProductService>();
//setup main proj to use Identityserver , openID connect
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies", c => c.ExpireTimeSpan = TimeSpan.FromMinutes(10))
.AddOpenIdConnect("oidc", options =>
{
options.Authority = builder.Configuration["ServiceUrls:IdentityAPI"];
options.GetClaimsFromUserInfoEndpoint = true;
options.ClientId = "mango";
options.ClientSecret = "secret";
options.ResponseType = "code";
options.ClaimActions.MapJsonKey("role", "role", "role");
options.ClaimActions.MapJsonKey("sub", "sub", "sub");
options.TokenValidationParameters.NameClaimType = "name";
options.TokenValidationParameters.RoleClaimType = "role";
options.Scope.Add("mango");
options.SaveTokens = true;
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/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.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
MVC 项目的 appsettings.json 文件 -
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ServiceUrls": {
"ProductAPI": "https://localhost:7174",
"IdentityAPI": "https://localhost:7270"
}
}
我的 Identity API 项目中的静态类 SD.vc -
namespace Mango.Services.Identity
{
using Duende.IdentityServer;
using Duende.IdentityServer.Models;
public static class SD
{
public const string Admin = "Admin";
public const string Customer = "Customer";
public static IEnumerable<IdentityResource> IdentityResources =>
new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Email(),
new IdentityResources.Profile()
};
public static IEnumerable<ApiScope> ApiScopes =>
new List<ApiScope> {
new ApiScope("mango", "Mango Server"),
new ApiScope(name: "read", displayName: "Read your data."),
new ApiScope(name: "write", displayName: "Write your data."),
new ApiScope(name: "delete", displayName: "Delete your data.")
};
public static IEnumerable<Client> Clients =>
new List<Client>
{
new Client
{
ClientId="client",
ClientSecrets= { new Secret("secret".Sha256())},
AllowedGrantTypes = GrantTypes.ClientCredentials,
AllowedScopes={ "read", "write","profile"}
},
//creating custom client for our mango app
new Client
{
ClientId="mango",
ClientSecrets= { new Secret("secret".Sha256())},
AllowedGrantTypes = GrantTypes.Code,
// for openid connect , we add signin-oidc
//44360 , 7182
RedirectUris={ "https://localhost:44360/signin-oidc", "https://localhost:7182/signin-oidc" },
//url to redirect after logout - main app
PostLogoutRedirectUris={"https://localhost:44360/signout-callback-oidc" },
AllowedScopes=new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
"mango"
}
},
};
}
}
Identity API 项目的 Program.cs 文件 -
using Mango.Services.Identity;
using Mango.Services.Identity.DbContext;
using Mango.Services.Identity.Initializer;
using Mango.Services.Identity.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
// configure identityserver to use our App user class
builder.Services.AddIdentity<ApplicationUser,IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();
//adding identityserver
builder.Services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
options.EmitStaticAudienceClaim = true;
})
//using our resources and apiscopes
.AddInMemoryIdentityResources(SD.IdentityResources)
.AddInMemoryApiScopes(SD.ApiScopes)
.AddInMemoryClients(SD.Clients)
.AddAspNetIdentity<ApplicationUser>();
builder.Services.AddScoped<IDbInitializer, DbInitializer>();
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/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();
//adding identity server to the pipeline
app.UseIdentityServer();
using (var scope = app.Services.CreateScope())
{
scope.ServiceProvider.GetRequiredService<IDbInitializer>().Initialize();
}
//app.Services.GetService<IDbInitializer>().Initialize();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
身份 API 的 appsettings.json -----
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Server=Local;Database=MangoIdentityServer;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
我不确定到底是什么导致了这个问题。我已验证我的 IdentityServer 正在 https://localhost:7270/上运行。
最佳答案
您需要将mvc项目的url添加到身份服务器中客户端的redirect_uri列表中。
假设您的 mvc 项目网址是“https://localhost:9999”,请将此地址添加到redirect_uri列表中。
例如,在您的身份 API 中,您有一个客户端芒果;
new Client
{
ClientId="mango",
ClientSecrets= { new Secret("secret".Sha256())},
AllowedGrantTypes = GrantTypes.Code,
// for openid connect , we add signin-oidc
//44360 , 7182
RedirectUris={ "https://localhost:44360/signin-oidc", "https://localhost:7182/signin-oidc" },
//url to redirect after logout - main app
PostLogoutRedirectUris={"https://localhost:44360/signout-callback-oidc" },
AllowedScopes=new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
"mango"
}
},
更改此行
RedirectUris={ "https://localhost:44360/signin-oidc", "https://localhost:7182/signin-oidc" },
至
RedirectUris={ "https://localhost:999/signin-oidc", "https://localhost:44360/signin-oidc", "https://localhost:7182/signin-oidc" },
在redirect_uri列表中添加了MVC项目URL。
您的MVC项目正在将redirect_uri的默认值发送到身份服务器。
关于c# - Duende 身份服务器 6 中的 redirect_uri 无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71983816/