ASPNET Core SignalR 을 이용한 Push Server 구현 - 2 (인증처리)
2023. 7. 3. 00:00ㆍASPNET/SignalR
반응형
SignalR 관련해서도 인증처리가 가능 하다.
일반적으로 인증서버를 만들고 해당 서버로 부터 인증처리 하도록 한다.
https://yogingang.tistory.com/412
Rest API Template 만들기 - EP 08 (DB 를 통해 AccessToken 및 RefreshToken 관리)
이제 인증관련 하여 수정을 해야할 때이다. 기존에는 JWT 를 통해 AccessToken 을 사용하여 validation 처리를 aspnet core 내부적으로 하게 하였다. 이렇게 만든 JWT 는 일반적인 validation 처리를 하기 때문
yogingang.tistory.com
위 Rest API Template 의 인증을 이용하여 인증 서버를 활용하겠다.
이제 이 인증서버를 이용하여 SignalR 관련 인증을 처리해보자
ChannelHubAuthorizationHandler.cs
using Microsoft.AspNetCore.Authorization;
namespace SignalRTemplate.Authorization;
public class ChannelHubAuthorizationRequirement : IAuthorizationRequirement
{
}
public class ChannelHubAuthorizationHandler : AuthorizationHandler<ChannelHubAuthorizationRequirement>
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IConfiguration _configuration;
private readonly ILogger _logger;
public ChannelHubAuthorizationHandler(IHttpContextAccessor httpContextAccessor, IConfiguration configuration, ILogger logger)
{
_httpContextAccessor = httpContextAccessor;
_configuration = configuration;
_logger = logger;
}
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, ChannelHubAuthorizationRequirement requirement)
{
string jwtToken = string.Empty;
var token = request?.Headers["Authorization"];
AuthenticationHeaderValue.TryParse(token, out var tokenValue);
jwtToken = tokenValue?.Parameter ?? "";
jwtToken = jwtToken =="" ? request?.Query["access_token"].FirstOrDefault() ?? string.Empty : jwtToken;
if (await ValidateTokenAsync(jwtToken))
{
_logger.LogDebug("Signalr authorization succeed");
context.Succeed(requirement);
}
else
{
_logger.LogDebug("Signalr authorization failed");
context.Fail();
}
}
private async ValueTask<bool> ValidateTokenAsync(string token)
{
try
{
var url = _configuration.GetSection("HostService").GetValue<string>("Identity");
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", $"bearer {token}");
var response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
return true;
}
return false;
}
catch (Exception e)
{
_logger.LogInformation(e.Message);
return false;
}
}
}
appsettings.json
...
"HostService": {
"Identity": "https://localhost:7207/user/authentication"
},
...
Program.cs
...
builder.Services.AddScoped<IAuthorizationHandler, ChannelHubAuthorizationHandler>();
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("ChannelHubAuthorizationPolicy", policy =>
{
policy.Requirements.Add(new ChannelHubAuthorizationRequirement());
});
});
...
ChannelHub.cs
[Authorize("ChannelHubAuthorizationPolicy")]
public class ChannelHub : Hub
{
...
이제 client 에서 작업을 해보자
SignalRClient
인증 서버로 부터 token 받아오기
var identityUrl = $"https://localhost:7207/user/login";
HttpClient client = new HttpClient();
var request = new
{
Id = "Test0001",
Password = "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4",
};
var contents = new StringContent(request.SerializeToJson(), System.Text.Encoding.UTF8, "application/json");
var response =await client.PostAsync(identityUrl, contents);
string token = string.Empty;
if (response.IsSuccessStatusCode)
{
var loginResponse = await response.Content.ReadAsAsync<Login.Response>();
token = loginResponse?.AccessToken ?? "";
}
받은 token 을 이용하여 HubConnection 생성
// signalR 접속 url
var url = $"https://localhost:5004/channel";
var connection = new HubConnectionBuilder()
.WithUrl(url, options =>
{
options.SkipNegotiation = true;
options.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.WebSockets;
options.Headers.Add("Authorization", $"bearer {token}");
})
.WithAutomaticReconnect()
.Build();
SignalR server 로 접속
// connection1 생성
var connection1 = await InitSignalRClient();
// server 접속
await connection1.StartAsync();
...
정상적으로 통신이 되는지 확인하자
이번에는 Headers token 을 빼고 인증해 보자
// signalR 접속 url
var url = $"https://localhost:5004/channel";
var connection = new HubConnectionBuilder()
.WithUrl(url, options =>
{
options.SkipNegotiation = true;
options.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.WebSockets;
//options.Headers.Add("Authorization", $"bearer {token}");
})
.WithAutomaticReconnect()
.Build();
인증 처리 없이 method 호출 처리시 401, 403 또는 접속 실패가 발생한다. (500 error 가 발생하기도 한다)
관련영상
반응형
'ASPNET > SignalR' 카테고리의 다른 글
ASPNET Core SignalR 을 이용한 Push Server 구현 - 1 (0) | 2023.06.26 |
---|