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

Antiforgery integration for minimal APIs #173

Open
Rick-Anderson opened this issue Aug 14, 2023 · 1 comment
Open

Antiforgery integration for minimal APIs #173

Rick-Anderson opened this issue Aug 14, 2023 · 1 comment

Comments

@Rick-Anderson
Copy link
Contributor

Rick-Anderson commented Aug 14, 2023

See Antiforgery integration for minimal APIs

and this sample

In this code I pass in the action so

app.MapGet("/DisableAntiforgery", () =>
{
    return Results.Content(MyHtml.html("/todo"), "text/html");
});

app.MapGet("/post2", () =>
{
    return Results.Content(MyHtml.html("/todo2"), "text/html");
});

Can use the same HTML when they pass in the action arg.

Is there a clean way to do this to pass in an arg for

<input name="{token.FormFieldName}" 
                              type="hidden" value="{token.RequestToken}" />

Maybe that makes things too messy. Perhaps I should duplicate most of the HTML and not get the HTML from a method while passing the action.

public static string html2(string action, AntiforgeryTokenSet token) => $"""
    <html><body>
        <form action="{action}" method="POST" enctype="multipart/form-data">
            <input name="{token.FormFieldName}" 
                          type="hidden" value="{token.RequestToken}" />
            <input type="text" name="name" />
            <input type="date" name="dueDate" />
            <input type="checkbox" name="isCompleted" />
            <input type="submit" />
        </form>
    </body></html>
""";

Works, but I'm not sure it's an improvement. There's no way to pass in a null token.

@sammychinedu2ky @david-acker

cc @guardrex

@sammychinedu2ky
Copy link
Contributor

I think this works @Rick-Anderson

using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder();

builder.Services.AddAntiforgery();

var app = builder.Build();

app.MapGet("/antiforgery", (HttpContext context, IAntiforgery antiforgery) =>
{
    var token = antiforgery.GetAndStoreTokens(context);
    return Results.Content(MyHtml.html("/todo", token), "text/html");
});

app.MapGet("/non-antiforgery", () =>
{
    Console.WriteLine("nonantiforgery");
    return Results.Content(MyHtml.html("/todo2"), "text/html");
});

app.MapPost("/todo", ([FromForm] Todo todo) => Results.Ok(todo));

app.MapPost("/todo2", ([FromForm] Todo todo) => Results.Ok(todo))
                                                .DisableAntiforgery();

app.Run();

class Todo
{
    public required string Name { get; set; }
    public bool IsCompleted { get; set; }
    public DateTime DueDate { get; set; }
}

public static class MyHtml
{

    public static string html(string action, AntiforgeryTokenSet token = null)
    {
        var forgeryInputField = token is null ?
        "" : generateTokenField(token);
        return $"""
    <html><body>
        <form action="{action}" method="POST" enctype="multipart/form-data">
            {forgeryInputField}
            <input type="text" name="name" />
            <input type="date" name="dueDate" />
            <input type="checkbox" name="isCompleted" />
            <input type="submit" />
        </form>
    </body></html>
""";
    }

    public static string generateTokenField(AntiforgeryTokenSet token) => $"""
        <input name="{token.FormFieldName}" 
                      type="hidden" value="{token.RequestToken}" />
    """;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants