diff --git a/samples/LiveStreamingServerNet.HlsAuthenticationDemo/Dockerfile b/samples/LiveStreamingServerNet.HlsAuthenticationDemo/Dockerfile new file mode 100644 index 00000000..675da5dd --- /dev/null +++ b/samples/LiveStreamingServerNet.HlsAuthenticationDemo/Dockerfile @@ -0,0 +1,29 @@ +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base +USER app +WORKDIR /app +EXPOSE 8080 +EXPOSE 8081 +EXPOSE 1935 + +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["samples/LiveStreamingServerNet.HlsAuthenticationDemo/LiveStreamingServerNet.HlsAuthenticationDemo.csproj", "samples/LiveStreamingServerNet.HlsAuthenticationDemo/"] +COPY ["src/LiveStreamingServerNet.StreamProcessor/LiveStreamingServerNet.StreamProcessor.csproj", "src/LiveStreamingServerNet.StreamProcessor/"] +COPY ["src/LiveStreamingServerNet.Rtmp/LiveStreamingServerNet.Rtmp.csproj", "src/LiveStreamingServerNet.Rtmp/"] +COPY ["src/LiveStreamingServerNet.Networking/LiveStreamingServerNet.Networking.csproj", "src/LiveStreamingServerNet.Networking/"] +COPY ["src/LiveStreamingServerNet.Utilities/LiveStreamingServerNet.Utilities.csproj", "src/LiveStreamingServerNet.Utilities/"] +COPY ["src/LiveStreamingServerNet/LiveStreamingServerNet.csproj", "src/LiveStreamingServerNet/"] +RUN dotnet restore "./samples/LiveStreamingServerNet.HlsAuthenticationDemo/LiveStreamingServerNet.HlsAuthenticationDemo.csproj" +COPY . . +WORKDIR "/src/samples/LiveStreamingServerNet.HlsAuthenticationDemo" +RUN dotnet build "./LiveStreamingServerNet.HlsAuthenticationDemo.csproj" -c $BUILD_CONFIGURATION -o /app/build + +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "./LiveStreamingServerNet.HlsAuthenticationDemo.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "LiveStreamingServerNet.HlsAuthenticationDemo.dll"] \ No newline at end of file diff --git a/samples/LiveStreamingServerNet.HlsAuthenticationDemo/LiveStreamingServerNet.HlsAuthenticationDemo.csproj b/samples/LiveStreamingServerNet.HlsAuthenticationDemo/LiveStreamingServerNet.HlsAuthenticationDemo.csproj new file mode 100644 index 00000000..49b2c831 --- /dev/null +++ b/samples/LiveStreamingServerNet.HlsAuthenticationDemo/LiveStreamingServerNet.HlsAuthenticationDemo.csproj @@ -0,0 +1,27 @@ + + + + net8.0 + enable + enable + true + false + false + Linux + ..\.. + -p 1935:1935 -p 8080:8080 + + + + + + + + + + + + + + + diff --git a/samples/LiveStreamingServerNet.HlsAuthenticationDemo/Program.cs b/samples/LiveStreamingServerNet.HlsAuthenticationDemo/Program.cs new file mode 100644 index 00000000..8e5e994e --- /dev/null +++ b/samples/LiveStreamingServerNet.HlsAuthenticationDemo/Program.cs @@ -0,0 +1,94 @@ +using LiveStreamingServerNet.Networking.Helpers; +using LiveStreamingServerNet.Rtmp; +using LiveStreamingServerNet.StreamProcessor.AspNetCore.Configurations; +using LiveStreamingServerNet.StreamProcessor.AspNetCore.Installer; +using LiveStreamingServerNet.StreamProcessor.Installer; +using Microsoft.IdentityModel.Tokens; +using System.Net; +using System.Text; + +namespace LiveStreamingServerNet.HlsAuthenticationDemo +{ + public class Program + { + public static async Task Main(string[] args) + { + using var liveStreamingServer = CreateLiveStreamingServer(); + + var builder = WebApplication.CreateBuilder(args); + + builder.Services.AddBackgroundServer(liveStreamingServer, new IPEndPoint(IPAddress.Any, 1935)); + + builder.Services.AddCors(options => + options.AddDefaultPolicy(policy => + policy.AllowAnyHeader() + .AllowAnyOrigin() + .AllowAnyMethod() + ) + ); + + // + builder.Services.AddAuthentication() + .AddJwtBearer(options => + { + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuer = false, + ValidateAudience = false, + ValidateLifetime = false, + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes( + "THIS_IS_A_SUPER_SECRET_KEY_FOR_DEMO_PURPOSE_ONLY")), + }; + } + ); + + builder.Services.AddAuthorization(); + + var app = builder.Build(); + + app.UseAuthorization(); + + app.UseAuthentication(); + + app.UseCors(); + + // Given that the scheme is https, the port is 7138, and the stream path is live/demo, + // the HLS stream will be available at https://localhost:7138/hls/live/demo/output.m3u8 + app.UseHlsFiles(liveStreamingServer, new HlsServingOptions + { + RequestPath = "/hls", + + // Use bearer token authentication for HLS files + OnProcessRequestAsync = async (context) => + { + if (context.Context.User.Identity?.IsAuthenticated != true) + { + context.Context.Response.StatusCode = StatusCodes.Status401Unauthorized; + await context.Context.Response.CompleteAsync(); + + context.Context.RequestServices + .GetRequiredService>() + .LogWarning($"Unauthorized request for {context.StreamPath} from {context.Context.Connection.RemoteIpAddress}"); + } + } + }); + + await app.RunAsync(); + } + + private static ILiveStreamingServer CreateLiveStreamingServer() + { + return LiveStreamingServerBuilder.Create() + .ConfigureRtmpServer(options => options + .Configure(options => options.EnableGopCaching = false) + .AddVideoCodecFilter(builder => builder.Include(VideoCodec.AVC)) + .AddAudioCodecFilter(builder => builder.Include(AudioCodec.AAC)) + .AddStreamProcessor() + .AddHlsTransmuxer() + ) + .ConfigureLogging(options => options.AddConsole()) + .Build(); + } + } +} diff --git a/samples/LiveStreamingServerNet.HlsAuthenticationDemo/Properties/launchSettings.json b/samples/LiveStreamingServerNet.HlsAuthenticationDemo/Properties/launchSettings.json new file mode 100644 index 00000000..c5e48552 --- /dev/null +++ b/samples/LiveStreamingServerNet.HlsAuthenticationDemo/Properties/launchSettings.json @@ -0,0 +1,48 @@ +{ + "profiles": { + "http": { + "commandName": "Project", + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5010" + }, + "https": { + "commandName": "Project", + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:7138;http://localhost:5010" + }, + "IIS Express": { + "commandName": "IISExpress", + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Container (Dockerfile)": { + "commandName": "Docker", + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", + "environmentVariables": { + "ASPNETCORE_HTTPS_PORTS": "8081", + "ASPNETCORE_HTTP_PORTS": "8080" + }, + "publishAllPorts": true, + "useSSL": true + } + }, + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:40329", + "sslPort": 44320 + } + } +} \ No newline at end of file diff --git a/samples/LiveStreamingServerNet.HlsAuthenticationDemo/appsettings.Development.json b/samples/LiveStreamingServerNet.HlsAuthenticationDemo/appsettings.Development.json new file mode 100644 index 00000000..0c208ae9 --- /dev/null +++ b/samples/LiveStreamingServerNet.HlsAuthenticationDemo/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/samples/LiveStreamingServerNet.HlsAuthenticationDemo/appsettings.json b/samples/LiveStreamingServerNet.HlsAuthenticationDemo/appsettings.json new file mode 100644 index 00000000..10f68b8c --- /dev/null +++ b/samples/LiveStreamingServerNet.HlsAuthenticationDemo/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +}