Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add dotnet user-jwts tool and runtime support (#41520) #41956

Merged
merged 1 commit into from
Jun 1, 2022

Conversation

captainsafia
Copy link
Member

@captainsafia captainsafia commented May 31, 2022

Description

This PR introduces a dotnet user-jwts CLI tool for generating JSON Web Tokens for use in local development and runtime changes in ASP.NET Core to support reading options for configuring authentication from config.

Fixes #39857

Customer Impact

The changes introduced in this changeset make it easier for user to configure JWT bearer-based authentication in their applications for local development by:

  • Reducing the lines of code needed to configure auth on a WebAPI
  • Making it easy to generate bearer tokens with a variety of roles/claims for use in testing

Regression?

  • Yes
  • No

Risk

  • High
  • Medium
  • Low

To minimize the risk associated with this change, we've:

  • Validated through automated and manual tests
  • Limited the changeset to a single authentication type
  • Limited the changeset to applications configured with the WebApplicationBuilder

Verification

  • Manual (required)
  • Automated

Packaging changes reviewed?

  • Yes
  • No
  • N/A

* Add dotnet dev-jwts tool

* Add dotnet dev-jwts tool

* Address feedback from review

* Rename project file

* Write auth config to app settings

* Address more feedback

* 🦭

* Apply suggestions from code review

Co-authored-by: Brennan <brecon@microsoft.com>

* Address more feedback

* Add framework support for authentication changes

* Add tests for user-jwts CLI and react to feedback

* Move ConsoleTable implementation to avoid conflicts in ProjectTemplates

* Update existing auth tests and fix middleware registration

* Update AzureAdB2C tests and auth app builder

* Fix build and move registration check

* Fix up resolution for Certificate test sources

* Fix write stream configuration for writing key material

* Fix handling missing config section when processing options

Co-authored-by: Brennan <brecon@microsoft.com>
@captainsafia captainsafia added Servicing-consider Shiproom approval is required for the issue area-web-frameworks *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels labels May 31, 2022
@ghost
Copy link

ghost commented May 31, 2022

Hi @captainsafia. Please make sure you've updated the PR description to use the Shiproom Template. Also, make sure this PR is not marked as a draft and is ready-to-merge.

To learn more about how to prepare a servicing PR click here.

Comment on lines +50 to +52
ValidIssuers = new[] { issuer },
ValidateAudience = audiences.Length > 0,
ValidAudiences = audiences,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come one issuer but multiple audiences when the properties are both arrays?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. We can address that in next preview.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@martincostello we should capture all these suggestions in s new issue. We're up against it for preview.5 so this has to go in as-is.

internal sealed class CreateCommand
{
private static readonly string[] _dateTimeFormats = new[] {
"yyyy-MM-dd", "yyyy-MM-dd HH:mm", "yyyy/MM/dd", "yyyy/MM/dd HH:mm" };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would accepting the "O" format be useful so people could paste in strings copied from something that outputs them in ISO-8601 format?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly? Can you log a separate issue to capture that suggestion please?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


var issuerOption = cmd.Option(
"--issuer",
"The issuer of the JWT. Defaults to the dotnet-user-jwts",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo or cut-off sentence?

Suggested change
"The issuer of the JWT. Defaults to the dotnet-user-jwts",
"The issuer of the JWT. Defaults to 'dotnet-user-jwts'.",


var schemeNameOption = cmd.Option(
"--scheme",
"The scheme name to use for the generated token. Defaults to 'Bearer'",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"The scheme name to use for the generated token. Defaults to 'Bearer'",
"The scheme name to use for the generated token. Defaults to 'Bearer'.",


var audienceOption = cmd.Option(
"--audience",
"The audiences to create the JWT for. Defaults to the URLs configured in the project's launchSettings.json",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"The audiences to create the JWT for. Defaults to the URLs configured in the project's launchSettings.json",
"The audiences to create the JWT for. Defaults to the URLs configured in the project's launchSettings.json.",


var notBeforeOption = cmd.Option(
"--not-before",
@"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",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@"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 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.",

Copy link
Member

@DamianEdwards DamianEdwards Jun 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one still seems to have the overly complex datetime format description still. We can clean these things up in preview.6

{
if (!force)
{
reporter.Output("Are you sure you want to reset the JWT signing key? This will invalidate all JWTs previously issued for this project.\n [Y]es / [N]o");
Copy link
Member

@martincostello martincostello Jun 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
reporter.Output("Are you sure you want to reset the JWT signing key? This will invalidate all JWTs previously issued for this project.\n [Y]es / [N]o");
reporter.Output($"Are you sure you want to reset the JWT signing key? This will invalidate all JWTs previously issued for this project.{Environment.NewLine} [Y]es / [N]o");

}
var jwtStore = new JwtStore(userSecretsId);

if (!jwtStore.Jwts.ContainsKey(id))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use TryGetValue()? Then you don't need to use the indexer on line 53.

userSecretsId = null;
if (project == null)
{
reporter.Error($"No project found at `-p|--project` path or current directory.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this message be a bit misleading if more than one *.proj file was found for some reason?

var value = applicationUrl.GetString();
if (value is { } applicationUrls)
{
return applicationUrls.Split(";");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return applicationUrls.Split(";");
return applicationUrls.Split(';');

{
public static void Register(ProjectCommandLineApplication app)
{
app.Command("delete", cmd =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use 'remove' in other places in CLI tools, should we be consistent?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep fair. We can make that change in preview.6

userSecretsId = GetUserSecretsId(project);
if (userSecretsId == null)
{
reporter.Error($"Project does not contain a user secrets ID.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommend adding instructions on how to resolve?


if (existingUserSecretsId == null)
{
return null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've always disliked this about user-secrets -- I've told the tool my intent, if you can't find the secrets key, just create one for me, don't make me extra hop to 'init' it. Let's do that here...if not found, create a new secrets id, add it to the project, output that created one as info ('No secrets file found, created with id {}')

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than gate the check-in on these suggestions, I think we should log them in a separate issue that can be addressed in preview.6

@captainsafia
Copy link
Member Author

Approved via email.

@captainsafia captainsafia added Servicing-approved Shiproom has approved the issue and removed Servicing-consider Shiproom approval is required for the issue labels Jun 1, 2022
@captainsafia
Copy link
Member Author

@dotnet/aspnet-build Can I get help merging?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-web-frameworks *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels Servicing-approved Shiproom has approved the issue
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants