diff --git a/src/Tools/dotnet-user-jwts/src/Commands/CreateCommand.cs b/src/Tools/dotnet-user-jwts/src/Commands/CreateCommand.cs index 0b6dda38a89f..63a3342b95e0 100644 --- a/src/Tools/dotnet-user-jwts/src/Commands/CreateCommand.cs +++ b/src/Tools/dotnet-user-jwts/src/Commands/CreateCommand.cs @@ -4,6 +4,7 @@ using System.Globalization; using System.Linq; using System.Text; +using System.Text.Json; using Microsoft.Extensions.CommandLineUtils; using Microsoft.Extensions.Tools.Internal; @@ -77,6 +78,11 @@ public static void Register(ProjectCommandLineApplication app) Resources.CreateCommand_ValidForOption_Description, CommandOptionType.SingleValue); + var outputOption = cmd.Option( + "-o|--output", + Resources.CreateCommand_OutputOption_Description, + CommandOptionType.SingleValue); + cmd.HelpOption("-h|--help"); cmd.OnExecute(() => @@ -89,7 +95,7 @@ public static void Register(ProjectCommandLineApplication app) return 1; } - return Execute(cmd.Reporter, cmd.ProjectOption.Value(), options, optionsString); + return Execute(cmd.Reporter, cmd.ProjectOption.Value(), options, optionsString, outputOption.Value()); }); }); } @@ -208,7 +214,8 @@ private static int Execute( IReporter reporter, string projectPath, JwtCreatorOptions options, - string optionsString) + string optionsString, + string outputFormat) { if (!DevJwtCliHelpers.GetProjectAndSecretsId(projectPath, reporter, out var project, out var userSecretsId)) { @@ -232,9 +239,20 @@ private static int Execute( var settingsToWrite = new JwtAuthenticationSchemeSettings(options.Scheme, options.Audiences, options.Issuer); settingsToWrite.Save(appsettingsFilePath); - reporter.Output(Resources.FormatCreateCommand_Confirmed(jwtToken.Id)); - reporter.Output(optionsString); - reporter.Output($"{Resources.JwtPrint_Token}: {jwt.Token}"); + switch (outputFormat) + { + case "token": + reporter.Output(jwt.Token); + break; + case "json": + reporter.Output(JsonSerializer.Serialize(jwt, new JsonSerializerOptions { WriteIndented = true })); + break; + default: + reporter.Output(Resources.FormatCreateCommand_Confirmed(jwtToken.Id)); + reporter.Output(optionsString); + reporter.Output($"{Resources.JwtPrint_Token}: {jwt.Token}"); + break; + } return 0; } diff --git a/src/Tools/dotnet-user-jwts/src/Resources.resx b/src/Tools/dotnet-user-jwts/src/Resources.resx index 3bd782f5b052..9a7dd45dbd52 100644 --- a/src/Tools/dotnet-user-jwts/src/Resources.resx +++ b/src/Tools/dotnet-user-jwts/src/Resources.resx @@ -1,17 +1,17 @@  - @@ -174,6 +174,9 @@ The UTC date & time the JWT should not be valid before in the format 'yyyy-MM-dd [[HH:mm[[:ss]]]]'. Defaults to the date & time the JWT is created. + + The format to use for displaying output from the command. Can be one of 'default', 'token', or 'json'. + A role claim to add to the JWT. Specify once for each role. @@ -300,4 +303,4 @@ No JWT with ID '{0}' found. - + \ No newline at end of file diff --git a/src/Tools/dotnet-user-jwts/test/UserJwtsTests.cs b/src/Tools/dotnet-user-jwts/test/UserJwtsTests.cs index 44a2a94798f7..bfacf663d61f 100644 --- a/src/Tools/dotnet-user-jwts/test/UserJwtsTests.cs +++ b/src/Tools/dotnet-user-jwts/test/UserJwtsTests.cs @@ -12,6 +12,8 @@ using Xunit; using Xunit.Abstractions; using System.Text.RegularExpressions; +using System.Text.Json; +using System.IdentityModel.Tokens.Jwt; namespace Microsoft.AspNetCore.Authentication.JwtBearer.Tools.Tests; @@ -277,4 +279,32 @@ public void PrintComamnd_ShowsAllOptionsWithShowAll() Assert.Contains($"Roles: [none]", output); Assert.Contains($"Custom Claims: [foo=bar]", output); } + + [Fact] + public void Create_WithJsonOutput_CanBeSerialized() + { + var project = Path.Combine(_fixture.CreateProject(), "TestProject.csproj"); + var app = new Program(_console); + + app.Run(new[] { "create", "--project", project, "--output", "json" }); + var output = _console.GetOutput(); + var deserialized = JsonSerializer.Deserialize(output); + + Assert.NotNull(deserialized); + Assert.Equal("Bearer", deserialized.Scheme); + Assert.Equal(Environment.UserName, deserialized.Name); + } + + [Fact] + public void Create_WithTokenOutput_ProducesSingleValue() + { + var project = Path.Combine(_fixture.CreateProject(), "TestProject.csproj"); + var app = new Program(_console); + + app.Run(new[] { "create", "--project", project, "-o", "token" }); + var output = _console.GetOutput(); + + var handler = new JwtSecurityTokenHandler(); + Assert.True(handler.CanReadToken(output.Trim())); + } }