Skip to content

Commit 9fda9a1

Browse files
committed
Separate OAuth from OIDC, more complete examples
- use Steeltoe UAA for fully-functional examples
1 parent 5a4e8e3 commit 9fda9a1

File tree

1 file changed

+148
-49
lines changed

1 file changed

+148
-49
lines changed

docs/docs/v4/welcome/migrate-quick-steps.md

Lines changed: 148 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,10 +1251,73 @@ For additional information, see the updated [Security documentation](../security
12511251
The CredHub client has been removed from Steeltoe in v4.
12521252
Use [CredHub Service Broker](https://techdocs.broadcom.com/us/en/vmware-tanzu/platform-services/credhub-service-broker/services/credhub-sb/index.html) instead.
12531253

1254-
### OAuth and OpenID Connect
1254+
### OAuth
12551255

12561256
OAuth support has been removed from Steeltoe in v4. Use OpenID Connect instead.
12571257

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+
12581321
Project file:
12591322

12601323
```diff
@@ -1271,7 +1334,9 @@ Project file:
12711334
appsettings.json:
12721335

12731336
```diff
1337+
{
12741338
- "$schema": "https://steeltoe.io/schema/v3/schema.json",
1339+
+ "$schema": "https://steeltoe.io/schema/v4/schema.json",
12751340
- "Security": {
12761341
- "Oauth2": {
12771342
- "Client": {
@@ -1280,7 +1345,7 @@ appsettings.json:
12801345
- "ClientId": "steeltoesamplesclient",
12811346
- "ClientSecret": "client_secret",
12821347
- "MetadataAddress": "http://localhost:8080/.well-known/openid-configuration",
1283-
- "AdditionalScopes": "profile sampleapi.read",
1348+
- "AdditionalScopes": "sampleapi.read",
12841349
- "SaveTokens": true,
12851350
- "RequireHttpsMetadata": false
12861351
- }
@@ -1300,6 +1365,7 @@ appsettings.json:
13001365
+ }
13011366
+ }
13021367
+ }
1368+
}
13031369
```
13041370

13051371
> [!NOTE]
@@ -1310,27 +1376,29 @@ Program.cs:
13101376

13111377
```diff
13121378
using Microsoft.AspNetCore.Authentication.Cookies;
1313-
+using Microsoft.AspNetCore.Authentication.OpenIdConnect;
13141379
-using Microsoft.AspNetCore.HttpOverrides;
1315-
-using Microsoft.Extensions.Options;
13161380
-using Steeltoe.Extensions.Configuration.CloudFoundry;
13171381
+using Steeltoe.Configuration.CloudFoundry;
1382+
+using Steeltoe.Configuration.CloudFoundry.ServiceBindings;
13181383
-using Steeltoe.Security.Authentication.CloudFoundry;
1384+
+using Microsoft.AspNetCore.Authentication.OpenIdConnect;
13191385
+using Steeltoe.Security.Authentication.OpenIdConnect;
13201386

13211387
var builder = WebApplication.CreateBuilder(args);
13221388
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+
})
13291396
.AddCookie(options => options.AccessDeniedPath = new PathString("/Home/AccessDenied"))
13301397
- .AddCloudFoundryOpenIdConnect(builder.Configuration);
13311398
+ .AddOpenIdConnect().ConfigureOpenIdConnectForCloudFoundry();
13321399
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"));
13341402

13351403
var app = builder.Build();
13361404

@@ -1343,9 +1411,6 @@ app.UseAuthentication();
13431411
app.UseAuthorization();
13441412
```
13451413

1346-
> [!NOTE]
1347-
> Use the code above for applications that previously used `.AddCloudFoundryOAuth(builder.Configuration);`.
1348-
13491414
### JWT Bearer
13501415

13511416
Project file:
@@ -1364,11 +1429,13 @@ Project file:
13641429
appsettings.json:
13651430

13661431
```diff
1432+
{
13671433
- "$schema": "https://steeltoe.io/schema/v3/schema.json",
1434+
+ "$schema": "https://steeltoe.io/schema/v4/schema.json",
13681435
- "Security": {
13691436
- "Oauth2": {
13701437
- "Client": {
1371-
- "AuthDomain": "http://localhost:8080/uaa",
1438+
- "AuthDomain": "http://localhost:8080",
13721439
- "ClientId": "steeltoesamplesserver",
13731440
- "ClientSecret": "server_secret",
13741441
- "JwtKeyUrl": "http://localhost:8080/token_keys",
@@ -1380,12 +1447,16 @@ appsettings.json:
13801447
+ "Authentication": {
13811448
+ "Schemes": {
13821449
+ "Bearer": {
1383-
+ "Authority": "http://localhost:8080/uaa",
1450+
+ "Authority": "http://localhost:8080",
13841451
+ "ClientId": "steeltoesamplesserver",
13851452
+ "ClientSecret": "server_secret",
1453+
+ "MetadataAddress": "http://localhost:8080/.well-known/openid-configuration",
1454+
+ "RequireHttpsMetadata": false,
1455+
+ "ValidAudiences": [ "sampleapi" ]
13861456
+ }
13871457
+ }
13881458
+ }
1459+
}
13891460
```
13901461

13911462
> [!NOTE]
@@ -1395,22 +1466,23 @@ appsettings.json:
13951466
Program.cs:
13961467

13971468
```diff
1398-
using Microsoft.AspNetCore.Authentication.JwtBearer;
13991469
-using Microsoft.AspNetCore.HttpOverrides;
14001470
-using Steeltoe.Extensions.Configuration.CloudFoundry;
14011471
+using Steeltoe.Configuration.CloudFoundry;
1472+
+using Steeltoe.Configuration.CloudFoundry.ServiceBindings;
14021473
-using Steeltoe.Security.Authentication.CloudFoundry;
14031474
+using Steeltoe.Security.Authentication.JwtBearer;
14041475

14051476
var builder = WebApplication.CreateBuilder(args);
14061477

14071478
builder.AddCloudFoundryConfiguration();
1479+
+builder.Configuration.AddCloudFoundryServiceBindings();
14081480

1409-
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
1481+
builder.Services.AddAuthentication()
14101482
- .AddCloudFoundryJwtBearer(builder.Configuration);
14111483
+ .AddJwtBearer().ConfigureJwtBearerForCloudFoundry();
14121484
builder.Services.AddAuthorizationBuilder()
1413-
.AddPolicy("some-group", policy => policy.RequireClaim("scope", "some-group"));
1485+
.AddPolicy("sampleapi.read", policy => policy.RequireClaim("scope", "sampleapi.read"));
14141486

14151487
var app = builder.Build();
14161488

@@ -1421,6 +1493,14 @@ var app = builder.Build();
14211493

14221494
app.UseAuthentication();
14231495
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();
14241504
```
14251505

14261506
### Client Certificates (Mutual TLS)
@@ -1443,42 +1523,39 @@ Program.cs (server-side):
14431523
-using Steeltoe.Security.Authentication.CloudFoundry;
14441524
+using Steeltoe.Security.Authorization.Certificate;
14451525

1526+
const string orgId = "a8fef16f-94c0-49e3-aa0b-ced7c3da6229";
1527+
const string spaceId = "122b942a-d7b9-4839-b26e-836654b9785f";
1528+
14461529
var builder = WebApplication.CreateBuilder(args);
14471530

1448-
-builder.Configuration.AddCloudFoundryContainerIdentity();
1449-
+builder.Configuration.AddAppInstanceIdentityCertificate();
1531+
-builder.Configuration.AddCloudFoundryContainerIdentity(orgId, spaceId);
1532+
+builder.Configuration.AddAppInstanceIdentityCertificate(new Guid(orgId), new Guid(spaceId));
14501533

1451-
-builder.Services.AddCloudFoundryCertificateAuth();
1534+
-builder.Services.AddCloudFoundryCertificateAuth(options => options.CertificateHeader = "X-Client-Cert");
14521535
+builder.Services.AddAuthentication().AddCertificate();
14531536
+builder.Services.AddAuthorizationBuilder().AddOrgAndSpacePolicies();
14541537

14551538
var app = builder.Build();
14561539

14571540
-app.UseCloudFoundryCertificateAuth();
14581541
+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);
14741550

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);
14821559
```
14831560

14841561
Program.cs (client-side):
@@ -1491,18 +1568,40 @@ Program.cs (client-side):
14911568
-using Steeltoe.Security.Authentication.CloudFoundry;
14921569
+using Steeltoe.Security.Authorization.Certificate;
14931570

1494-
var builder = WebApplication.CreateBuilder(args);
1571+
const string orgId = "a8fef16f-94c0-49e3-aa0b-ced7c3da6229";
1572+
const string spaceId = "122b942a-d7b9-4839-b26e-836654b9785f";
14951573

1496-
-builder.Configuration.AddCloudFoundryContainerIdentity();
1497-
+builder.Configuration.AddAppInstanceIdentityCertificate();
1574+
var builder = WebApplication.CreateBuilder(args);
14981575

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) =>
15001581
-{
1582+
- client.BaseAddress = new Uri("http://example-service/")
15011583
- var options = services.GetRequiredService<IOptions<CertificateOptions>>();
15021584
- var b64 = Convert.ToBase64String(options.Value.Certificate.Export(X509ContentType.Cert));
15031585
- client.DefaultRequestHeaders.Add("X-Client-Cert", b64);
15041586
-});
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+
}
15061605
```
15071606

15081607
### DataProtection Key Store using Redis/Valkey

0 commit comments

Comments
 (0)