Auth0으로 AspNetCore .NET 6 API 보호 - SwaggerUI와 함께 작동

AspNetCore에서 JWT 인증의 내부 작업에 대해서는 자세히 설명하지 않겠습니다.

그러나 시작하려면 로그인 성공 시 Auth0이 반환하는 JWT 토큰의 유효성을 검사하는 Nuget 패키지를 추가해야 합니다.

작업 디렉토리를 인증을 추가하려는 프로젝트로 변경하십시오. 그런 다음 다음을 실행하십시오.
dotnet add Microsoft.AspNetCore.Authentication.JwtBearer
다음으로 Program.cs 파일로 이동하여 다음을 추가합니다.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.Authority = "https://<auth0-domain>/";
        options.Audience = "https://<auth0-domain>/userinfo"; // or "<your audience>"
    });


예를 들어 단순하게 유지했지만 AspNetCore의 구성 시스템을 사용하여 값을 저장하는 것이 좋습니다.

기본적으로 이는 값이 AuthorizationBearer <auth0 access token jwt> 헤더에 도착하는 JWT를 찾도록 AspNetCore 파이프라인을 구성할 것입니다. 추가한 라이브러리는 구성에 대해 Auth0의 JWT를 검증합니다.

다음으로 두 개의 추가 호출을 추가해야 합니다.

app.UseAuthentication();
app.UseAuthorization();



// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
    options.AddSecurityDefinition("Auth0", new OpenApiSecurityScheme()
    {
        Type = SecuritySchemeType.OAuth2,
        Flows = new OpenApiOAuthFlows
        {
            AuthorizationCode = new OpenApiOAuthFlow()
            {
                // you need to set the urls as they are specific to Auth0
                AuthorizationUrl = new Uri("https://<auth0-domain>/authorize"),
                TokenUrl = new Uri("https://<auth0-domain>/oauth/token"),
                Scopes = new Dictionary<string, string>
                {
                    {"openid", "openid"},
                    {"email", "email"},
                    {"profile", "profile"},
                    // any additional custom scopes you want
                }
            }
        }
    });
    // optional if you are not using [Authorize] attributes
    options.OperationFilter<SecurityRequirementsOperationFilter>();
});


작업 필터는 전역 권한 부여 정책을 사용하는 경우에만 필요합니다. 예: app.MapControllers().RequireAuthorization(...) 마지막에 클래스 코드를 포함했습니다.

이 다음 부분은 아래 주석에서 설명한 것처럼 대체로 선택 사항입니다. Swagger UI에서 조정할 수 있는 몇 가지 추가 값이 있습니다.

Auth0으로 audience를 조심하십시오. 나는 이것을 볼 때까지 왜 내가 올바른 액세스 토큰을 돌려받지 못하는지 궁금해하는 데 많은 시간을 보냈습니다.

In addition, if you have chosen to allow users to log in through an Identity Provider (IdP), such as Facebook, the IdP will issue its own access token to allow your application to call the IDP's API. For example, if your user authenticates using Facebook, the access token issued by Facebook can be used to call the Facebook Graph API. These tokens are controlled by the IdP and can be issued in any format. See Identity Provider Access Tokens for details. - Auth0 - Access Tokens



// optional: only want to have Swagger UI available in Development 
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(options =>
    {
        // optional: just prefills the Swagger UI input boxes, if left off you must supply these values. Would make sense to get these from configuration and better yet user-secrets 
        options.OAuthClientId("<auth0 client id>");
        options.OAuthClientSecret("<auth0 client secret>");
        // optional & gotcha: but if you are using Auth0 with a Social Connection you MUST supply an audience otherwise you will get back the underlying identity providers access token, NOT Auth0's
        options.OAuthAdditionalQueryStringParams(new Dictionary<string, string>
        {
            {"audience", "<your audience>"}
        });
    });
}


이제 모든 것이 코드 관점에서 설정되었으므로 API를 실행하고 /swagger/ 로 이동할 수 있습니다. 이제 인증 버튼이 표시됩니다.



SwaggerUI 콜백 URL(예: https://<your api url>/swagger/oauth2-redirect.html)로 Auth0을 구성해야 합니다.

최종Program.cs 파일은 다음과 같아야 합니다.
https://gist.github.com/OliverRC/650436fbae77371a55b84c646c35ba3a

신용 거래



내가 여기에 쓴 대부분의 내용에 영감을 준 그의 기사에 큰 박수를 보냅니다.

https://dotnetcoretutorials.com/2021/02/14/using-auth0-with-an-asp-net-core-api-part-3-swagger/

부록 - SecurityRequirementsOperationFilter




public class SecurityRequirementsOperationFilter : IOperationFilter
{
    /// <summary>
    /// Applies the this filter on swagger documentation generation.
    /// </summary>
    /// <param name="operation"></param>
    /// <param name="context"></param>
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        // then check if there is a method-level 'AllowAnonymous', as this overrides any controller-level 'Authorize'
        var anonControllerScope = context
                .MethodInfo
                .DeclaringType?.GetCustomAttributes(true)
                .OfType<AllowAnonymousAttribute>();

        var anonMethodScope = context
                .MethodInfo
                .GetCustomAttributes(true)
                .OfType<AllowAnonymousAttribute>();

        // only add authorization specification information if there is at least one 'Authorize' in the chain and NO method-level 'AllowAnonymous'
        if (anonMethodScope.Any()) return;
        if (anonControllerScope != null && anonControllerScope.Any()) return;

        // add generic message if the controller methods dont already specify the response type
        if (!operation.Responses.ContainsKey("401"))
            operation.Responses.Add("401", new OpenApiResponse { Description = "If Authorization header is not present, the value is empty or value is not a valid jwt bearer token" });
        if (!operation.Responses.ContainsKey("403"))
            operation.Responses.Add("403", new OpenApiResponse { Description = "If user is not authorized to perform requested action" });

        var jwtAuthScheme = new OpenApiSecurityScheme
        {
            Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Auth0" }
        };

        operation.Security = new List<OpenApiSecurityRequirement>
        {
            new OpenApiSecurityRequirement
            {
                [ jwtAuthScheme ] = new List<string>()
            }
        };
    }
}

좋은 웹페이지 즐겨찾기