Skip to content

Commit

Permalink
Add authentication for gRPC
Browse files Browse the repository at this point in the history
  • Loading branch information
rstropek committed Nov 21, 2020
1 parent 671943c commit b519424
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
using System.Linq;
using NetCoreMicroserviceSample.Api.Dto;
using NetCoreMicroserviceSample.MachineService;
using System.Net.Http;
using Microsoft.Extensions.Configuration;
using System.Net.Http.Json;
using System.Text.Json.Serialization;
using Grpc.Core;

namespace NetCoreMicroserviceSample.Api.Controllers
{
Expand All @@ -18,11 +23,16 @@ public class MachineController : ControllerBase
{
private readonly MachineVisualizerDataContext dbContext;
private readonly MachineAccess.MachineAccessClient machineClient;
private readonly IHttpClientFactory clientFactory;
private readonly IConfiguration configuration;

public MachineController(MachineVisualizerDataContext dbContext, MachineAccess.MachineAccessClient machineClient)
public MachineController(MachineVisualizerDataContext dbContext, MachineAccess.MachineAccessClient machineClient,
IHttpClientFactory clientFactory, IConfiguration configuration)
{
this.dbContext = dbContext;
this.machineClient = machineClient;
this.clientFactory = clientFactory;
this.configuration = configuration;
}

[HttpGet(Name = "GetAllMachines")]
Expand Down Expand Up @@ -122,13 +132,36 @@ public async Task<IActionResult> GetSwitchesAsync(Guid id)
return Ok(switches);
}

private class OidcAccessToken
{
[JsonPropertyName("access_token")]
public string AccessToken { get; set; } = string.Empty;
}

[HttpPut("{id}/settings", Name = "UpdateMachineSettings")]
[ProducesResponseType((int)HttpStatusCode.OK)]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task<IActionResult> PutSettingsAsync(Guid id, [FromBody] MachineSettingsUpdateDto[] settings)
{
var existingSettings = await dbContext.MachineSettings.Where(s => s.MachineId == id).ToListAsync();

var client = clientFactory.CreateClient("identity-server");
var formDictionary = new Dictionary<string, string>
{
{ "grant_type", "client_credentials" },
{ "client_id", configuration["Oidc:MachineClientId"] },
{ "client_secret", configuration["Oidc:MachineClientSecret"] },
{ "audience", "api" }
};
using var formContent = new FormUrlEncodedContent(formDictionary!);
var response = await client.PostAsync(new Uri($"{configuration["Oidc:Domain"]}/connect/token"), formContent);
var token = await response.Content.ReadFromJsonAsync<OidcAccessToken>();

var headers = new Metadata
{
{ "Authorization", $"Bearer {token!.AccessToken}" }
};

foreach (var settingToWrite in settings)
{
var settingToUpdateInDb = existingSettings.Single(s => s.Id == settingToWrite.Id);
Expand All @@ -139,7 +172,7 @@ await machineClient.UpdateSettingsAsync(new MachineSettingsUpdate
MachineId = id.ToString(),
SettingId = settingToWrite.Id.ToString(),
Value = settingToWrite.value
});
}, headers);
}

await dbContext.SaveChangesAsync();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ public void ConfigureServices(IServiceCollection services)
options.MinimumSameSitePolicy = SameSiteMode.None;
});

services.AddHttpClient("identity-server", c =>
{
c.BaseAddress = new Uri(Configuration["Oidc:Domain"]);
});

// Add authentication services
services.AddAuthentication(options =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
"Oidc": {
"Domain": "https://demo.identityserver.io",
"ClientId": "interactive.confidential",
"ClientSecret": "secret"
"ClientSecret": "secret",
"MachineClientId": "m2m",
"MachineClientSecret": "secret"
},
"AllowedHosts": "*"
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
using Google.Protobuf.Collections;
using Grpc.Core;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Logging;
using NetCoreMicroserviceSample.MachineService;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using static NetCoreMicroserviceSample.MachineService.MachineAccess;

namespace NetCoreMicroserviceSample.Machine
{
[Authorize]
public class MachineService : MachineAccessBase
{
private readonly ILogger<MachineService> logger;
Expand All @@ -23,6 +26,9 @@ public MachineService(ILogger<MachineService> logger)

public override Task<MachineResponse> UpdateSettings(MachineSettingsUpdate request, ServerCallContext context)
{
var user = context.GetHttpContext().User;
logger.LogInformation($"Got request from client {user.Claims.Single(c => c.Type == "client_id")}");

Console.WriteLine($"Updating setting {request.SettingId} for Machine {request.MachineId}: {request.Value:F2}");
return Task.FromResult(new MachineResponse() { ResultCode = 1 });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.33.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
Expand All @@ -6,9 +7,11 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;

namespace NetCoreMicroserviceSample.Machine
Expand All @@ -25,6 +28,20 @@ public Startup(IConfiguration configuration)
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
string domain = $"{Configuration["Oidc:Domain"]}";
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = domain;
options.Audience = Configuration["Oidc:Audience"];
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = ClaimTypes.NameIdentifier
};
});
services.AddAuthorization();

services.AddGrpc();
}

Expand All @@ -40,6 +57,9 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

app.UseRouting();

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

app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<MachineService>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
{
"Logging": {
"LogLevel": {
"Default": "Error",
"Microsoft": "Error",
"Microsoft.Hosting.Lifetime": "Error"
}
},
"AllowedHosts": "*"
"Logging": {
"LogLevel": {
"Default": "Error",
"Microsoft": "Error",
"Microsoft.Hosting.Lifetime": "Error"
}
},
"Oidc": {
"Domain": "https://demo.identityserver.io",
"Audience": "api",
"ClientId": "interactive.confidential",
"ClientSecret": "secret"
},
"AllowedHosts": "*"
}
10 changes: 8 additions & 2 deletions NetCoreMicroserviceSample/requests.http
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,11 @@ Content-Type: application/json
}

###
https://demo.identityserver.io/connect/userinfo
Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IkVCQTRGRDNDRUExMDREOTlBODkwODkyNEJBMjNDMEYwIiwidHlwIjoiYXQrand0In0.eyJuYmYiOjE2MDU4NTQ4MDksImV4cCI6MTYwNTg1ODQwOSwiaXNzIjoiaHR0cHM6Ly9kZW1vLmlkZW50aXR5c2VydmVyLmlvIiwiY2xpZW50X2lkIjoiaW50ZXJhY3RpdmUuY29uZmlkZW50aWFsIiwic3ViIjoiMTEiLCJhdXRoX3RpbWUiOjE2MDU4NTM2NzIsImlkcCI6ImxvY2FsIiwianRpIjoiNEY4NTkxODA2RUIzRTNBRUJDQkMzMDE1NkVBMTc1OTYiLCJzaWQiOiI5REFGNjE1MkYxQUFDNEY5MkNCMjBBQTJCNEU0Mjk0MiIsImlhdCI6MTYwNTg1NDgwOSwic2NvcGUiOlsib3BlbmlkIiwicHJvZmlsZSIsImVtYWlsIl0sImFtciI6WyJwd2QiXX0.wxmY3XvAsnDY2n5Jm7dpF3OpvF63MDaARkXrLfn5yNMk4EPRaP8L51Rdu7G34lGdu0Gp-g81PbnmWKssVujlTnSuOJL0GKxMpK1sc8TVBv2maOiyXiGMp5Qfs2vZQG9OiNtpuP-mlCzX0XZFlgoSq2jOs6_OvOPU2jT_JlYSRu9wyPKzaXjLvluRj-N_RVvF7isHzAO2eqGwHPw7mDm4k-PybLywbiRJddDjFPazCXzRkoeltDN3AHU3XGYRsQQ88F0dyIaF6dI2ox4PMYh0mnxzHBoKjeBaV3iTptAm4TCekT0av4kBUodCOhRUQ7g8SBiQ11awFHoCntiN2jmdgg
GET https://demo.identityserver.io/connect/userinfo
Authorization: Bearer ...

###
POST https://demo.identityserver.io/connect/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&MachineClientId=m2m&client_secret=secret&audience=api

0 comments on commit b519424

Please sign in to comment.