You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular集成Duende Identity Server SSO无法跳转至登录页问题

Angular + Duende Identity Server SSO登录问题

初始问题

尝试让Angular应用通过自建的Duende Identity Server实现SSO登录,Postman可正常登录并获取令牌,但Angular应用点击登录按钮时出现invalid_request错误,无法跳转至正确的/Account/Login页面,而是跳转到错误页http://localhost:5000/home/error。使用angular-oauth2-oidc包简化开发,已配置相关代码。

更新情况

将redirectUri从window.location.origin改为window.location.origin + '/api/auth/callback'后,可正常进入登录页并获取令牌,但登录后会跳转到http://localhost:4200/api/auth/callback?iss=identity-svc,而非期望的http://localhost:4200,目前无法调整跳转地址至目标路径。


sso.config.ts

import { AuthConfig } from 'angular-oauth2-oidc';

export const authCodeFlowConfig: AuthConfig = {      
  issuer: 'http://localhost:5000',
  clientId: 'nextApp',
  responseType: 'code',
  redirectUri: window.location.origin,
  // dummyClientSecret: 'secret',
  scope: 'openid profile auctionApp',
  strictDiscoveryDocumentValidation: false, 
  skipIssuerCheck: true,
  showDebugInformation: true,
};

HeaderComponent.ts

export class HeaderComponent implements OnInit{


constructor(private router: Router,private oauthService: OAuthService) 
{ 
  this.configureSingleSignOn(); 
}

configureSingleSignOn()
{
  this.oauthService.configure(authCodeFlowConfig);
  this.oauthService.loadDiscoveryDocumentAndTryLogin();     
} 

login() {
   this.oauthService.initLoginFlow();           
}

HeaderComponent.html

<li class="nav-item">
    <button class="nav-link" (click)="login()">LogIn</button>
 </li>

Asp.Net Core Identity服务Config.cs

public static class Config
{
    public static IEnumerable<IdentityResource> IdentityResources =>
        new IdentityResource[]
        {
        new IdentityResources.OpenId(),
        new IdentityResources.Profile(),
        };

    public static IEnumerable<ApiScope> ApiScopes =>
        new ApiScope[]
        {
            new ApiScope("auctionApp", "Auciton app full access"),
        };

    public static IEnumerable<Client> Clients(IConfiguration config) =>
        new Client[]
        {        
            // interactive client using code flow + pkce
            new Client
            {
                ClientId = "postman",
                ClientName = "postman",
                AllowedScopes = {"openid","profile", "auctionApp"},
                RedirectUris = {"https://www.getpostman.com/oauth2/callback"},
                ClientSecrets = new [] {new Secret("NotASecret".Sha256())},
                AllowedGrantTypes = {GrantType.ResourceOwnerPassword}
            },
            new Client
            {
                ClientId = "nextApp",
                ClientName = "nextApp",
                ClientSecrets = {new Secret("secret".Sha256())},
                AllowedGrantTypes = GrantTypes.CodeAndClientCredentials,
                RequirePkce = false,
                RedirectUris = {config["ClientApp"] + "/api/auth/callback/id-server"},
                AllowOfflineAccess = true,
                AllowedScopes = {"openid", "profile", "auctionApp"},
                AccessTokenLifetime = 3600*24*30,
                AlwaysIncludeUserClaimsInIdToken = true
            }
        };
}

含CORS配置的HostingExtensions.cs

internal static class HostingExtensions
{
    public static WebApplication ConfigureServices(this WebApplicationBuilder builder)
    {
        builder.Services.AddRazorPages();

        builder.Services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); 

        builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        builder.Services
            .AddIdentityServer(options =>
            {
                options.Events.RaiseErrorEvents = true;
                options.Events.RaiseInformationEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseSuccessEvents = true;

                if (builder.Environment.IsEnvironment("Docker"))
                {
                    options.IssuerUri = "identity-svc";
                }

                // see https://docs.duendesoftware.com/identityserver/v6/fundamentals/resources/
                //options.EmitStaticAudienceClaim = true;
            })
            .AddInMemoryIdentityResources(Config.IdentityResources)
            .AddInMemoryApiScopes(Config.ApiScopes)
            .AddInMemoryClients(Config.Clients(builder.Configuration))
            .AddAspNetIdentity<ApplicationUser>()
            .AddProfileService<CustomProfileService>();

        builder.Services.ConfigureApplicationCookie(options =>
        {
            //for using HTTP
            options.Cookie.SameSite = SameSiteMode.Lax;
        });

        builder.Services.AddAuthentication();
            

        return builder.Build();
    }

    public static WebApplication ConfigurePipeline(this WebApplication app)
    {
        app.UseSerilogRequestLogging();

        if (app.Environment.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseCors(builder => builder.AllowAnyHeader()
                                      .AllowAnyMethod()                               
                                      .WithOrigins("http://localhost:4200")); 
        app.UseStaticFiles();
        app.UseRouting();
        app.UseIdentityServer();
        app.UseAuthorization();

        app.MapRazorPages()
            .RequireAuthorization();

        return app;
    }
}

内容的提问来源于stack exchange,提问作者whisk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 19:20:09