angular - 用 Angular 组件替换 IdentityServer4 登录页面
问题描述
我想将 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();
}
解决方案
以最好的方式,是的,您的方法有问题;)
如果遵循 JS 客户端应用程序的当前最佳实践,那么您应该将authorization_code
授权类型与公共客户端一起使用(即没有秘密)。用户身份验证将涉及重定向到authorize
您的实现中的端点identityserver4
(如果不存在会话,则可能会显示登录 UI)。
如果您想在客户端中处理登录 UI,那么这通常会涉及使用ResourceOwnerPassword
强烈建议使用的授权类型。看这里:
identityserver4
但是,如果您愿意,没有什么可以阻止您为您的服务编写一个漂亮的 Angular UI 。只是要小心引入 CSRF 问题。
无论哪种方式,都无需创建任何自定义 API 端点来促进登录过程 -authorize
和token
OIDCuserinfo
端点已经涵盖了。
推荐阅读
- r - 优化 R 中的一个参数时的 optim()
- javascript - 为什么我的函数不等待 API 响应?
- c++ - 移动 ctor 没有被调用
- javascript - 如何将一个对象推到另一个 p5js javascript 前面
- sql - SQLPlus 找不到带有 where 子句的值
- javascript - 控制台记录数据给了我一个空数组(第 12 行),我注意到该值甚至在过滤功能完成之前就记录在控制台中
- python - 使用 QPushbutton 将变量传递到第二个脚本并执行它
- vuejs2 - VueJS2:帮助追踪“TypeError:无法读取未定义的属性'XXX'”
- python - Pytorch ConvNet loss 保持不变,只预测一个类
- r - 限制面板数据以使用 data.table 删除主题