@@ -1251,10 +1251,73 @@ For additional information, see the updated [Security documentation](../security
1251
1251
The CredHub client has been removed from Steeltoe in v4.
1252
1252
Use [ CredHub Service Broker] ( https://techdocs.broadcom.com/us/en/vmware-tanzu/platform-services/credhub-service-broker/services/credhub-sb/index.html ) instead.
1253
1253
1254
- ### OAuth and OpenID Connect
1254
+ ### OAuth
1255
1255
1256
1256
OAuth support has been removed from Steeltoe in v4. Use OpenID Connect instead.
1257
1257
1258
+ Consider migrating to OpenID Connect on Steeltoe v3 before moving to v4.
1259
+
1260
+ appsettings.json:
1261
+
1262
+ ``` diff
1263
+ {
1264
+ "$schema": "https://steeltoe.io/schema/v3/schema.json",
1265
+ "Security": {
1266
+ "Oauth2": {
1267
+ "Client": {
1268
+ - "AuthDomain": "http://localhost:8080",
1269
+ + "Authority": "http://localhost:8080/uaa",
1270
+ "CallbackPath": "/signin-oidc",
1271
+ "ClientId": "steeltoesamplesclient",
1272
+ "ClientSecret": "client_secret"
1273
+ + "MetadataAddress": "http://localhost:8080/.well-known/openid-configuration",
1274
+ + "RequireHttpsMetadata": false
1275
+ + "AdditionalScopes": "sampleapi.read"
1276
+ }
1277
+ }
1278
+ }
1279
+ }
1280
+ ```
1281
+
1282
+ > [ !NOTE]
1283
+ > Depending on your application's needs, you may need to add scopes to the application's configuration that did not previously need to be specified.
1284
+
1285
+ program.cs:
1286
+
1287
+ ``` diff
1288
+ using Microsoft.AspNetCore.Authentication.Cookies;
1289
+ using Microsoft.AspNetCore.HttpOverrides;
1290
+ using Steeltoe.Extensions.Configuration.CloudFoundry;
1291
+ using Steeltoe.Security.Authentication.CloudFoundry;
1292
+
1293
+ var builder = WebApplication.CreateBuilder(args);
1294
+ builder.AddCloudFoundryConfiguration();
1295
+ builder.Services.AddAuthentication(options =>
1296
+ {
1297
+ options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
1298
+ options.DefaultChallengeScheme = CloudFoundryDefaults.AuthenticationScheme;
1299
+ })
1300
+ .AddCookie(options => options.AccessDeniedPath = new PathString("/Home/AccessDenied"))
1301
+ - .AddCloudFoundryOAuth(builder.Configuration);
1302
+ + .AddCloudFoundryOpenIdConnect(builder.Configuration);
1303
+ builder.Services.AddAuthorizationBuilder()
1304
+ .AddPolicy("read", policy => policy.RequireClaim("scope", "sampleapi.read"))
1305
+ .AddPolicy("write", policy => policy.RequireClaim("scope", "sampleapi.write"));
1306
+
1307
+ var app = builder.Build();
1308
+
1309
+ app.UseForwardedHeaders(new ForwardedHeadersOptions
1310
+ {
1311
+ ForwardedHeaders = ForwardedHeaders.XForwardedProto
1312
+ });
1313
+
1314
+ app.UseAuthentication();
1315
+ app.UseAuthorization();
1316
+
1317
+ ```
1318
+
1319
+ ### OpenID Connect
1320
+
1258
1321
Project file:
1259
1322
1260
1323
``` diff
@@ -1271,7 +1334,9 @@ Project file:
1271
1334
appsettings.json:
1272
1335
1273
1336
``` diff
1337
+ {
1274
1338
- "$schema": "https://steeltoe.io/schema/v3/schema.json",
1339
+ + "$schema": "https://steeltoe.io/schema/v4/schema.json",
1275
1340
- "Security": {
1276
1341
- "Oauth2": {
1277
1342
- "Client": {
@@ -1280,7 +1345,7 @@ appsettings.json:
1280
1345
- "ClientId": "steeltoesamplesclient",
1281
1346
- "ClientSecret": "client_secret",
1282
1347
- "MetadataAddress": "http://localhost:8080/.well-known/openid-configuration",
1283
- - "AdditionalScopes": "profile sampleapi.read",
1348
+ - "AdditionalScopes": "sampleapi.read",
1284
1349
- "SaveTokens": true,
1285
1350
- "RequireHttpsMetadata": false
1286
1351
- }
@@ -1300,6 +1365,7 @@ appsettings.json:
1300
1365
+ }
1301
1366
+ }
1302
1367
+ }
1368
+ }
1303
1369
```
1304
1370
1305
1371
> [ !NOTE]
@@ -1310,27 +1376,29 @@ Program.cs:
1310
1376
1311
1377
``` diff
1312
1378
using Microsoft.AspNetCore.Authentication.Cookies;
1313
- + using Microsoft.AspNetCore.Authentication.OpenIdConnect;
1314
1379
- using Microsoft.AspNetCore.HttpOverrides;
1315
- - using Microsoft.Extensions.Options;
1316
1380
- using Steeltoe.Extensions.Configuration.CloudFoundry;
1317
1381
+ using Steeltoe.Configuration.CloudFoundry;
1382
+ + using Steeltoe.Configuration.CloudFoundry.ServiceBindings;
1318
1383
- using Steeltoe.Security.Authentication.CloudFoundry;
1384
+ + using Microsoft.AspNetCore.Authentication.OpenIdConnect;
1319
1385
+ using Steeltoe.Security.Authentication.OpenIdConnect;
1320
1386
1321
1387
var builder = WebApplication.CreateBuilder(args);
1322
1388
builder.AddCloudFoundryConfiguration();
1323
- builder.Services.AddAuthentication((options) =>
1324
- {
1325
- options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
1326
- - options.DefaultChallengeScheme = CloudFoundryDefaults.AuthenticationScheme;
1327
- + options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
1328
- })
1389
+ + builder.Configuration.AddCloudFoundryServiceBindings();
1390
+ builder.Services.AddAuthentication(options =>
1391
+ {
1392
+ options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
1393
+ - options.DefaultChallengeScheme = CloudFoundryDefaults.AuthenticationScheme;
1394
+ + options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
1395
+ })
1329
1396
.AddCookie(options => options.AccessDeniedPath = new PathString("/Home/AccessDenied"))
1330
1397
- .AddCloudFoundryOpenIdConnect(builder.Configuration);
1331
1398
+ .AddOpenIdConnect().ConfigureOpenIdConnectForCloudFoundry();
1332
1399
builder.Services.AddAuthorizationBuilder()
1333
- .AddPolicy("some-group", policy => policy.RequireClaim("scope", "some-group"));
1400
+ .AddPolicy("read", policy => policy.RequireClaim("scope", "sampleapi.read"))
1401
+ .AddPolicy("write", policy => policy.RequireClaim("scope", "sampleapi.write"));
1334
1402
1335
1403
var app = builder.Build();
1336
1404
@@ -1343,9 +1411,6 @@ app.UseAuthentication();
1343
1411
app.UseAuthorization();
1344
1412
```
1345
1413
1346
- > [ !NOTE]
1347
- > Use the code above for applications that previously used ` .AddCloudFoundryOAuth(builder.Configuration); ` .
1348
-
1349
1414
### JWT Bearer
1350
1415
1351
1416
Project file:
@@ -1364,11 +1429,13 @@ Project file:
1364
1429
appsettings.json:
1365
1430
1366
1431
``` diff
1432
+ {
1367
1433
- "$schema": "https://steeltoe.io/schema/v3/schema.json",
1434
+ + "$schema": "https://steeltoe.io/schema/v4/schema.json",
1368
1435
- "Security": {
1369
1436
- "Oauth2": {
1370
1437
- "Client": {
1371
- - "AuthDomain": "http://localhost:8080/uaa ",
1438
+ - "AuthDomain": "http://localhost:8080",
1372
1439
- "ClientId": "steeltoesamplesserver",
1373
1440
- "ClientSecret": "server_secret",
1374
1441
- "JwtKeyUrl": "http://localhost:8080/token_keys",
@@ -1380,12 +1447,16 @@ appsettings.json:
1380
1447
+ "Authentication": {
1381
1448
+ "Schemes": {
1382
1449
+ "Bearer": {
1383
- + "Authority": "http://localhost:8080/uaa ",
1450
+ + "Authority": "http://localhost:8080",
1384
1451
+ "ClientId": "steeltoesamplesserver",
1385
1452
+ "ClientSecret": "server_secret",
1453
+ + "MetadataAddress": "http://localhost:8080/.well-known/openid-configuration",
1454
+ + "RequireHttpsMetadata": false,
1455
+ + "ValidAudiences": [ "sampleapi" ]
1386
1456
+ }
1387
1457
+ }
1388
1458
+ }
1459
+ }
1389
1460
```
1390
1461
1391
1462
> [ !NOTE]
@@ -1395,22 +1466,23 @@ appsettings.json:
1395
1466
Program.cs:
1396
1467
1397
1468
``` diff
1398
- using Microsoft.AspNetCore.Authentication.JwtBearer;
1399
1469
- using Microsoft.AspNetCore.HttpOverrides;
1400
1470
- using Steeltoe.Extensions.Configuration.CloudFoundry;
1401
1471
+ using Steeltoe.Configuration.CloudFoundry;
1472
+ + using Steeltoe.Configuration.CloudFoundry.ServiceBindings;
1402
1473
- using Steeltoe.Security.Authentication.CloudFoundry;
1403
1474
+ using Steeltoe.Security.Authentication.JwtBearer;
1404
1475
1405
1476
var builder = WebApplication.CreateBuilder(args);
1406
1477
1407
1478
builder.AddCloudFoundryConfiguration();
1479
+ + builder.Configuration.AddCloudFoundryServiceBindings();
1408
1480
1409
- builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme )
1481
+ builder.Services.AddAuthentication()
1410
1482
- .AddCloudFoundryJwtBearer(builder.Configuration);
1411
1483
+ .AddJwtBearer().ConfigureJwtBearerForCloudFoundry();
1412
1484
builder.Services.AddAuthorizationBuilder()
1413
- .AddPolicy("some-group ", policy => policy.RequireClaim("scope", "some-group "));
1485
+ .AddPolicy("sampleapi.read ", policy => policy.RequireClaim("scope", "sampleapi.read "));
1414
1486
1415
1487
var app = builder.Build();
1416
1488
@@ -1421,6 +1493,14 @@ var app = builder.Build();
1421
1493
1422
1494
app.UseAuthentication();
1423
1495
app.UseAuthorization();
1496
+
1497
+ app.MapGet("/jwt", async httpContext =>
1498
+ {
1499
+ httpContext.Response.StatusCode = 200;
1500
+ httpContext.Response.ContentType = "text/plain";
1501
+ await httpContext.Response.WriteAsync("JWT is valid and contains the required claim");
1502
+ }).RequireAuthorization("sampleapi.read");
1503
+ app.Run();
1424
1504
```
1425
1505
1426
1506
### Client Certificates (Mutual TLS)
@@ -1443,42 +1523,39 @@ Program.cs (server-side):
1443
1523
- using Steeltoe.Security.Authentication.CloudFoundry;
1444
1524
+ using Steeltoe.Security.Authorization.Certificate;
1445
1525
1526
+ const string orgId = "a8fef16f-94c0-49e3-aa0b-ced7c3da6229";
1527
+ const string spaceId = "122b942a-d7b9-4839-b26e-836654b9785f";
1528
+
1446
1529
var builder = WebApplication.CreateBuilder(args);
1447
1530
1448
- - builder.Configuration.AddCloudFoundryContainerIdentity();
1449
- + builder.Configuration.AddAppInstanceIdentityCertificate();
1531
+ - builder.Configuration.AddCloudFoundryContainerIdentity(orgId, spaceId );
1532
+ + builder.Configuration.AddAppInstanceIdentityCertificate(new Guid(orgId), new Guid(spaceId) );
1450
1533
1451
- - builder.Services.AddCloudFoundryCertificateAuth();
1534
+ - builder.Services.AddCloudFoundryCertificateAuth(options => options.CertificateHeader = "X-Client-Cert" );
1452
1535
+ builder.Services.AddAuthentication().AddCertificate();
1453
1536
+ builder.Services.AddAuthorizationBuilder().AddOrgAndSpacePolicies();
1454
1537
1455
1538
var app = builder.Build();
1456
1539
1457
1540
- app.UseCloudFoundryCertificateAuth();
1458
1541
+ app.UseCertificateAuthorization();
1459
- ```
1460
-
1461
- Secured endpoints:
1462
-
1463
- ``` diff
1464
- - using Steeltoe.Security.Authentication.CloudFoundry;
1465
- + using Steeltoe.Security.Authorization.Certificate;
1466
-
1467
- - [Authorize(CloudFoundryDefaults.SameOrganizationAuthorizationPolicy)]
1468
- + [Authorize(CertificateAuthorizationPolicies.SameOrg)]
1469
- [HttpGet]
1470
- public string SameOrg()
1471
- {
1472
- return "Certificate is valid and both client and server are in the same org";
1473
- }
1542
+ app.MapGet("/sameOrg", async httpContext =>
1543
+ {
1544
+ httpContext.Response.StatusCode = 200;
1545
+ httpContext.Response.ContentType = "text/plain";
1546
+ await httpContext.Response.WriteAsync("Client and server identity certificates have matching Org values");
1547
+ })
1548
+ - .RequireAuthorization(CloudFoundryDefaults.SameOrganizationAuthorizationPolicy);
1549
+ + .RequireAuthorization(CertificateAuthorizationPolicies.SameOrg);
1474
1550
1475
- - [Authorize(CloudFoundryDefaults.SameSpaceAuthorizationPolicy)]
1476
- + [Authorize(CertificateAuthorizationPolicies.SameSpace)]
1477
- [HttpGet]
1478
- public string SameSpace()
1479
- {
1480
- return "Certificate is valid and both client and server are in the same space";
1481
- }
1551
+ app.MapGet("/sameSpace", async httpContext =>
1552
+ {
1553
+ httpContext.Response.StatusCode = 200;
1554
+ httpContext.Response.ContentType = "text/plain";
1555
+ await httpContext.Response.WriteAsync("Client and server identity certificates have matching Space values");
1556
+ })
1557
+ - .RequireAuthorization(CloudFoundryDefaults.SameSpaceAuthorizationPolicy);
1558
+ + .RequireAuthorization(CertificateAuthorizationPolicies.SameSpace);
1482
1559
```
1483
1560
1484
1561
Program.cs (client-side):
@@ -1491,18 +1568,40 @@ Program.cs (client-side):
1491
1568
- using Steeltoe.Security.Authentication.CloudFoundry;
1492
1569
+ using Steeltoe.Security.Authorization.Certificate;
1493
1570
1494
- var builder = WebApplication.CreateBuilder(args);
1571
+ const string orgId = "a8fef16f-94c0-49e3-aa0b-ced7c3da6229";
1572
+ const string spaceId = "122b942a-d7b9-4839-b26e-836654b9785f";
1495
1573
1496
- - builder.Configuration.AddCloudFoundryContainerIdentity();
1497
- + builder.Configuration.AddAppInstanceIdentityCertificate();
1574
+ var builder = WebApplication.CreateBuilder(args);
1498
1575
1499
- - builder.Services.AddHttpClient("withCertificate", (services, client) =>
1576
+ - builder.Configuration.AddCloudFoundryContainerIdentity(orgId, spaceId);
1577
+ + builder.Configuration.AddAppInstanceIdentityCertificate(new Guid(orgId), new Guid(spaceId));
1578
+ - builder.Services.AddCloudFoundryContainerIdentity();
1579
+ builder.Services
1580
+ - .AddHttpClient<PingClient>((services, client) =>
1500
1581
- {
1582
+ - client.BaseAddress = new Uri("http://example-service/")
1501
1583
- var options = services.GetRequiredService<IOptions<CertificateOptions>>();
1502
1584
- var b64 = Convert.ToBase64String(options.Value.Certificate.Export(X509ContentType.Cert));
1503
1585
- client.DefaultRequestHeaders.Add("X-Client-Cert", b64);
1504
1586
- });
1505
- + builder.Services.AddHttpClient("withCertificate").AddAppInstanceIdentityCertificate();
1587
+ + .AddHttpClient<PingClient>(httpClient => httpClient.BaseAddress = new Uri("http://example-service/"))
1588
+ + .AddAppInstanceIdentityCertificate();
1589
+
1590
+ var app = builder.Build();
1591
+
1592
+ var pingClient = app.Services.GetRequiredService<PingClient>();
1593
+ string orgResponse = await pingClient.GetPingAsync("org");
1594
+ Console.WriteLine($"Org response: {orgResponse}");
1595
+ string spaceResponse = await pingClient.GetPingAsync("space");
1596
+ Console.WriteLine($"Space response: {spaceResponse}");
1597
+
1598
+ public class PingClient(HttpClient httpClient)
1599
+ {
1600
+ public async Task<string> GetPingAsync(string matchType)
1601
+ {
1602
+ return await httpClient.GetStringAsync($"same{matchType}");
1603
+ }
1604
+ }
1506
1605
```
1507
1606
1508
1607
### DataProtection Key Store using Redis/Valkey
0 commit comments