Adding JWT Authentication & Authorization #9

์ถœ์ฒ˜: https://youtu.be/mgeuh8k3I4g

๊ทธ๋™์•ˆ TIM Corey ์„ ์ƒ๋‹˜์˜ ๊ฐ•์ขŒ๋ฅผ clone ํ•˜๋‹ค๊ฐ€ ๋‹ค๋ฅธ๋ถ„๋„ ํ•ด๋ด…๋‹ˆ๋‹ค.
Nick Chapsas ์˜ ์ธ์ฆ ,ํ—ˆ๊ฐ€์˜ ๊ด€ํ•œ ๊ฐ•์ขŒ์ž…๋‹ˆ๋‹ค.
์ œ๊ฐ€ ์•ž์œผ๋กœ ๊ถŒํ•œ ,์ธ์ฆ์˜ ๊ด€๋ จ ์—…๋ฌด(?)๋ฅผ ํ• ๊ฒƒ ๊ฐ™์•„ ๊ณต๋ถ€์ค‘์ด๊ธฐ๋„ ํ•˜๊ณ ์š”

chater 1

jwt ์„ค๋ช…
์ถœ์ฒ˜: https://youtu.be/qDJYgGzmalQ

๋ณดํ†ต ์‚ฌ์šฉ์ž๊ฐ€ ์›น์‚ฌ์ดํŠธ์˜ ์ ‘๊ทผํ• ๋•Œ ์‚ฌ์šฉํ—ˆ๊ฐ€๋ฅผ ๋ฐ›์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๊ณผ๊ฑฐ ๋ชจ๋…ธ๋กคํ‹ฑ ๊ฐœ๋ฐœ์—์„œ ์ธ์ฆ์„ ํ†ต๊ณผํ•œ ์‚ฌ์šฉ์ž๋Š” ์‹๋ณ„๊ฐ’์€ ๋ณดํ†ต ์„œ๋ฐ”๊ฐ€ ์„ธ์…˜์— ์ €์žฅํ•˜๋Š”๊ฒƒ์ด ๋ณดํ†ต์ด์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๋•Œ ์‚ฌ์šฉ์ž๋Š” ์„œ๋ฒ„์—๊ฒŒ ์š”์ฒญ์„ ๋ณด๋‚ผ๋•Œ ์ž์‹์„ ๊ตฌ๋ถ„ํ•˜๋Š” Key๊ฐ€ ์žˆ๋Š๋ฐ ๋ณดํ†ต
cookie ๊ฐ’์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์˜ cookie๋ฅผ ์„œ๋ฒ„ ์„ธ์…˜ ํ‚ค๊ฐ’๊ณผ ๋งค์นญํ•ด์„œ
์‚ฌ์šฉ์ž๋ฅผ ์‹๋ณ„ํ•ฉ๋‹ˆ๋‹ค. ์ „ํ†ต์ ์ธ ์ธ์ฆ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์›น์‚ฌ์ดํŠธ๊ฐ€ ํ™•์žฅ์„ ํ•œ๋‹ค๊ณ  ํ–ˆ์„๋•Œ ์ด ์„ธ์…˜์€ ๊ณต์œ ๋˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
(์„ฑ๋Šฅ๋„ ์•ˆ์ข‹๊ณ ์š”)

์ด ๋ฌธ์ œ๋ฅผํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด stateless ๋กœ ์„œ๋ฒ„์—์„œ ์‚ฌ์šฉ์ž ์ƒํƒœ๊ฐ’์„ ๋”ฐ๋กœ ์ €์žฅํ•˜์ง€ ์•Š๊ณ 
ํ•ด์‰ฌ๊ฐ’์œผ๋กœ ์‚ฌ์šฉ์ž๋ฅผ ์ฒดํฌํ•˜๋Š” ๋ฐฉ์‹์„ ๊ฐœ๋ฐœํ•ฉ๋‹ˆ๋‹ค.
์ด๊ฑด ํ•ด๋‹น ์„œ๋ฒ„์—์„œ๋งŒ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ ์—ด์‡ ๋ฅผ ์‚ฌ์šฉ์ž๊ฐ€ ๊ฐ€์ง€๊ณ  ๋‹ค๋‹Œ๋‹ค๋Š” ์˜๋ฏธ์ฃ 

์ด๋Ÿฐ ์‹œ์Šคํ…œ์€ ์ฃผ๋กœ API๋กœ ๋ฌถ์ธ MSA์— ๋งŽ์ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž๋Š” ์‚ฌ์ดํŠธ๊ฐ€ ํ•˜๋‚˜๊ฐ™์ด ๋ณด์ด์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ๋ฌผ๋ฆฌ์ ์œผ๋กœ ํŠธ๋ž˜ํ”ฝ์„ ๋ถ„์‚ฐ์‹œํ‚ต๋‹ˆ๋‹ค.
์ด๋•Œ API๋Š” ์‚ฌ์šฉ์ž๋ฅผ ์‹๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด ์š”์ฒญ Header ์— jwt token์„ ๋ณด๋‚ด์ค๋‹ˆ๋‹ค.


JWT ํ† ํฐ์˜ ๊ตฌ์กฐ

Header

typ: ํ† ํฐ์˜ ํƒ€์ž…์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”๋กœ JWT ์ด์ฃ .
alg: ํ•ด์‹ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ํ•ด์‹ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ๋Š” ๋ณดํ†ต HMAC SHA256 ํ˜น์€ RSA ๊ฐ€ ์‚ฌ์šฉ๋˜๋ฉฐ, ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์€, ํ† ํฐ์„ ๊ฒ€์ฆ ํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” signature ๋ถ€๋ถ„์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

์ •๋ณด(payload)

token์— ๋‹ด์„ ์ •๋ณด

{
โ€œissโ€: โ€œvelopert.comโ€,
โ€œexpโ€: โ€œ1485270000000โ€,
โ€œhttps://velopert.com/jwt_claims/is_adminโ€: true,
โ€œuserIdโ€: โ€œ11028373727102โ€,
โ€œusernameโ€: โ€œvelopertโ€
}

์„œ๋ช…

JSON Web Token ์˜ ๋งˆ์ง€๋ง‰ ๋ถ€๋ถ„์€ ๋ฐ”๋กœ ์„œ๋ช…(signature) ์ž…๋‹ˆ๋‹ค. ์ด ์„œ๋ช…์€ ํ—ค๋”์˜ ์ธ์ฝ”๋”ฉ๊ฐ’๊ณผ, ์ •๋ณด์˜ ์ธ์ฝ”๋”ฉ๊ฐ’์„ ํ•ฉ์นœํ›„ ์ฃผ์–ด์ง„ ๋น„๋ฐ€ํ‚ค๋กœ ํ•ด์‰ฌ๋ฅผ ํ•˜์—ฌ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค


๊ตฌํ˜„


API ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

๊ท€์ฐฎ์œผ๋‹ˆ ๊ธฐ๋ณธ ์™€๊พธ๋Š” ๋งŒ๋“ค์ž๊ณ ์š” ^^
๊ทธ ๋‹ค์Œ nuget package

Microsoft.AspNetCore.Authentication.JwtBearer

๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  program.cs ์—์„œ

builder.Services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
});

์„œ๋น„์Šค๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  jwt ๊ธฐ๋ณธ ์˜ต์…˜ ์„ค์ •๊ฐ’์„ appsettings.json์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "JwtSettings": {
    "Issuer": "https://dotnetdeve.com",
    "Audience": "https://dotnetdeve.com/bluebird",
    "Key": "dotnetdevforeverdotnetdevforeverdotnetdevforeverdotnetdevforeverdotnetdevforever"
  }
}

์ถ”๊ฐ€๋กœ ์•„๊นŒ ๋“ฑ๋กํ•œ jwt ์ธ์ฆ์—

builder.Services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x=> {
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidIssuer = config["JwtSettings:Issuer"],
        ValidAudience = config["JwtSettings:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config["JwtSettings:Key"]!)),
        ValidateIssuer = true,
        ValidateAudience= true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey =true

    };
});

Token ์— ๋Œ€ํ•œ ์ธ์ฆ ์˜ต์…˜์„ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.
ValidIssuer,ValidAudience,IssuerSigningKey ๋Š” ์ด๊ฐ’์ด ์—ฌ๊ธฐ์„œ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ’์ด๋ผ๋Š” ์˜๋ฏธ์ด๊ณ  ValidateIssuer,ValidateAudience,ValidateLifetime,ValidateIssuerSigningKey
ํ•„์ˆ˜ ์—ฌ๋ถ€์ž…๋‹ˆ๋‹ค.


์—ฌ๋‹ด์œผ๋กœ ์ด ์•„์ €์”จ ๋ง ์ง„์งœ ๋น ๋ฅด๋„ค์š” 10๋ถ„์งœ๋ฆฌ ๊ฐ•์˜์ธ๋ฐ ๋ถ„๋Ÿ‰์€ ํ•œ 30๋ถ„ ๋˜๋Š”๊ฒƒ ๊ฐ™๋„ค์š”


๊ทธ๋ฆฌ๊ณ  builder.Services.AddAuthentication(); ์ธ์ฆ์„œ๋น„์Šค๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
๋ฏธ๋“ค์›จ์–ด๋„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. (์ˆœ์„œ ์ค‘์š”!)

๊ทธ๋ฆฌ๊ณ  controller ์— ๊ถŒํ•œ ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

[ApiController]
[Route("[controller]")]
[Authorize]
public class WeatherForecastController : ControllerBase

์ด๋ฒˆ์—๋Š” token ์„ ์ƒ์„ฑํ•˜๋Š” conroller ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

[HttpGet]
    [Route("Token")]
    public IActionResult GenerateToken()
    {
        var tokenhandler = new JwtSecurityTokenHandler();
        var key = Encoding.UTF8.GetBytes(TokenSecret);
        var timespan = TimeSpan.FromHours(8);
        var claims = new List<Claim>
        {
            new (JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString()),
            new (JwtRegisteredClaimNames.Sub,"dotnetdev"),
            new (JwtRegisteredClaimNames.Email,"dot@korea.com"),
            new ("Userid","blueBird"),
        };

        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(claims),
            Expires = DateTime.UtcNow.Add(timespan),
            Issuer = "https://dotnetdeve.com",
            Audience = "https://dotnetdeve.com/bluebird",
            SigningCredentials =new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256)
        };

        var token = tokenhandler.CreateToken(tokenDescriptor);
        var jwt = tokenhandler.WriteToken(token);
        return Ok(jwt);
    }

์›๋ž˜ ์ด๋ ‡๊ฒŒ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•˜๋ฉด ์•ˆ๋˜์ง€๋งŒ ๊ตฌํ˜„์—๋งŒ ์ดˆ์ ์„ ๋งž์ถฐ์„œ ์‹ฌํ”Œํ•˜๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค.

swagger๋กœ ํ™•์ธํ•ด๋ณด๋‹ˆ ์ž˜๋‚˜์˜ค๋Š”๊ตฐ์š” ๋‚˜์˜จ ํ† ํฐ์„ https://jwt.ms/
์—ฌ๊ธฐ์—์„œ ํ™•์ธํ•ด๋ด…๋‹ˆ๋‹ค.

์ด์ œ ์ด token ์ด ์ด API ์—์„œ๋„ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•œ์ง€ ์‚ฌ์šฉํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Insomnia(https://insomnia.rest/) ๋กœ ํ™•์ธํ•ด๋ด…๋‹ˆ๋‹ค.


header ์— Authorization๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  Bearer [token] ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

์—ญ์‹œ ์ž˜๋‚˜์˜ค๋„ค์š”


์ •์ฑ… ์„ค์ •

roll ๋ช…์„ ์ €์žฅํ•  IdentityData.cs ์ƒ์„ฑํ•œํ›„

public class IdentityData
{
    public const string AdminUserClaimName = "admin";
    public const string AdminUserPolicyName = "Admin";
}

Program.cs์—์„œ ์ •์ฑ…์„ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

builder.Services.AddAuthorization(option =>
{
    option.AddPolicy(IdentityData.AdminUserClaimName, p => p.RequireClaim(IdentityData.AdminUserClaimName,"true"));
});

token ์— IdentityData.AdminUserClaimName ์ด claim value๊ฐ€ true ์—ฌ์•ผ ํ†ต๊ณผํ•œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

์ด์ œ ์ด ์ •์ฑ…์„ ์“ฐ๋Š” API๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

   [HttpGet("Test1")]
        [Authorize(Policy =IdentityData.AdminUserPolicyName)]
        public string GetAutor()
        {
            return "์•ˆ๋…•";
        }

[Authorize(Policy =IdentityData.AdminUserPolicyName)]

์ด Claim์ด ํฌํ•จ๋˜์•ผ ํ†ต๊ณผ ๋œ๋‹ค ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  token ์ƒ์„ฑ์—์„œ

 var claims = new List<Claim>
       {
           new (JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString()),
           new (JwtRegisteredClaimNames.Sub,"dotnetdev"),
           new (JwtRegisteredClaimNames.Email,"dot@korea.com"),
           new ("Userid","blueBird"),
           new ("admin","true"),
       };

์ด๋ ‡๊ฒŒ new (โ€œadminโ€,โ€œtrueโ€) claim์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ์ž˜ ์ž‘๋™๋˜๋Š” ๋ชจ์Šต์„ ๋ณผ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Git Source : GitHub - BlueBirdJun/JwtAuth_Tutorial

์ด๋ ‡๊ฒŒ API ์˜ ์ธ์ฆ ๊ถŒํ•œ์„ ๊ฐ•์ขŒ๋ฅผ ์ตœ๋Œ€ํ•œ Simple ํ•˜๊ฒŒ ์ž‘์„ฑํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.
๊ทธ๋™์•ˆ ์ •๋ฆฌ๊ฐ€ ์•ˆ๋˜์„œ ํž˜๋“ค์—ˆ๋Š”๋ฐ ์ €๋„ ์ฐธ ๋œป๊นŠ์€ ์‹œ๊ฐ„์ด์—ˆ์Šต๋‹ˆ๋‹ค.
์•ž์œผ๋กœ๋Š” nick ์•„์ €์”จ ๊ฐ•์ขŒ๋ฅผ ์œ„์ฃผ๋กœ ๋ณผ์ƒ๊ฐ์ž…๋‹ˆ๋‹ค.

10๊ฐœ์˜ ์ข‹์•„์š”

์—…๋ฌด๋ฅผ ํ•˜์‹ค ์˜ˆ์ •์ด๋ผ๊ณ  ํ•˜์…”์„œ ์กฐ๊ธˆ ๋ณดํƒœ์ž๋ฉด ๋ณด์•ˆ์ ์ธ ์ธก๋ฉด์—์„œ 8์‹œ๊ฐ„์˜ accessToken์€ ์กฐ๊ธˆ ๊ธธ๋‹ค๊ณ  ๋ณผ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์•„๋งˆ ์ผ๋ฐ˜์ ์ธ ํ† ํฐ ๋ฐœ๊ธ‰ ์„œ๋น„์Šค๋“ค์„ ์‚ดํŽด ๋ณด์‹œ๋ฉด, ๊ธฐ๋ณธ์ ์œผ๋กœ 1์‹œ๊ฐ„ ์ •๋„์˜ ๋งŒ๋ฃŒ์‹œ๊ฐ„์„ ๊ฐ–๋„๋ก ์„ค๊ณ„ ํ•˜๋Š”๋ฐ์š”.

accessToken ๋ฐœ๊ธ‰์‹œ refreshToken์„ ํ•จ๊ป˜ ๋ฐœ๊ธ‰ํ•˜๊ณ , refreshToken์€ accessToken์— ๋น„ํ•ด ์ƒ๋Œ€์ ์œผ๋กœ ๊ธด ์‹œ๊ฐ„์„ ๊ฐ–๊ณ  ๋ณดํ†ต์˜ ๊ฒฝ์šฐ๋ผ๋ฉด ์œ ์ €๋ณ„๋กœ ๊ด€๋ฆฌ๋˜๋ฉฐ, ๋ธŒ๋ผ์šฐ์ € ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅํ•˜์—ฌ api ํ˜ธ์ถœ์‹œ ํ† ํฐ ๋งŒ๋ฃŒ์— ๋”ฐ๋ฅธ ์˜ˆ์™ธ ๋ฐœ์ƒ(403) ์— ๋Œ€ํ•œ ๋Œ€์‘์œผ๋กœ refreshToken์œผ๋กœ accessToken์„ ์žฌ๋ฐœ๊ธ‰ํ•˜์—ฌ ๋ณด์•ˆ์€ ์ง€ํ‚ค๋ฉด์„œ ์„œ๋น„์Šค์˜ ๋ถˆํŽธํ•จ์„ ์ตœ์†Œํ™”ํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐœ๋ฐœํ•˜๋Š” ์˜ˆ์ œ๋“ค์„ ๋งŽ์ด ๋ณด์‹ค ์ˆ˜ ์žˆ์œผ์‹ค๊บผ์—์š”.

6๊ฐœ์˜ ์ข‹์•„์š”

์กฐ์–ธ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ํ˜น์‹œ ๋ช‡๊ฐ€์ง€ ์งˆ๋ฌธ ๋“œ๋ ค๋„ ๋ ๊นŒ์š”??
์˜ˆ์ œ๋ฅผ ๋ณด๋ฉด token ์„ db ์— ๋งŽ์ด ์ €์žฅํ•˜๋Š”๋ฐ ์ด๊ฑด ๊ด€๋ฆฌ์— ์ด์œ ์ผ๊นŒ์š”?(๊ทธ๋ ‡๋‹คํ•ด๋„ ๋”ฑํžˆ ๋กœ๊ทธ
์™ธ์—๋Š” ์“ธ์ผ์ด ์—†์–ด๋ณด์ด๋„ค์š”)์‹ค๋ฌด์—์„œ๋Š”
db์— ์ €์žฅํ•˜๋Š”๊ฒƒ์ด ๋ณดํ†ต์ผ๊นŒ์š”??

๊ทธ๋ฆฌ๊ณ  ์ €๋Š” ์˜ˆ์ œ์—์„œ Microsoft.AspNetCore.Authentication.JwtBearer ๋กœ ๊ตฌํ˜„์„ ํ–ˆ์ง€๋งŒ
์ƒ๋‹น์ˆ˜ ์˜ˆ์ œ๋“ค์ด identyserver4 ๋ฅผ ์“ฐ๋‹ค๊ฐ€ ์œ ๋ฃŒํ™”๋กœ ๋„˜์–ด๊ฐ„๊ฒƒ ๊ฐ™์€๋ฐ
๊ตณ์ด identyserver4 ๋ฅผ ์•ˆ์จ๋„ ๋ ๊นŒ์š” ์•„๋‹ˆ๋ฉด ์žˆ๋‹ค๋ฉด
ํ˜น์‹œ ์˜คํ”ˆ ์†Œ์Šค์ค‘์— ์ถ”์ฒœํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ™์€๊ฒƒ์ด ์žˆ์„๊นŒ์š”?
๊ทธ๋ฆฌ๊ณ  ์ด๊ฒŒ ๊ฐ€๋Šฅํ•œ์ง€ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ Claim์€ policy ์ƒ์„ฑ์˜ ๊ฒฝ์šฐ
์• ์ดˆ์— ์ฒ˜์Œ๋ถ€ํ„ฐ code์ƒ์˜ ํ•˜๋“œ ์ฝ”๋”ฉ ํ•˜๋Š”๊ฒƒ์œผ๋กœ ๋˜์žˆ๋Š”๋ฐ
์ด๊ฑธ db์— ๋„ฃ์–ด๋†“๊ณ  ๋Ÿฐํƒ€์ž„์—์„œ ๋ณ€๊ฒฝํ•˜๋Š”๊ฒƒ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒ ์ฃ ??

1๊ฐœ์˜ ์ข‹์•„์š”

์กฐ์–ธ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ํ˜น์‹œ ๋ช‡๊ฐ€์ง€ ์งˆ๋ฌธ ๋“œ๋ ค๋„ ๋ ๊นŒ์š”??
์˜ˆ์ œ๋ฅผ ๋ณด๋ฉด token ์„ db ์— ๋งŽ์ด ์ €์žฅํ•˜๋Š”๋ฐ ์ด๊ฑด ๊ด€๋ฆฌ์— ์ด์œ ์ผ๊นŒ์š”?
(๊ทธ๋ ‡๋‹คํ•ด๋„ ๋”ฑํžˆ ๋กœ๊ทธ์™ธ์—๋Š” ์“ธ์ผ์ด ์—†์–ด๋ณด์ด๋„ค์š”)์‹ค๋ฌด์—์„œ๋Š” db์— ์ €์žฅํ•˜๋Š”๊ฒƒ์ด ๋ณดํ†ต์ผ๊นŒ์š”??

์–ด๋–ค ์˜ˆ์ œ์ธ์ง€๋Š” ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค๋งŒ, accessToken์„ db์— ์ €์žฅํ•˜์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค.
์œ ํšจํ•œ ํ† ํฐ ๊ฒ€์‚ฌ์— ๋น ๋ฅด๊ฒŒ ๋Œ€์‘ํ•˜๊ธฐ ์œ„ํ•ด redis๋ฅผ ์ด์šฉํ•˜๊ธฐ๋Š” ํ•ฉ๋‹ˆ๋‹ค.
refreshToken์€ ์œ ์ €๋‹น ํ•œ๊ฐœ๋งŒ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ user ํ…Œ์ด๋ธ”์— ๋งคํ•‘ํ•ด์„œ ์ €์žฅํ•ด์„œ ์‚ฌ์šฉํ•˜๊ธด ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ €๋Š” ์˜ˆ์ œ์—์„œ Microsoft.AspNetCore.Authentication.JwtBearer ๋กœ ๊ตฌํ˜„์„ ํ–ˆ์ง€๋งŒ
์ƒ๋‹น์ˆ˜ ์˜ˆ์ œ๋“ค์ด identyserver4 ๋ฅผ ์“ฐ๋‹ค๊ฐ€ ์œ ๋ฃŒํ™”๋กœ ๋„˜์–ด๊ฐ„๊ฒƒ ๊ฐ™์€๋ฐ
๊ตณ์ด identyserver4 ๋ฅผ ์•ˆ์จ๋„ ๋ ๊นŒ์š” ์•„๋‹ˆ๋ฉด ์žˆ๋‹ค๋ฉด
ํ˜น์‹œ ์˜คํ”ˆ ์†Œ์Šค์ค‘์— ์ถ”์ฒœํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ™์€๊ฒƒ์ด ์žˆ์„๊นŒ์š”?

์จ๋ณด์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค๋งŒ, OpenIddict๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ๊ธ€์„ ์ฐธ์กฐํ•ด์ฃผ์„ธ์š”.
asp.net core - IdentityServer4 vs AspNet.Security.OpenIdConnect.Server vs OpenIddict - Stack Overflow
์ฐธ๊ณ ๋กœ, ์ €๋Š” azure-ad์— ๊ถŒํ•œ ํ† ํฐ์„ ๋ณ„๋„ ๋ฐœ๊ธ‰ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์—ฐ๋™ํ•ด๋ณธ ๊ฒฝํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.
Protecting an ASP.NET Core Web API using Microsoft identity platform - Code Samples | Microsoft Learn

๊ทธ๋ฆฌ๊ณ  ์ด๊ฒŒ ๊ฐ€๋Šฅํ•œ์ง€ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ Claim์€ policy ์ƒ์„ฑ์˜ ๊ฒฝ์šฐ
์• ์ดˆ์— ์ฒ˜์Œ๋ถ€ํ„ฐ code์ƒ์˜ ํ•˜๋“œ ์ฝ”๋”ฉ ํ•˜๋Š”๊ฒƒ์œผ๋กœ ๋˜์žˆ๋Š”๋ฐ
์ด๊ฑธ db์— ๋„ฃ์–ด๋†“๊ณ  ๋Ÿฐํƒ€์ž„์—์„œ ๋ณ€๊ฒฝํ•˜๋Š”๊ฒƒ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒ ์ฃ ??

์•„๋งˆ๋„ policy ์ž์ฒด๋ฅผ ์ฝ”๋“œ์ƒ์—์„œ ์ •์˜ํ•˜์ง€ ์•Š๋„๋ก ํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ• ์ง€ ๋ชจ๋ฅด์ง€๋งŒ, policy์— ์—ฐ๊ฒฐ๋˜๋Š” role๋“ค์„ json config ํŒŒ์ผ์ด๋‚˜ db์— ๋„ฃ๊ณ  ๋ถˆ๋Ÿฌ ์˜ค๋„๋ก ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์€ AuthorizationPolicyBuilder๋ฅผ ํ™œ์šฉํ•ด์„œ ์–ผ๋งˆ๋“ ์ง€ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
๋‹ค๋งŒ ์ €๋Š” db๊นŒ์ง€๋Š” ํ•„์š”ํ•˜์ง€ ์•Š์•„ json์œผ๋กœ ์„ค์ •ํ•˜๋„๋ก ํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋„์›€์ด ๋˜์…จ๊ธธ ๋ฐ”๋ž˜์š”~

3๊ฐœ์˜ ์ข‹์•„์š”

์•„ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์•ˆ ๊ทธ๋ž˜๋„ ?OIDC ๋Š” ๋ดค๋Š”๋ฐ Sample ๊ตฌํ˜„์„ ํ–ˆ๋Š”๋ฐ
๋ญ”๊ฐ€ ?? custom ํ•˜๋ ค๋ฉด ํž˜๋“ค์–ด์„œ ๊ทธ๋ƒฅ ๋”ฐ๋กœ ๊ตฌํ˜„ ํ•ด๋ดค์Šต๋‹ˆ๋‹ค.

?AuthorizationPolicyBuilder ์ด๋Ÿฐ ๊ฒƒ์ด ์žˆ๊ตฐ์š” ํ•œ๋ฒˆ ํŒŒ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค ^^

๊ทธ๋ฆฌ๊ณ  ๊ด€๋ฆฌ ์ธก๋ฉด์—์„œ ์ƒ๊ฐํ•ด ๋ดค๋Š”๋ฐ ํ† ํฐ์„ ์ €์žฅํ•œ๋‹ค๊ณ  ํ•˜๊ธฐ๋ณด๋‹ค
๋ฐœํ–‰์š”์ฒญ์ •๋ณด, ๋ฐœํ–‰์ž IP๊ฐ™์€ ๊ฒƒ Log๋กœ ์ €์žฅํ•ด ๋‘๋Š” ํŽธ์ด ๋‚˜์„ ๊ฒƒ ๊ฐ™๋„ค์š”
์ž„์˜๋กœ ๊ณ„์ •์ด ํƒˆ์ทจ๋‹นํ•ด์„œ key ๊ฐ€ ๋ฐœํ–‰ ์š”์ฒญ์„ ์ถ”์ ํ•œ๋‹ค๊ฑฐ๋‚˜ ํ•  ๋•Œ ํ•„์š”ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

2๊ฐœ์˜ ์ข‹์•„์š”