JWT рдХреЗ рд╕рд╛рде .NET рдХреЛрд░ gRpc рдореЗрдВ рдкреНрд░рдорд╛рдгреАрдХрд░рдг

рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ JWT рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ gRpc рд╕реЗрд╡рд╛рдУрдВ рдореЗрдВ рдПрдкреАрдЖрдИ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдХреА рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк JWT рдФрд░ HTTP рд╣реЗрдбрд░ рд╕реЗ .NET рдХреЛрд░ рд╡реЗрдмрдПрдкреАрдЖрдИ рдореЗрдВ рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдЗрди рд╡рд┐рд╡рд░рдгреЛрдВ рдкрд░ рдЪрд░реНрдЪрд╛ рдирд╣реАрдВ рдХреАред рдЬрдм рдореИрдВрдиреЗ gRpc рдореЗрдВ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛, рддреЛ рдореБрдЭреЗ рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдЕрдзрд┐рдХрд╛рдВрд╢ рдЙрджрд╛рд╣рд░рдг рдХрдВрд╕реЛрд▓ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВред рдпрд╣ рдЙрд╕ рд╡рд╛рд╕реНрддрд╡рд┐рдХрддрд╛ рд╕реЗ рдмрд╣реБрдд рджреВрд░ рд╣реИ рдЬрд┐рд╕рдореЗрдВ, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдбреЗрд╡рд▓рдкрд░реНрд╕ рд░рд╣рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореИрдВ рд╣рд░ рдмрд╛рд░ рдПрдХ рдЪреИрдирд▓ рдирд╣реАрдВ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рдЬреЛ рдореИрдВ рдПрдХ рд╕реЗрд╡рд╛ рдкрджреНрдзрддрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдореИрдВ рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдХреЗ рд╕рд╛рде рдПрдХ рдЯреЛрдХрди рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЬрд╛рдирдХрд╛рд░реА рднреЗрдЬрдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рднреА рдЪрд┐рдВрддрд╛ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдореИрдВ рдПрдХ рдмреБрдирд┐рдпрд╛рджреА рдврд╛рдВрдЪрд╛ рд╕реНрддрд░ рд░рдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдЬреЛ рдореЗрд░реЗ рд▓рд┐рдП рдпрд╣ рд╕рдм рдзреНрдпрд╛рди рд░рдЦреЗрдЧрд╛ред рдпрджрд┐ рдпрд╣ рд╡рд┐рд╖рдп рдЖрдкрдХреЗ рд▓рд┐рдП рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рддреЛ рдХрдЯреМрддреА рдХреЗ рддрд╣рдд рдЕрдзрд┐рдХ рд╣реЛрдЧрд╛ред рдЗрд╕ рдЖрд▓реЗрдЦ рдХреЗ рд╕рднреА рдЙрджрд╛рд╣рд░рдг .NET рдХреЛрд░ 3.1 рдХреЗ рд▓рд┐рдП рдорд╛рдиреНрдп рд╣реИрдВред

рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛


рд╡рд┐рд╖рдп рдореЗрдВ рджреЗрд░реА рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдпрд╣ рд▓реЗрдЦ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИред рдкреВрд░реЗ рд╕рдорд╛рдзрд╛рди рдореЗрдВ рджреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╢рд╛рдорд┐рд▓ рд╣реИрдВ: рдПрдХ рд╡реЗрдмрд╕рд╛рдЗрдЯ рдФрд░ рдЬреАрдЖрд░рдкреАрд╕реА рд╕реЗрд╡рд╛ (рдЗрд╕рдХреЗ рдмрд╛рдж рдПрдкреАрдЖрдИ)ред рджреЛрдиреЛрдВ .NET рдХреЛрд░ 3.1 рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд▓реЙрдЧ рдЗрди рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдХреБрдЫ рдбреЗрдЯрд╛ рджреЗрдЦ рд╕рдХрддрд╛ рд╣реИ рдпрджрд┐ рд╡рд╣ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХреГрдд рд╣реИред рд╡реЗрдмрд╕рд╛рдЗрдЯ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдирд╣реАрдВ рдХрд░рддреА рд╣реИ рдФрд░ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдПрдХ рдПрдкреАрдЖрдИ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИред GRpc рд╕реЗрд╡рд╛ рдХреЗ рд╕рд╛рде рд╕рдВрд╡рд╛рдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╡реЗрдмрд╕рд╛рдЗрдЯ рдХреЗ рдкрд╛рд╕ рдПрдХ рд╡реИрдз JWT рдЯреЛрдХрди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рдпрд╣ рдЯреЛрдХрди рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдкрд░ рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЕрдкрдиреА рддрд░рдл рдХреБрдХреАрдЬрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рдпрд╣ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд┐рд╕ рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИ, рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА JWT рдЯреЛрдХрди рдХреЗ рд╕рд╛рде рднреЗрдЬреА рдЬрд╛рддреА рд╣реИ, рд▓реЗрдХрд┐рди рдЯреЛрдХрди рдореЗрдВ рд╣реА рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдЕрддрд┐рд░рд┐рдХреНрдд HTTP рд╣реЗрдбрд░ рдХреЗ рд╕рд╛рдеред рдиреАрдЪреЗ рджрд┐рдпрд╛ рдЧрдпрд╛ рдЖрдВрдХрдбрд╝рд╛ рдЙрд╕ рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╕реНрдХреАрдорд╛ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореИрдВрдиреЗ рдЕрднреА рдмрд╛рдд рдХреА рд╣реИ:


рдпрд╣рд╛рдВ рдореБрдЭреЗ рдзреНрдпрд╛рди рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЬрдм рдореИрдВрдиреЗ рдпрд╣ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рдерд╛, рддреЛ рдореЗрд░реЗ рдкрд╛рд╕ рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рд╕рд╣реА рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдкрджреНрдзрддрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рд▓рдХреНрд╖реНрдп рдирд╣реАрдВ рдерд╛ред рдпрджрд┐ рдЖрдк рдХреБрдЫ рд╕рд░реНрд╡реЛрддреНрддрдо рдкреНрд░рдерд╛рдУрдВ рдХреЛ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ OpenID рдХрдиреЗрдХреНрдЯ рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рджреЗрдЦреЗрдВ ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдХрднреА-рдХрднреА рдореБрдЭреЗ рдпрд╣ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдмрд╕реЗ рд╕рд╣реА рд╕рдорд╛рдзрд╛рди рд╕рдорд╕реНрдпрд╛ рдХреЗ рд╕рдорд╛рдзрд╛рди рдФрд░ рд╕рдордп рдФрд░ рдзрди рдХреА рдмрдЪрдд рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдореЗрдВ рдмреЗрдорд╛рдиреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

GWpc рд╕реЗрд╡рд╛ рдореЗрдВ JWT рдкреНрд░рдорд╛рдгреАрдХрд░рдг рд╕рдХреНрд╖рдо рдХрд░реЗрдВ


рдЬреАрдЖрд░рдкреАрд╕реА рд╕реЗрд╡рд╛ рдХрд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕рд╛рдорд╛рдиреНрдп рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕реЗ рдЕрд▓рдЧ рдирд╣реАрдВ рд╣реИ рдЬреЛ .NET рдХреЛрд░ рдПрдкреАрдЖрдИ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд▓рд╕ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ HTTP рдФрд░ HTTPS рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ рдирд╣реАрдВ рд╣реИред рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдЖрдкрдХреЛ рдорд╛рдирдХ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдФрд░ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рд╕реЗрд╡рд╛рдУрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд╕рд╛рде рд╣реА рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк.рдХреЗрдПрд╕ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдорд┐рдбрд┐рд▓рд╡реЗ рднреА ред рд╡рд╣ рд╕реНрдерд╛рди рдЬрд╣рд╛рдБ рдЖрдк рдорд┐рдбрд▓рд╡реЗрдпрд░ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ: рдЖрдкрдХреЛ рдЗрд╕реЗ рд░рд╛рдЙрдЯрд┐рдВрдЧ рдФрд░ рдкреЙрдЗрдВрдЯреНрд╕ рдХреЗ рдмреАрдЪ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ ( рдХреБрдЫ рдХреЛрдб рдЧрд╛рдпрдм рд╣реИ ):

public void Configure(...) {
    app.UseRouting();
    
    app.UseAuthentication();
    app.UseAuthorization();
    
    app.UseEndpoints(...
}

рд▓реЗрдХрд┐рди рдЬрд┐рд╕ рд╕реНрдерд╛рди рдкрд░ рд╕реЗрд╡рд╛рдПрдВ рдкрдВрдЬреАрдХреГрдд рд╣реИрдВ, рд╡рд╣ рдЗрддрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИ, рдмрд╕ рд╡рд┐рдзрд┐ рдореЗрдВ рдХрдиреНрдлрд┐рдЧрд░рд╕рд░реНрд╡рд┐рд╕ () рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ ред рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рдЖрдкрдХреЛ JWT рдЯреЛрдХрди рдЪреЗрдХ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕реЗ рдпрд╣реАрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕реЗ рдПрдХ рдЕрд▓рдЧ рд╡рд░реНрдЧ рдореЗрдВ рдЦреАрдВрдЪрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдХреЛрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:

public void ConfigureServices(...) {
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(o => {
            var validator = new JwtTokenValidator(...);
            o.SecurityTokenValidators.Add(validator);
        });
    services.AddAuthorization();
}

JwtTokenValidator рд╡рд░реНрдЧ рд╡рд╣ рд╣реИ рдЬрд╣рд╛рдВ рдЖрдк рд╕рддреНрдпрд╛рдкрди рддрд░реНрдХ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВрдЧреЗред рдЖрдкрдХреЛ рд╕рд╣реА рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЗ рд╕рд╛рде TokenValidationParameters рд╡рд░реНрдЧ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдФрд░ рдпрд╣ JWT рдХреЗ рдмрд╛рдХреА рд╡реИрдз рдХрд╛рдо рдХрд░реЗрдЧрд╛ред рдПрдХ рдмреЛрдирд╕ рдХреЗ рд░реВрдк рдореЗрдВ, рдЖрдк рдпрд╣рд╛рдВ рд╕реБрд░рдХреНрд╖рд╛ рдХреА рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдкрд░рдд рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ рдХреНрдпреЛрдВрдХрд┐ JWT рдПрдХ рдкреНрд░рд╕рд┐рджреНрдз рдкреНрд░рд╛рд░реВрдк рд╣реИред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ JWT рд╣реИ, рддреЛ рдЖрдк jwt.io рдкрд░ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдХреБрдЫ рдЬрд╛рдирдХрд╛рд░реА рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВ JWT рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдЬреЛрдбрд╝рдирд╛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВ, рдЬрд┐рд╕рд╕реЗ рдбрд┐рдХреНрд░рд┐рдкреНрд╢рди рдЕрдзрд┐рдХ рдХрдард┐рди рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣рд╛рдБ рдПрдХ рд╕рддреНрдпрд╛рдкрдирдХрд░реНрддрд╛ рдХреИрд╕рд╛ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:

public class JwtTokenValidator : ISecurityTokenValidator
{
    public bool CanReadToken(string securityToken) => true;
    
    public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
    {
        var handler = new JwtSecurityTokenHandler();
        var tokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = "your string",
            ValidAudience = "your string",
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your secrete code"))
        };
        
        var claimsPrincipal = handler.ValidateToken(token, tokenValidationParameters, out validatedToken);
        return claimsPrincipal;
    }
    
    public bool CanValidateToken { get; } = true;
    public int MaximumTokenSizeInBytes { get; set; } = int.MaxValue;
}

рдФрд░ рдпрд╣ рд╕рднреА рдПрдкреАрдЖрдИ рдкрдХреНрд╖ рдХреА рдЬрд░реВрд░рдд рд╣реИред рдХреНрд▓рд╛рдЗрдВрдЯ рд╕реЗрдЯрдЕрдк рдЗрддрд┐рд╣рд╛рд╕ рдЪрдпрдирд┐рдд HTTP рдпрд╛ HTTPS рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдереЛрдбрд╝рд╛ рд▓рдВрдмрд╛ рдФрд░ рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рд╣реИред

GRpc рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рд╣рд░ рдЕрдиреБрд░реЛрдз рдХреЗ рд╕рд╛рде HTTP рд╣реЗрдбрд░ рднреЗрдЬрдирд╛


рдЖрдк рдЗрд╕реЗ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рджрд╕реНрддрд╛рд╡реЗрдЬ рд╕реЗ рдЬрд╛рди рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЖрдк рдбрдВрдмрд▓ рдХрдВрд╕реЛрд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдХрд╣реАрдВ рднреА рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдЗрд╕реЗ рдпрд╣рд╛рдБ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ ред

var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Greeter.GreeterClient(channel);
var response = await client.SayHelloAsync(
    new HelloRequest { Name = "World" });
Console.WriteLine(response.Message);

рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЕрднреА рднреА рдПрдХ рдХреЗрдВрджреНрд░реАрдХреГрдд рд╡рд┐рдиреНрдпрд╛рд╕ рдФрд░ рдбреАрдЖрдИ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬрд┐рдиреНрд╣реЗрдВ рд▓рдЧрднрдЧ рдирд╣реАрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣рд╛рдБ рд╣реИ рдЖрдкрдХреЛ рдХреНрдпрд╛ рдХрд░рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдиреНрдпреВрдЧреЗрдЯ рдкреИрдХреЗрдЬ рдЬреЛрдбрд╝рдиреЗ рд╣реЛрдВрдЧреЗред Grpc.Tools рдкреИрдХреЗрдЬ рдЖрдкрдХреЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рддреЗ рд╕рдордп рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдмрдирд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛, рдФрд░ Grpc.Net.ClientFactory рдЖрдкрдХреЛ DI рд╕реЗрдЯ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред рдЬреАрдЖрд░рдкреАрд╕реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп, рдпрджрд┐ рдЖрдкрдХреЛ рдЕрдиреБрд░реЛрдз-рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рдмреАрдЪ рдореЗрдВ рдХрд╣реАрдВ рдЕрдкрдирд╛ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯрд░ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рд╡рд░реНрдЧреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ , рдЬреЛ рдХрд┐ рдЬреАрдЖрд░рдкреАрдХреЛрд░ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ ред рдпрджрд┐ рдЖрдкрдХреЛ рдЕрдкрдиреА рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рдЕрдВрджрд░ HttpContext.User.Identity рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ , рддреЛ рдЖрдк IHttpContextAccessor рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ

dotnet add package Grpc.Net.Client
dotnet add package Google.Protobuf
dotnet add package Grpc.Tools
dotnet add package Grpc.Net.ClientFactory



рдЖрдкрдХреА рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП (рдЗрд╕рдХреЗ рд▓рд┐рдП рд╕реЗрд╡рд╛рдУрдВ рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рдкрдВрдЬреАрдХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ)ред рдЖрдкрдХреЛ рдЕрдкрдиреА рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдирд┐рдореНрди рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред

services.AddTransient<AuthHeadersInterceptor>();
services.AddHttpContextAccessor();

var httpClientBuilder = services.AddGrpcClient<MygRpcService.MygRpcServiceClient>(o => { o.Address = new Uri("grpc-endpoint-url"); });
httpClientBuilder.AddInterceptor<AuthHeadersInterceptor>();              
httpClientBuilder.ConfigureChannel(o => o.Credentials = ChannelCredentials.Insecure);

AuthHeadersInterceptor рд╡рд░реНрдЧ рд╣рдорд╛рд░рд╛ рдЕрдкрдирд╛ рд╡рд░реНрдЧ рд╣реИ, рдЬреЛ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯрд░ рд╡рд░реНрдЧ рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ред рдпрд╣ IHttpContextAccessor рдФрд░ registering .AddHttpContextAccessor () рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ ред

HTTP рдХреЗ рд▓рд┐рдП рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕реБрд╡рд┐рдзрд╛рдПрдБ


рдЖрдк рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд┐рдиреНрдпрд╛рд╕ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ:

httpClientBuilder.ConfigureChannel(o => o.Credentials = ChannelCredentials.Insecure);

рдпрд╣ HTTP рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИред рдЖрдкрдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ () рд╡рд┐рдзрд┐ рд╕реЗ рдЗрд╕ рдкрдВрдХреНрддрд┐ рдХреЛ рдмрд╛рд╣рд░ рдХрд░рдиреЗ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

app.UseHttpsRedirection();

рдФрд░ рдлрд┐рд░ рднреА рдЖрдкрдХреЛ рдХрд┐рд╕реА рднреА gRpc рдЪреИрдирд▓ рдХреЛ рдмрдирд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╕реЗрдЯрд┐рдВрдЧ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдиреГрддреНрдп рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ред рдпрд╣ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓реЙрдиреНрдЪ рдХреЗ рджреМрд░рд╛рди рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдореИрдВрдиреЗ рдЗрд╕реЗ рд▓рдЧрднрдЧ рдЙрд╕реА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рдЙрд▓реНрд▓рд┐рдЦрд┐рдд рдбрд┐рд▓реАрдЯ рд▓рд╛рдЗрди рд╣реИред рдЗрд╕реЗ рдХреЗрд╡рд▓ HTTP рдХреЗ рд▓рд┐рдП рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

HTTPS рдХреЗ рд▓рд┐рдП рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕реБрд╡рд┐рдзрд╛рдПрдБ


рд╡рд┐рдВрдбреЛрдЬ рдФрд░ рд▓рд┐рдирдХреНрд╕ рдкрд░ рдПрд╕рдПрд╕рдПрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рдХреБрдЫ рдХрдард┐рдирд╛рдЗрдпрд╛рдВ рд╣реИрдВред рдРрд╕рд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рд╡рд┐рдВрдбреЛрдЬ рдХрдВрдкреНрдпреВрдЯрд░ рдкрд░ рд╡рд┐рдХрд╕рд┐рдд рд╣реЛрдВ рдФрд░ рд▓рд┐рдирдХреНрд╕-рдЖрдзрд╛рд░рд┐рдд рдЫрд╡рд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбреЙрдХрдЯрд░ / рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдореЗрдВ рддреИрдирд╛рдд рд╣реЛрдВред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХрдИ рдкреЛрд╕реНрдЯреНрд╕ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╕рд░рд▓ рдирд╣реАрдВ рд╣реИред рдореИрдВ рдПрдХ рдЕрдиреНрдп рд▓реЗрдЦ рдореЗрдВ рдЗрд╕ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛, рдФрд░ рдпрд╣рд╛рдВ рдореИрдВ рдХреЗрд╡рд▓ рдХреЛрдб рдкрд░ рд╕реНрдкрд░реНрд╢ рдХрд░реВрдВрдЧрд╛ред

рд╣рдореЗрдВ SSL рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП gRpc рдЪреИрдирд▓ рдХреЛ рдлрд┐рд░ рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдпрджрд┐ рдЖрдк рдбреЙрдХрд░ рдореЗрдВ рддреИрдирд╛рдд рд╣реИрдВ рдФрд░ рд▓рд┐рдирдХреНрд╕-рдЖрдзрд╛рд░рд┐рдд рдЪрд┐рддреНрд░ рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдЕрдорд╛рдиреНрдп рдкреНрд░рдорд╛рдгрдкрддреНрд░реЛрдВ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП HttpClient рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рдкрдбрд╝ рд╕рдХрддрд╛ рд╣реИред HttpClient рдкреНрд░рддреНрдпреЗрдХ рдЪреИрдирд▓ рдХреЗ рд▓рд┐рдП рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред

httpClientBuilder.ConfigureChannel(o =>
{
    // add SSL credentials
    o.Credentials = new SslCredentials();
    // allow invalid/untrusted certificates
    var httpClientHandler = new HttpClientHandler
    {
        ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
    };
    var httpClient = new HttpClient(httpClientHandler);
    o.HttpClient = httpClient;
});

HTTP рд╣реЗрдбрд░ рдЬреЛрдбрд╝рдирд╛


рд╣реЗрдбрд░реНрд╕ рдХреЛ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯрд░ рдХреНрд▓рд╛рд╕ ( рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯрд░ рд╕реЗ рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░реА ) рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ ред gRpc рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рд╣реЗрдбрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд╕рд╛рде рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯрд░ рд╡рд░реНрдЧ рдХреЛ рдХреЙрд▓ рд╕рдВрджрд░реНрдн рдХреЗ рд▓рд┐рдП рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рд┐рдПред

public class AuthHeadersInterceptor : Interceptor
{
    public AuthHeadersInterceptor(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }
    
    public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
    {
        var metadata = new Metadata
        {
            {HttpHeaderNames.Authorization, $"Bearer <JWT_TOKEN>"}
        };
        var userIdentity = _httpContextAccessor.HttpContext.User.Identity;
        if (userIdentity.IsAuthenticated)
        {
            metadata.Add(HttpHeaderNames.User, userIdentity.Name);
        }
        var callOption = context.Options.WithHeaders(metadata);
        context = new ClientInterceptorContext<TRequest, TResponse>(context.Method, context.Host, callOption);
        
        return base.AsyncUnaryCall(request, context, continuation);
    }
}

рдкрд░рд┐рджреГрд╢реНрдп рдХреЗ рд▓рд┐рдП, рдЬрдм рдЖрдк рд╕рд┐рд░реНрдл gRpc рд╕реЗрд╡рд╛ рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдХреЗрд╡рд▓ AsyncUnaryCall рдкрджреНрдзрддрд┐ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдирд╛ рд╣реЛрдЧрд╛ ред рдмреЗрд╢рдХ, JWT рдЯреЛрдХрди рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рд╕рд╣реЗрдЬрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдФрд░ рдпрд╣ рд╕рдм рд╣реИред рдмрд╛рдж рдореЗрдВ рдореИрдВ рд╡рд░реНрдгрд┐рдд рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдХреЗ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдХреЛрдб рдореЗрдВ рдПрдХ рд▓рд┐рдВрдХ рдЬреЛрдбрд╝реВрдВрдЧрд╛ред рдпрджрд┐ рдЖрдкрдХреЗ рдХреЛрдИ рдФрд░ рдкреНрд░рд╢реНрди рд╣реИрдВ, рддреЛ рдХреГрдкрдпрд╛ рдореБрдЭреЗ рд▓рд┐рдЦреЗрдВред рдореИрдВ рдЬрд╡рд╛рдм рджреЗрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ред

All Articles