用 Angular 组件替换 IdentityServer4 登录页面

daw*_*zaw 4 asp.net-core identityserver4 angular

我想将 IdentityServer4(代码 + PKCE 流程)与 .Net Core 和 Angular 一起使用。

我不想使用快速启动 UI,而是想在 Angular 端进行登录过程。在官方教程中,用户转到 Angular 应用程序,重定向到 IdentityServer4 UI,在那里登录,然后有另一个重定向 - 返回 Angular 应用程序。我还想提一下,我没有使用 .net 身份和实体框架,因为数据库流依赖于存储过程。

在我的设置中,Identiy Server 在端口 5555 上运行,Angular App 在端口 4200 上运行。为了与服务器通信,我使用 oidc-client-js。

我创建了一个从 Angular 调用的示例端点(登录)。不幸的是,IdSr 没有将我重定向到 AuthCallbackComponent。我只是得到一个空响应(如预期),但没有发生更多事情。据我了解,在模拟登录用户后,我只需要引发 UserLoginSuccessEvent 。之后 IdSr 应生成令牌并进行重定向。我错过了什么吗?我的做法有什么问题吗?

export class AuthService {
  private userManager: UserManager;
  private user: User;

  constructor(private client: HttpClient) {
    this.userManager = new UserManager(AuthSettings.settings);
    this.userManager.getUser().then(user => (this.user = user));
  }

  login() {
    let api = "http://localhost:5555/api/User";
    let headers = new HttpHeaders();
    headers.set("Content-Type", "application/json");
    let content = {
      UserName: "test@test.com",
      Id: "123456",
      Name: "Test User"
    };
    let data = `"${content}"`;
    console.log("logging");
    this.client
      .post(api, content, {
        headers: headers,
        withCredentials: false
      })
      .subscribe(response => console.log(response), err => console.log(err));
  }

  async completeAuthentication() {
    this.user = await this.userManager.signinRedirectCallback();
  }
}



import { UserManagerSettings } from "oidc-client";

export class AuthSettings {
  public static settings: UserManagerSettings = {
    authority: "http://localhost:5555/",
    client_id: "ng",
    redirect_uri: "http://localhost:4200/callback",
    post_logout_redirect_uri: "http://localhost:4200/",
    response_type: "code",
    scope: "openid profile email API"
  };
}


export class AuthCallbackComponent implements OnInit {
  constructor(private authService: AuthService) {}

  ngOnInit() {
    this.authService
      .completeAuthentication()
      .then(e => console.log("auth completed"));
  }
}


public static IEnumerable < Client > GetClients() {
    return new List < Client > {
        new Client {
            ClientId = "ng",
            ClientName = "Angular",
            AllowedScopes = {
                "openid",
                "profile",
                "email",
                "API"
            },
            RedirectUris = new List < string > {
                "http://localhost:4200/callback"
            },
            PostLogoutRedirectUris = new List < string > {
                "http://localhost:4200/"
            },
            AllowedCorsOrigins = new List < string > {
                "http://localhost:4200"
            },
            AllowedGrantTypes = GrantTypes.Code,
            RequirePkce = true,
            RequireClientSecret = false,
            AllowAccessTokensViaBrowser = true,
            RequireConsent = false
        }
    };
}


[AllowAnonymous][HttpPost]
public async Task < ActionResult > Login(LoginInputModel model) {
    var user = new User("test@test.com", "123456", "Test User");
    await _eventService.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, user.Name));
    return Ok();
}

Run Code Online (Sandbox Code Playgroud)

mac*_*kie 5

以最好的方式,是的,你的方法有问题;)

如果遵循 JS 客户端应用程序的当前最佳实践,那么您应该authorization_code对公共客户端使用授权类型(即无秘密)。authorize用户身份验证将涉及到实现中端点的重定向identityserver4(如果不存在会话,则可能会显示登录 UI)。

如果您想在客户端中处理登录 UI,那么这通常会涉及使用ResourceOwnerPassword强烈建议不要使用的授权类型。看这里:

https://www.scottbrady91.com/OAuth/Why-the-Resource-Owner-Password-Credentials-Grant-Type-is-not-Authentication-nor-Suitable-for-Modern-Applications

identityserver4然而,如果您愿意的话,没有什么可以阻止您为您的服务编写一个漂亮的、新颖的 Angular UI 。只是要小心引入 CSRF 问题。

无论哪种方式,都无需创建任何自定义 API 端点来促进登录过程 -authorize和OIDC 端点已满足您tokenuserinfo需求。