Skip to content

Commit

Permalink
Merge pull request #1245 from DuendeSoftware/joe/initiate-login-uri
Browse files Browse the repository at this point in the history
Add support for initiate_login_uri
  • Loading branch information
brockallen committed Apr 12, 2023
2 parents b6da8a9 + 43cfc8e commit 58d30ad
Show file tree
Hide file tree
Showing 19 changed files with 147 additions and 11 deletions.
3 changes: 2 additions & 1 deletion hosts/Configuration/ClientsWeb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ public static IEnumerable<Client> Get()

AllowOfflineAccess = true,

AllowedScopes = allowedScopes
AllowedScopes = allowedScopes,
InitiateLoginUri = "https://localhost:44302/Home/Secure"
},

///////////////////////////////////////////
Expand Down
4 changes: 2 additions & 2 deletions hosts/EntityFramework/HostingExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using Duende.IdentityServer;
using Duende.IdentityServer.Configuration;
using IdentityServerHost.Pages.Admin.ApiScopes;
using IdentityServerHost.Pages.Admin.Clients;
using IdentityServerHost.Pages.Admin.IdentityScopes;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.IdentityModel.Tokens;
Expand Down Expand Up @@ -60,7 +59,8 @@ private static void AddAdminFeatures(this WebApplicationBuilder builder)
builder.Services.Configure<RazorPagesOptions>(options =>
options.Conventions.AuthorizeFolder("/Admin", "admin"));

builder.Services.AddTransient<ClientRepository>();
builder.Services.AddTransient<Pages.Admin.Clients.ClientRepository>();
builder.Services.AddTransient<Pages.Portal.ClientRepository>();
builder.Services.AddTransient<IdentityScopeRepository>();
builder.Services.AddTransient<ApiScopeRepository>();
}
Expand Down
3 changes: 3 additions & 0 deletions hosts/EntityFramework/Pages/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
<li>
Click <a href="~/admin">here</a> to view the simple admin page.
</li>
<li>
Click <a href="~/portal">here</a> to view the client application portal.
</li>
<li>
Here are links to the
<a href="https://github.com/duendesoftware/IdentityServer">source code repository</a>,
Expand Down
40 changes: 40 additions & 0 deletions hosts/EntityFramework/Pages/Portal/ClientRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Duende.IdentityServer.EntityFramework.DbContexts;
using Microsoft.EntityFrameworkCore;

namespace IdentityServerHost.Pages.Portal;

public class ThirdPartyInitiatedLoginLink
{
public string LinkText { get; set; }
public string InitiateLoginUri { get; set; }
}


public class ClientRepository
{
private readonly ConfigurationDbContext _context;

public ClientRepository(ConfigurationDbContext context)
{
_context = context;
}

public async Task<IEnumerable<ThirdPartyInitiatedLoginLink>> GetClientsWithLoginUris(string filter = null)
{
var query = _context.Clients
.Where(c => c.InitiateLoginUri != null);

if (!String.IsNullOrWhiteSpace(filter))
{
query = query.Where(x => x.ClientId.Contains(filter) || x.ClientName.Contains(filter));
}

var result = query.Select(c => new ThirdPartyInitiatedLoginLink
{
LinkText = string.IsNullOrWhiteSpace(c.ClientName) ? c.ClientId : c.ClientName,
InitiateLoginUri = c.InitiateLoginUri
});

return await result.ToArrayAsync();
}
}
30 changes: 30 additions & 0 deletions hosts/EntityFramework/Pages/Portal/Index.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
@page
@model IdentityServerHost.Pages.Portal.Index

<div class="portal-page">

<div class="lead">
<h1>Client Application Portal</h1>
<p>This portal contains links to client applications that are configured
with an InitiateLoginUri, which enables
<a href="https://openid.net/specs/openid-connect-core-1_0.html#ThirdPartyInitiatedLogin">third-party initiated login</a>.
</p>
</div>

@if(!Model.Clients.Any())
{
<div class="alert">
You do not have any clients configured with an InitiateLoginUri.
</div>
}

<ul class="list-group">
@foreach (var client in Model.Clients)
{
<li class="list-group-item">
<a href="@client.InitiateLoginUri">@client.LinkText</a>
</li>
}
</ul>

</div>
19 changes: 19 additions & 0 deletions hosts/EntityFramework/Pages/Portal/Index.cshtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace IdentityServerHost.Pages.Portal;

public class Index : PageModel
{
private readonly ClientRepository _repository;
public IEnumerable<ThirdPartyInitiatedLoginLink> Clients { get; private set; }

public Index(ClientRepository repository)
{
_repository = repository;
}

public async Task OnGetAsync()
{
Clients = await _repository.GetClientsWithLoginUris();
}
}
2 changes: 1 addition & 1 deletion hosts/EntityFramework/appsettings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"ConnectionStrings": {
"db": "server=localhost;database=Duende.EntityFramework-6.3.0;trusted_connection=yes;"
// "db": "server=(localdb)\\mssqllocaldb;database=Duende.EntityFramework-6.1.0;trusted_connection=yes;"
// "db": "server=(localdb)\\mssqllocaldb;database=Duende.EntityFramework-6.3.0;trusted_connection=yes;"
}
}
6 changes: 5 additions & 1 deletion migrations/IdentityServerDb/Migrations/ConfigurationDb.sql
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ CREATE TABLE [Clients] (
[AllowPlainTextPkce] bit NOT NULL,
[RequireRequestObject] bit NOT NULL,
[AllowAccessTokensViaBrowser] bit NOT NULL,
[RequireDPoP] bit NOT NULL,
[DPoPValidationMode] int NOT NULL,
[DPoPClockSkew] time NOT NULL,
[FrontChannelLogoutUri] nvarchar(2000) NULL,
[FrontChannelLogoutSessionRequired] bit NOT NULL,
[BackChannelLogoutUri] nvarchar(2000) NULL,
Expand All @@ -83,6 +86,7 @@ CREATE TABLE [Clients] (
[AlwaysSendClientClaims] bit NOT NULL,
[ClientClaimsPrefix] nvarchar(200) NULL,
[PairWiseSubjectSalt] nvarchar(200) NULL,
[InitiateLoginUri] nvarchar(2000) NULL,
[UserSsoLifetime] int NULL,
[UserCodeType] nvarchar(100) NULL,
[DeviceCodeLifetime] int NOT NULL,
Expand Down Expand Up @@ -361,7 +365,7 @@ CREATE UNIQUE INDEX [IX_IdentityResources_Name] ON [IdentityResources] ([Name]);
GO

INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
VALUES (N'20220324152912_Configuration', N'6.0.0');
VALUES (N'20230410170353_Configuration', N'6.0.0');
GO

COMMIT;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ protected override void Up(MigrationBuilder migrationBuilder)
AllowPlainTextPkce = table.Column<bool>(type: "bit", nullable: false),
RequireRequestObject = table.Column<bool>(type: "bit", nullable: false),
AllowAccessTokensViaBrowser = table.Column<bool>(type: "bit", nullable: false),
RequireDPoP = table.Column<bool>(type: "bit", nullable: false),
DPoPValidationMode = table.Column<int>(type: "int", nullable: false),
DPoPClockSkew = table.Column<TimeSpan>(type: "time", nullable: false),
FrontChannelLogoutUri = table.Column<string>(type: "nvarchar(2000)", maxLength: 2000, nullable: true),
FrontChannelLogoutSessionRequired = table.Column<bool>(type: "bit", nullable: false),
BackChannelLogoutUri = table.Column<string>(type: "nvarchar(2000)", maxLength: 2000, nullable: true),
Expand All @@ -97,6 +100,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
AlwaysSendClientClaims = table.Column<bool>(type: "bit", nullable: false),
ClientClaimsPrefix = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: true),
PairWiseSubjectSalt = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: true),
InitiateLoginUri = table.Column<string>(type: "nvarchar(2000)", maxLength: 2000, nullable: true),
UserSsoLifetime = table.Column<int>(type: "int", nullable: true),
UserCodeType = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: true),
DeviceCodeLifetime = table.Column<int>(type: "int", nullable: false),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,12 @@ protected override void BuildModel(ModelBuilder modelBuilder)
b.Property<DateTime>("Created")
.HasColumnType("datetime2");
b.Property<TimeSpan>("DPoPClockSkew")
.HasColumnType("time");
b.Property<int>("DPoPValidationMode")
.HasColumnType("int");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
Expand All @@ -401,6 +407,10 @@ protected override void BuildModel(ModelBuilder modelBuilder)
b.Property<bool>("IncludeJwtId")
.HasColumnType("bit");
b.Property<string>("InitiateLoginUri")
.HasMaxLength(2000)
.HasColumnType("nvarchar(2000)");
b.Property<DateTime?>("LastAccessed")
.HasColumnType("datetime2");
Expand Down Expand Up @@ -435,6 +445,9 @@ protected override void BuildModel(ModelBuilder modelBuilder)
b.Property<bool>("RequireConsent")
.HasColumnType("bit");
b.Property<bool>("RequireDPoP")
.HasColumnType("bit");
b.Property<bool>("RequirePkce")
.HasColumnType("bit");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ CREATE INDEX [IX_ServerSideSessions_SubjectId] ON [ServerSideSessions] ([Subject
GO

INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
VALUES (N'20220324152905_Grants', N'6.0.0');
VALUES (N'20230410170347_Grants', N'6.0.0');
GO

COMMIT;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions migrations/IdentityServerDb/appsettings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"ConnectionStrings": {
"db": "server=(localdb)\\mssqllocaldb;database=Duende.EntityFramework-6.1.0;trusted_connection=yes;"
//"db": "Data Source=DuendeIdentityServer.db;"
"db": "server=localhost;database=Duende.EntityFramework-6.3.0;trusted_connection=yes;"
// "db": "server=(localdb)\\mssqllocaldb;database=Duende.EntityFramework-6.3.0;trusted_connection=yes;"
}
}
1 change: 1 addition & 0 deletions src/EntityFramework.Storage/Entities/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public class Client
public string ClientClaimsPrefix { get; set; } = "client_";
public string PairWiseSubjectSalt { get; set; }
public List<ClientCorsOrigin> AllowedCorsOrigins { get; set; }
public string InitiateLoginUri { get; set; }
public List<ClientProperty> Properties { get; set; }
public int? UserSsoLifetime { get; set; }
public string UserCodeType { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public static void ConfigureClientContext(this ModelBuilder modelBuilder, Config
client.Property(x => x.PairWiseSubjectSalt).HasMaxLength(200);
client.Property(x => x.UserCodeType).HasMaxLength(100);
client.Property(x => x.AllowedIdentityTokenSigningAlgorithms).HasMaxLength(100);
client.Property(x => x.InitiateLoginUri).HasMaxLength(2000);
client.HasIndex(x => x.ClientId).IsUnique();
Expand Down
7 changes: 7 additions & 0 deletions src/Storage/Models/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,13 @@ public ICollection<string> AllowedGrantTypes
/// </value>
public ICollection<string> AllowedCorsOrigins { get; set; } = new HashSet<string>();

/// <summary>
/// Gets of sets a URI that can be used to initiate login from the
/// IdentityServer host or a third party. See
/// https://openid.net/specs/openid-connect-core-1_0.html#ThirdPartyInitiatedLogin
/// </summary>
public string? InitiateLoginUri { get; set; }

/// <summary>
/// Gets or sets the custom properties for the client.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public async Task FindClientByIdAsync_WhenClientDoesNotExist_ExpectNull(DbContex
}

[Theory, MemberData(nameof(TestDatabaseProviders))]
public async Task FindClientByIdAsync_WhenClientExists_ExpectClientRetured(DbContextOptions<ConfigurationDbContext> options)
public async Task FindClientByIdAsync_WhenClientExists_ExpectClientReturned(DbContextOptions<ConfigurationDbContext> options)
{
var testClient = new Client
{
Expand Down

0 comments on commit 58d30ad

Please sign in to comment.