我的问题很简单。我在 .NET Core 中使用 Windows 身份验证。在应用程序的前端部分(Angular)我有一个 HTTP 拦截器,它设置 widhcredentails:true 所有 HTTP 请求。
此拦截器不能与 WebSocket 配合使用,因此我需要一个解决方案来将相同的代码从 Interceptor 添加到 SignalR 服务。
这是我的拦截器代码:
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>>
{
request = request.clone({ withCredentials: true });
return next.handle(request);
}
这是我的 SignalR 服务:
this.requestConnection = new HubConnectionBuilder().
withUrl(`${environment.apiUrl}/request`).
withAutomaticReconnect([0, 2000, 30000, 60000, null]).
build();
this.requestConnection.
start().
then(() => console.log('Connection started')).
catch(err => console.log(`Error while starting connection: ${err}`));
请记住,拦截器已添加到 app.module 组件的提供者数组中:
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: WinAuthInterceptor,
multi: true
}
],
SignalR 服务被注入(inject)到根目录中。
@Injectable({
providedIn: 'root'
})
最佳答案
终于,我意识到问题出在哪里了。由于我使用的是 Windows 身份验证,因此无需添加任何类型的 JWT 授权。另外,我上面发布的拦截器代码没有什么区别,哈哈。这意味着您在拦截器或 SignalR 中都不需要 withCredetials: true 。
无论如何,(如果您使用的是 IIS,您需要按照此 documentation 配置它,在本地它将完美工作,但如果您在 IIS 上托管/部署您的应用程序,您需要事先执行此操作,否则您的Context 将为 NULL),您需要在 launchSettings.json 中将 anonymousAuthentication 属性设置为 false(.NET Core 作为后端)
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:64152",
"sslPort": 44385
}
长话短说,Angular 代码如下所示:
this.requestConnection = new HubConnectionBuilder().
withUrl(`${environment.apiUrl}/request`).
withAutomaticReconnect([0, 2000, 30000, 60000, null]).
build();
this.requestConnection.
start().
then(() => console.log('Connection started')).
catch(err => console.log(`Error while starting connection: ${err}`));
在 .NET Core 中,我刚刚重写 OnConnectAsync() 类来获取连接并执行一些逻辑:
public override Task OnConnectedAsync()
{
var user = Context.User.Identity.Name.ToUpper();
//remove domain name
user = user[user.IndexOf("\\")..];
//remove speacial chars, excluding .
user = UserProvider.RemoveSpecialCharacters(user);
var conId = Context.ConnectionId;
if (UserProvider.UserConnections.Any(key => key.Key == user))
{
UserProvider.UserConnections[user] = conId;
}
else
{
UserProvider.UserConnections.Add(user, conId);
}
return base.OnConnectedAsync();
}
关于Angular SignalR 和 Windows 身份验证 (NTLM),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71057367/