IdentityServer4 无效的 Redirect_Uri 错误

Posted

技术标签:

【中文标题】IdentityServer4 无效的 Redirect_Uri 错误【英文标题】:IdentityServer4 Invalid Redirect_Uri Error 【发布时间】:2021-08-31 17:29:48 【问题描述】:

我创建了 3 个单独的项目,web api 项目、一个 web mvc 项目和一个 asp.net 核心应用程序。我正在将 IdentityServer4 与 asp.net 核心身份一起使用。我有一个项目解决方案id,其中包含TestUsers 的信息。在RedirectUris = "https://localhost:5444/signin-oidc" 线上,我将其重定向到项目WeatherMVC。所有三个文件上的 launchsettings.json 都是正确的,RedirectUris 也是正确的。 是我做错了什么导致我收到此消息吗?

weatherapi project:

----startup.cs:

namespace weatherapi

    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.AddAuthentication("Bearer")
                .AddIdentityServerAuthentication("Bearer", options =>
                
                    options.ApiName = "weatherapi";
                    options.Authority = "https://localhost:5443";
                );

            services.AddControllers();

            services.AddSwaggerGen(c =>
            
                c.SwaggerDoc("v1", new OpenApiInfo  Title = "weatherapi", Version = "v1" );
            );
        

        // 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();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "weatherapi v1"));
            

            app.UseHttpsRedirection();

            app.UseRouting();

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

            app.UseEndpoints(endpoints =>
            
                endpoints.MapControllers();
            );
        
    

----launchsettings.json:


  "$schema": "http://json.schemastore.org/launchsettings.json",
  "iisSettings": 
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": 
      "applicationUrl": "http://localhost:52575",
      "sslPort": 44354
    
  ,
  "profiles": 
    "IIS Express": 
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "swagger",
      "environmentVariables": 
        "ASPNETCORE_ENVIRONMENT": "Development"
      
    ,
    "weatherapi": 
      "commandName": "Project",
      "dotnetRunMessages": "true",
      "launchBrowser": true,
      "hotReloadProfile": "aspnetcore",
      "launchUrl": "swagger",
      "applicationUrl": "https://localhost:5445;http://localhost:5002",
      "environmentVariables": 
        "ASPNETCORE_ENVIRONMENT": "Development"
      
    
  

WeatherMVC Project

----launchsettings.json:


  "iisSettings": 
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": 
      "applicationUrl": "http://localhost:65206",
      "sslPort": 44398
    
  ,
  "profiles": 
    "IIS Express": 
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": 
        "ASPNETCORE_ENVIRONMENT": "Development"
      
    ,
    "WeatherMVC": 
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": 
        "ASPNETCORE_ENVIRONMENT": "Development"
      ,
      "dotnetRunMessages": "true",
      "applicationUrl": "https://localhost:5444;http://localhost:5001"
    
  

这两个项目属于一个解决方案,我执行多个启动项目。

在另一个项目中,名为 id...

id project

----launchsettings.json


  "iisSettings": 
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": 
      "applicationUrl": "http://localhost:19916",
      "sslPort": 44341
    
  ,
  "profiles": 
    "IIS Express": 
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": 
        "ASPNETCORE_ENVIRONMENT": "Development"
      
    ,
    "id": 
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": 
        "ASPNETCORE_ENVIRONMENT": "Development"
      ,
      "hotReloadProfile": "aspnetcore",
      "dotnetRunMessages": "true",
      "applicationUrl": "https://localhost:5443;http://localhost:5000"
    
  

Config.cs下面的这个类中,我有代码执行Redirect_uri

        public static IEnumerable<Client> Clients =>
          new[]
          
        // m2m client credentials flow client
        new Client
        
          ClientId = "m2m.client",
          ClientName = "Client Credentials Client",

          AllowedGrantTypes = GrantTypes.ClientCredentials,
          ClientSecrets = new Secret("SuperSecretPassword".Sha256()),

          AllowedScopes = "weatherapi.read", "weatherapi.write"
        ,

        // interactive client using code flow + pkce
        new Client
        
          ClientId = "interactive",
          ClientSecrets = new Secret("SuperSecretPassword".Sha256()),

          AllowedGrantTypes = GrantTypes.Code,

          RedirectUris = "https://localhost:5444/signin-oidc",
          FrontChannelLogoutUri = "https://localhost:5444/signout-oidc",
          PostLogoutRedirectUris = "https://localhost:5444/signout-callback-oidc",

          AllowOfflineAccess = true,
          AllowedScopes = "openid", "profile", "weatherapi.read",
          RequirePkce = true,
          RequireConsent = true,
          AllowPlainTextPkce = false
        ,
          ;
    

----startup.cs:

public class Startup
    
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        
            services.AddIdentityServer()
                .AddInMemoryClients(Config.Clients)
                .AddInMemoryIdentityResources(Config.IdentityResources)
                .AddInMemoryApiResources(Config.ApiResources)
                .AddInMemoryApiScopes(Config.ApiScopes)
                .AddTestUsers(Config.Users)
                .AddDeveloperSigningCredential();

            services.AddControllersWithViews();
        

        // 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();
            

            app.UseRouting();
            app.UseStaticFiles();
            app.UseIdentityServer();
            app.UseAuthorization();

           app.UseEndpoints(endpoints => endpoints.MapDefaultControllerRoute());

        
    

更新

按照建议在program.cs 中添加调试器后:

public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            
                webBuilder.UseStartup<Startup>();
            )
            .ConfigureLogging(builder =>
            
                builder.SetMinimumLevel(LogLevel.Debug);
                builder.AddFilter("IdentityServer4", LogLevel.Debug);
            );

我终于注意到它正在调用属于名为WeatherMVC 的项目的重定向uri,使用它的sslPort: 44398。请参阅launchsettings.json 了解weathermvc projcect。如果我没有设置它,似乎无法理解为什么它会重定向那个 URI。

【问题讨论】:

IdentityServer 日志包含有关错误的详细信息。像这样在 program.cs 中打开日志记录 Host.CreateDefaultBuilder(args).ConfigureLogging(builder => builder.SetMinimumLevel(LogLevel.Debug); builder.AddFilter("IdentityServer4", LogLevel.Debug); ) 谢谢,帮助我调试。我不明白为什么它会重定向到我没有将其设置为的 uri.... 是导致此错误重定向的原因吗?抱歉,我对此很陌生。 @Rosco 请查看我在Updated下的更新帖子 【参考方案1】:

WeatherApi 是 IdentityServer 的客户端,当它进行身份验证时,它会告诉 IdentityServer 其重定向 uri。 IdentityServer 检查其允许的重定向 uri,如果找到匹配项则进行重定向。

此代码指定一个有效重定向 uri 的列表,而不是重定向 uri。

RedirectUris = "https://localhost:5444/signin-oidc",

您的launchsettings.json 中有 IISExpress 和 Kestrel 设置,我认为您的 WeatherApi 项目只是使用它找到的第一个设置作为重定向 uri。

一些可能的解决方案是:

将 WeatherApi 的其他 uri 添加到允许的 uri,例如

RedirectUris = 
  "https://localhost:5444/signin-oidc", "https://localhost:44398/signin-oidc",

您还可以更改 launchsettings.json 中的 Kestrel,以便 WeatherApi 使用相同的端口

"applicationUrl": "https://localhost:44398;http://localhost:65206"

【讨论】:

我现在明白了,这很有道理!谢谢!要更改WeatherMVC 下的launchsettings.json,我必须将其写为"applicationUrl": "https://localhost:44398","http://localhost:65206",因为"applicationUrl": "https://localhost:44398;http://localhost:65206" 说的URL 无效。 另一方面,当我在 WeatherMVC 项目浏览器上转到该路径 /home/weather 时,它让我登录并请求许可(如同意),这很棒......登录后显示随机温度。关闭应用程序并重新打开它后,我再次转到该路径/home/weather,这一次它没有将我重定向到登录(身份服务器)它只是给了我随机温度。身份服务器正常吗? @罗斯科 @NoviceCoder Identityserver 的令牌有效期为 1 小时(默认),因此您不需要登录 很高兴知道,再次感谢您的帮助!

以上是关于IdentityServer4 无效的 Redirect_Uri 错误的主要内容,如果未能解决你的问题,请参考以下文章

.NET Core 3.1 IdentityServer4:使用资源所有者密码凭据授予时获取无效访问令牌

允许每个用户的单个会话 IdentityServer4

虚拟主机 - *.80 重定向有效,为啥 *.443 无效?

Invalid Token - 观众“空”无效

AuthorizeRequestValidator:错误:无效的客户端授予类型:隐式

use redir to make port redirecting