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

Angular结合ASP.NET OWIN与Azure AD认证后,回调Angular时无法获取id_token及用户信息的问题求助

Angular结合ASP.NET OWIN与Azure AD认证后,回调Angular时无法获取id_token及用户信息的问题求助

大家好,我最近碰到了一个挺棘手的认证集成问题,想请教下各位大佬。我的需求是给基于ASP.NET OWIN(.NET Framework 4.7.2)的认证服务器添加Azure Active Directory(AAD)认证功能,配合Angular前端完成完整的登录流程。

整体的流程大概是这样:

  • Angular应用里用户点击“其他登录”按钮,触发认证流程
  • 用户被重定向到ASP.NET OWIN的登录页面,这里会引导用户去AAD完成认证
  • AAD认证成功后,用户会被重定向回Angular应用,同时带上必要的token和用户信息

Angular这边我用的是oidc-client库,下面是我的代码细节:

Angular 代码部分

AuthService

import { User, UserManager, UserManagerSettings, Log, WebStorageStateStore} from 'oidc-client'

constructor(private http: HttpClient) {

const settings: UserManagerSettings = {
  authority: 'https://localhost:44302',
  client_id:'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx',
  redirect_uri:'http://localhost:4200/#/loggedin',
  response_type:'id_token',
  scope:'openid profile',
  post_logout_redirect_uri:'',
  loadUserInfo: true,
  response_mode: 'query',
  userStore: new WebStorageStateStore({ store: window.localStorage }),
  metadata:{
    issuer: 'https://localhost:44302/',
    authorization_endpoint: 'https://localhost:44302/login'
  }
};

this.userManager = new UserManager(settings);
}

login(): Promise<any>{
  return this.userManager.signinRedirect();
}

completeLogin(): any{
  return this.userManager.signinRedirectCallback();
}

这里我手动配置了metadata,因为之前一直找不到.well-known配置文档。

路由配置(app.routing.module.ts)

{path:'loggedin',component:AuthUserComponent },

回调组件(auth.user.component.ts)

ngOnInit(): void {
  this.authService.completeLogin().then(function (loginCompleted) {
    console.log(loginCompleted);
  });
}

用户完成认证后会被重定向到这个组件,在这里处理回调。


ASP.NET OWIN 代码部分

Startup.cs

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
  AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
  LoginPath = new PathString("/login")
});

app.UseOpenIdConnectAuthentication(
  new OpenIdConnectAuthenticationOptions
  {
    ClientId = clientId,
    Authority = authority,
    PostLogoutRedirectUri = postLogoutRedirectUri,
    RedirectUri = redirectUri,
    Scope = "openid profile email",
    ResponseType = "id_token",
    SaveTokens = true,
    SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
    TokenValidationParameters = new TokenValidationParameters()
    {
      ValidateIssuer = false
    },
    Notifications = new OpenIdConnectAuthenticationNotifications
    {
      RedirectToIdentityProvider = (context) =>
      {
        context.ProtocolMessage.Prompt = "login";
        return Task.FromResult(0);
      },
      AuthenticationFailed = (context) =>
      {
        context.HandleResponse();
        context.OwinContext.Response.Redirect("/login");
        return Task.CompletedTask;
      },
      SecurityTokenReceived = (context) =>
      {
        return Task.FromResult(0);
      },
      SecurityTokenValidated = (context) =>
      {
        string idToken = context.ProtocolMessage.IdToken;
        Debug.WriteLine(idToken); // 这里能正常拿到id token
        context.AuthenticationTicket.Identity.AddClaim(new Claim("id_token", idToken));
        return Task.FromResult(0);
      }
    }
  });

RouteConfig.cs

public static void RegisterRoutes(RouteCollection routes)
{
  routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

  routes.MapRoute(
    name: "Auth",
    url: "login",
    defaults: new { controller = "Account", action = "SignIn" }
  );

  routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
  );
}

AccountController.cs

private string redirectUrl;
private string state;

public ActionResult SignIn()
{
  redirectUrl = HttpContext.Request.QueryString["redirect_uri"]; // Angular的回调地址
  state = HttpContext.Request.QueryString["state"];
  redirectUrl = redirectUrl + "?state=" + state;

  return View();
}

[HttpPost, Route("Account/TrySignIn")]
public void TrySignIn()
{
  if (!Request.IsAuthenticated)
  {
    HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = redirectUrl },
    OpenIdConnectAuthenticationDefaults.AuthenticationType);
  }
}

目前已完成的步骤

  • 成功从Angular重定向到ASP.NET OWIN的认证页面
  • 顺利完成AAD的登录认证
  • 认证成功后能重定向回Angular应用

遇到的错误

但是重定向回Angular后,我碰到了这些问题:

  • 报错:Error: No id_token in response
  • 控制台输出:UserManager.getUser: user not found in storage
  • 偶尔还会出现:No state found

我的需求

现在我希望能在Angular应用里获取到用户信息或者id_token,最好两者都能拿到,麻烦各位帮忙看看问题出在哪,谢谢大家了!


备注:内容来源于stack exchange,提问作者Ajit Darnal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 10:39:49