Rest API Template 만들기 - EP 06 (Authentication, Authorization with jwt)

2023. 1. 5. 00:00ASPNET/ASPNET 7

반응형

이제 만들어 놓은 JWT 를 이용하여 기본적인 token validation 처리를 통해

Authentication 과 Authorization 을 처리 해보자.

다음 과정을 통해 순서대로 처리할 것이다.

 

1. AddAuthentication 과 AddJwtBearer 를 통해 Jwt 를 기본으로 하는 인증 서비스를 추가

2. AddAuthoirzation 을 추가하여 권한부여 서비스  추가

3. Cross Domain 문제 처리를 위한 CORS 처리

4. Test 를 위해 Swagger 에 인증관련 Test 를 할 수 있도록 설정 추가

 

cross domain 문제에 의해 client 에서 호출시 CORS 문제가 생길 경우를 대비하여 CORS 를 처리 하자

(여기서는 모든 client 를 access 가능하게 할 것이다.

보안상 이러한 문제를 다르게 처리 하고 싶다면 특정 client 만 처리하도록 domain 을 지정하자)

 

appsettings.json 에 정의한 TokenManagement 를 읽어서 필요한 값들을 얻어오자

Program.cs 

...
builder.Services.Configure<TokenManagement>(builder.Configuration.GetSection("TokenManagement"));
var token = builder.Configuration.GetSection("TokenManagement").Get<TokenManagement>();
if (token == null)
    throw new ArgumentNullException(nameof(token));
var secret = Encoding.ASCII.GetBytes(token.Secret);
...

Authentication 과 Authorization 을 처리 하자

...
builder.Services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x =>
{
    x.SaveToken = true;
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(token.Secret)),
        ValidIssuer = token.Issuer,
        ValidAudience = token.Audience,
        ValidateIssuer = false,
        ValidateAudience = false
        //ClockSkew = isDevelopment ? TimeSpan.Zero : TimeSpan.FromSeconds(30)
    };
});
builder.Services.AddAuthorization();
...

그리고 Cors 를 처리해보자

...
builder.Services.AddCors(o => o.AddPolicy("ApiServerPolicy", builder =>
{
    builder.AllowAnyOrigin()
           .AllowAnyMethod()
           .AllowAnyHeader();
}));
...

Test 를 위해서 swagger 에 authorization 관련 설정을 할 수 있도록 해보자

...
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "ApiServer API", Version = "v1" });
    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.Http,
        Name = "Bearer",
        BearerFormat = "JWT",
        Description = "Please enter authorization key",
        Scheme = "Bearer"
    });
    c.AddSecurityRequirement(new OpenApiSecurityRequirement()
            {
                {
                    new OpenApiSecurityScheme()
                    {
                         Reference = new OpenApiReference()
                         {
                             Type = ReferenceType.SecurityScheme,
                             Id = "Bearer"
                         }
                    },
                    Enumerable.Empty<string>().ToList()
                }
            });
    c.CustomSchemaIds(x => x.FullName?.Replace("+", "."));
});
builder.Services.Configure<SwaggerGeneratorOptions>(opts =>
{
    opts.InferSecuritySchemes = true;
});
...

이제 UserController 로 이동하여서 인증을 해야 처리되는 api 를 만들어 보자

Features/User/UserController.cs

...
[Authorize]
public class UserController : ControllerBase
{
	...
	
    [HttpGet("hello")]
    [ProducesResponseType(typeof(string), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> AuthHello() => await Task.FromResult(Ok("Hello"));
}

 

swagger 에서 우선 hello 를 실행해보자

401 unauthorized

위와 같이 처리될 것이다. 인증 및 권한이 필요하다는 메세지 이다. 

이제 Login 을 하고 AccessToken 을 얻어온 후 swagger 상단 오른쪽 에 자물쇠 표시를 클릭하자

얻어온 AccessToken 을 value 에 따옴표를 제외하고 넣자.

Authorize 를 클릭하자

 

그후 hello 를 다시 실행해보자

아래와 같이 request 시에 header 에 Bearer token 이 들어가는 것을 확인 할 수 있다.

그리고 Response 는 아래와 같다. 

정상 처리 되었다. 

 

 

관련영상

https://youtu.be/mv1-e7T2YmE

 

반응형