Skip to content

Commit e688fad

Browse files
authored
Merge pull request #295
* New basic js sample voor BFF v4 * Update NuGet packages
1 parent 6a793fd commit e688fad

44 files changed

Lines changed: 1845 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"version": "0.2.0",
3+
"compounds": [
4+
{
5+
"name": "Run All",
6+
"configurations": ["BFF", "API"],
7+
"presentation": {
8+
"hidden": false,
9+
"group": "",
10+
"order": 1
11+
}
12+
}
13+
],
14+
"configurations": [
15+
{
16+
"name": "API",
17+
"type": "coreclr",
18+
"request": "launch",
19+
"preLaunchTask": "build-api",
20+
"program": "${workspaceFolder}/BackendApiHost/bin/Debug/net8.0/BackendApiHost.dll",
21+
"args": [],
22+
"cwd": "${workspaceFolder}/BackendApiHost",
23+
"env": {
24+
"ASPNETCORE_ENVIRONMENT": "Development"
25+
},
26+
"console": "externalTerminal",
27+
},
28+
{
29+
"name": "BFF",
30+
"type": "coreclr",
31+
"request": "launch",
32+
"preLaunchTask": "build-bff",
33+
"program": "${workspaceFolder}/FrontendHost/bin/Debug/net8.0/FrontendHost.dll",
34+
"args": [],
35+
"cwd": "${workspaceFolder}/FrontendHost",
36+
"env": {
37+
"ASPNETCORE_ENVIRONMENT": "Development"
38+
},
39+
"serverReadyAction": {
40+
"action": "openExternally",
41+
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
42+
},
43+
"console": "externalTerminal",
44+
}
45+
]
46+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"label": "build",
6+
"type": "process",
7+
"command": "dotnet",
8+
"args": [
9+
"build",
10+
"${workspaceFolder}/JsBffSample.sln",
11+
"/property:GenerateFullPaths=true",
12+
"/consoleloggerparameters:NoSummary"
13+
],
14+
"problemMatcher": "$msCompile"
15+
},
16+
{
17+
"label": "build-api",
18+
"type": "process",
19+
"command": "dotnet",
20+
"args": [
21+
"build",
22+
"${workspaceFolder}\\BackendApiHost\\BackendApiHost.csproj",
23+
"/property:GenerateFullPaths=true",
24+
"/consoleloggerparameters:NoSummary"
25+
],
26+
"problemMatcher": "$msCompile"
27+
},
28+
{
29+
"label": "build-bff",
30+
"type": "process",
31+
"command": "dotnet",
32+
"args": [
33+
"build",
34+
"${workspaceFolder}\\FrontendHost\\FrontendHost.csproj",
35+
36+
"/property:GenerateFullPaths=true",
37+
"/consoleloggerparameters:NoSummary"
38+
],
39+
"problemMatcher": "$msCompile"
40+
}
41+
]
42+
43+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net10.0</TargetFramework>
5+
<ImplicitUsings>true</ImplicitUsings>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.2" />
10+
</ItemGroup>
11+
12+
</Project>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (c) Duende Software. All rights reserved.
2+
// Licensed under the MIT License. See LICENSE in the project root for license information.
3+
4+
var builder = WebApplication.CreateBuilder(args);
5+
6+
builder.Services.AddControllers();
7+
8+
builder.Services.AddAuthentication("token")
9+
.AddJwtBearer("token", options =>
10+
{
11+
options.Authority = "https://demo.duendesoftware.com";
12+
options.Audience = "api";
13+
14+
options.MapInboundClaims = false;
15+
});
16+
17+
builder.Services.AddAuthorization(options =>
18+
{
19+
options.AddPolicy("ApiCaller", policy =>
20+
{
21+
policy.RequireClaim("scope", "api");
22+
});
23+
24+
options.AddPolicy("RequireInteractiveUser", policy =>
25+
{
26+
policy.RequireClaim("sub");
27+
});
28+
});
29+
30+
var app = builder.Build();
31+
32+
app.UseRouting();
33+
34+
app.UseAuthentication();
35+
app.UseAuthorization();
36+
37+
app.MapControllers().RequireAuthorization("ApiCaller");
38+
39+
app.Run();
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"iisSettings": {
3+
"windowsAuthentication": false,
4+
"anonymousAuthentication": true,
5+
"iisExpress": {
6+
"applicationUrl": "http://localhost:25721",
7+
"sslPort": 44337
8+
}
9+
},
10+
"profiles": {
11+
"BackendApiHost": {
12+
"commandName": "Project",
13+
"environmentVariables": {
14+
"ASPNETCORE_ENVIRONMENT": "Development"
15+
},
16+
"applicationUrl": "https://localhost:5020"
17+
}
18+
}
19+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Copyright (c) Duende Software. All rights reserved.
2+
// Licensed under the MIT License. See LICENSE in the project root for license information.
3+
4+
using Microsoft.AspNetCore.Authorization;
5+
using Microsoft.AspNetCore.Mvc;
6+
7+
namespace BackendApiHost;
8+
9+
[Authorize("RequireInteractiveUser")]
10+
public class ToDoController : ControllerBase
11+
{
12+
private readonly ILogger<ToDoController> _logger;
13+
14+
private static readonly List<ToDo> __data = new List<ToDo>()
15+
{
16+
new ToDo { Id = ToDo.NewId(), Date = DateTimeOffset.UtcNow, Name = "Demo ToDo API", User = "bob" },
17+
new ToDo { Id = ToDo.NewId(), Date = DateTimeOffset.UtcNow.AddHours(1), Name = "Stop Demo", User = "bob" },
18+
new ToDo { Id = ToDo.NewId(), Date = DateTimeOffset.UtcNow.AddHours(4), Name = "Have Dinner", User = "alice" },
19+
};
20+
21+
public ToDoController(ILogger<ToDoController> logger)
22+
{
23+
_logger = logger;
24+
}
25+
26+
[HttpGet("todos")]
27+
public IActionResult GetAll()
28+
{
29+
_logger.LogInformation("GetAll");
30+
31+
return Ok(__data.AsEnumerable());
32+
}
33+
34+
[HttpGet("todos/{id}")]
35+
public IActionResult Get(int id)
36+
{
37+
var item = __data.FirstOrDefault(x => x.Id == id);
38+
if (item == null) return NotFound();
39+
40+
_logger.LogInformation("Get {id}", id);
41+
return Ok(item);
42+
}
43+
44+
[HttpPost("todos")]
45+
public IActionResult Post([FromBody] ToDo model)
46+
{
47+
model.Id = ToDo.NewId();
48+
model.User = $"{User.FindFirst("sub").Value} ({User.FindFirst("name").Value})";
49+
50+
__data.Add(model);
51+
_logger.LogInformation("Added todo");
52+
53+
return Created(Url.Action(nameof(Get), new { id = model.Id }), model);
54+
}
55+
56+
[HttpPut("todos/{id}")]
57+
public IActionResult Put(int id, [FromBody] ToDo model)
58+
{
59+
var item = __data.FirstOrDefault(x => x.Id == id);
60+
if (item == null) return NotFound();
61+
62+
item.Date = model.Date;
63+
item.Name = model.Name;
64+
65+
_logger.LogInformation("Updated todo");
66+
67+
return NoContent();
68+
}
69+
70+
[HttpDelete("todos/{id}")]
71+
public IActionResult Delete(int id)
72+
{
73+
var item = __data.FirstOrDefault(x => x.Id == id);
74+
if (item == null) return NotFound();
75+
76+
__data.Remove(item);
77+
_logger.LogInformation("Delete {id}", id);
78+
79+
return NoContent();
80+
}
81+
}
82+
83+
public class ToDo
84+
{
85+
static int _nextId = 1;
86+
public static int NewId()
87+
{
88+
return _nextId++;
89+
}
90+
91+
public int Id { get; set; }
92+
public DateTimeOffset Date { get; set; }
93+
public string Name { get; set; }
94+
public string User { get; set; }
95+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net10.0</TargetFramework>
5+
<ImplicitUsings>true</ImplicitUsings>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="Duende.BFF" Version="4.0.2" />
10+
<PackageReference Include="Duende.BFF.Yarp" Version="4.0.2" />
11+
12+
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="10.0.2" />
13+
</ItemGroup>
14+
15+
</Project>
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright (c) Duende Software. All rights reserved.
2+
// Licensed under the MIT License. See LICENSE in the project root for license information.
3+
4+
using Duende.AccessTokenManagement.OpenIdConnect;
5+
using Duende.Bff;
6+
using Duende.Bff.DynamicFrontends;
7+
using Duende.Bff.Yarp;
8+
9+
var builder = WebApplication.CreateBuilder(args);
10+
11+
builder.Services.AddControllers();
12+
13+
builder.Services.AddBff()
14+
.AddRemoteApis()
15+
.ConfigureOpenIdConnect(options =>
16+
{
17+
options.Authority = "https://demo.duendesoftware.com";
18+
options.ClientId = "interactive.confidential";
19+
options.ClientSecret = "secret";
20+
options.ResponseType = "code";
21+
options.ResponseMode = "query";
22+
23+
options.GetClaimsFromUserInfoEndpoint = true;
24+
options.MapInboundClaims = false;
25+
options.SaveTokens = true;
26+
options.DisableTelemetry = true;
27+
28+
options.Scope.Clear();
29+
options.Scope.Add("openid");
30+
options.Scope.Add("profile");
31+
options.Scope.Add("api");
32+
options.Scope.Add("offline_access");
33+
34+
options.TokenValidationParameters = new()
35+
{
36+
NameClaimType = "name",
37+
RoleClaimType = "role"
38+
};
39+
})
40+
.ConfigureCookies(options =>
41+
{
42+
options.Cookie.Name = "__Host-bff";
43+
options.Cookie.SameSite = SameSiteMode.Strict;
44+
});
45+
46+
builder.Services.AddAuthentication(options =>
47+
{
48+
options.DefaultScheme = BffAuthenticationSchemes.BffCookie;
49+
options.DefaultChallengeScheme = BffAuthenticationSchemes.BffOpenIdConnect;
50+
options.DefaultSignOutScheme = BffAuthenticationSchemes.BffOpenIdConnect;
51+
});
52+
53+
// registers HTTP client that uses the managed user access token
54+
builder.Services.AddUserAccessTokenHttpClient("api_client", configureClient: client =>
55+
{
56+
client.BaseAddress = new Uri("https://localhost:5002/");
57+
});
58+
59+
var app = builder.Build();
60+
61+
app.UseDefaultFiles();
62+
app.UseStaticFiles();
63+
64+
app.UseRouting();
65+
66+
app.UseAuthentication();
67+
app.UseBff();
68+
app.UseAuthorization();
69+
70+
app.MapBffManagementEndpoints();
71+
72+
// if you want the TODOs API local
73+
app.MapControllers()
74+
.RequireAuthorization()
75+
.AsBffApiEndpoint();
76+
77+
// if you want the TODOs API remote
78+
// app.MapRemoteBffApiEndpoint("/todos", "https://localhost:5020/todos")
79+
// .RequireAccessToken(Duende.Bff.TokenType.User);
80+
81+
app.Run();
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"iisSettings": {
3+
"windowsAuthentication": false,
4+
"anonymousAuthentication": true,
5+
"iisExpress": {
6+
"applicationUrl": "http://localhost:32659",
7+
"sslPort": 44348
8+
}
9+
},
10+
"profiles": {
11+
"JsBffSample": {
12+
"commandName": "Project",
13+
"launchBrowser": true,
14+
"environmentVariables": {
15+
"ASPNETCORE_ENVIRONMENT": "Development"
16+
},
17+
"applicationUrl": "https://localhost:5010"
18+
}
19+
}
20+
}

0 commit comments

Comments
 (0)