246 lines
8.7 KiB
C#
246 lines
8.7 KiB
C#
// Copyright (c) .NET Foundation. All rights reserved.
|
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using IdentityServer4;
|
|
using IdentityServer4.Models;
|
|
|
|
namespace Microsoft.AspNetCore.ApiAuthorization.IdentityServer
|
|
{
|
|
/// <summary>
|
|
/// A builder for Clients.
|
|
/// </summary>
|
|
public class ClientBuilder
|
|
{
|
|
private const string NativeAppClientRedirectUri = "urn:ietf:wg:oauth:2.0:oob";
|
|
|
|
Client _client;
|
|
private bool _built = false;
|
|
|
|
/// <summary>
|
|
/// Creates a new builder for a single page application that coexists with an authorization server.
|
|
/// </summary>
|
|
/// <param name="clientId">The client id for the single page application.</param>
|
|
/// <returns>A <see cref="ClientBuilder"/>.</returns>
|
|
public static ClientBuilder IdentityServerSPA(string clientId)
|
|
{
|
|
var client = CreateClient(clientId);
|
|
return new ClientBuilder(client)
|
|
.WithApplicationProfile(ApplicationProfiles.IdentityServerSPA)
|
|
.WithAllowedGrants(GrantTypes.Implicit)
|
|
.WithAllowedOrigins(Array.Empty<string>())
|
|
.AllowAccessTokensViaBrowser();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new builder for an externally registered single page application.
|
|
/// </summary>
|
|
/// <param name="clientId">The client id for the single page application.</param>
|
|
/// <returns>A <see cref="ClientBuilder"/>.</returns>
|
|
public static ClientBuilder SPA(string clientId)
|
|
{
|
|
var client = CreateClient(clientId);
|
|
return new ClientBuilder(client)
|
|
.WithApplicationProfile(ApplicationProfiles.SPA)
|
|
.WithAllowedGrants(GrantTypes.Implicit)
|
|
.AllowAccessTokensViaBrowser();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new builder for an externally registered native application.
|
|
/// </summary>
|
|
/// <param name="clientId">The client id for the native application.</param>
|
|
/// <returns>A <see cref="ClientBuilder"/>.</returns>
|
|
public static ClientBuilder NativeApp(string clientId)
|
|
{
|
|
var client = CreateClient(clientId);
|
|
return new ClientBuilder(client)
|
|
.WithApplicationProfile(ApplicationProfiles.NativeApp)
|
|
.WithAllowedGrants(GrantTypes.Code)
|
|
.WithRedirectUri(NativeAppClientRedirectUri)
|
|
.WithLogoutRedirectUri(NativeAppClientRedirectUri)
|
|
.WithPkce()
|
|
.WithoutClientSecrets()
|
|
.WithScopes(IdentityServerConstants.StandardScopes.OfflineAccess);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Creates a new builder for an externally registered web application.
|
|
/// </summary>
|
|
/// <param name="clientId">The client id for the web application.</param>
|
|
/// <returns>A <see cref="ClientBuilder"/>.</returns>
|
|
internal static ClientBuilder WebApplication(string clientId)
|
|
{
|
|
var client = CreateClient(clientId);
|
|
return new ClientBuilder(client)
|
|
.WithApplicationProfile(ApplicationProfiles.WebApplication)
|
|
.WithAllowedGrants(GrantTypes.HybridAndClientCredentials)
|
|
.WithScopes(IdentityServerConstants.StandardScopes.OfflineAccess);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of <see cref="ClientBuilder"/>.
|
|
/// </summary>
|
|
public ClientBuilder() : this(new Client())
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new intance of <see cref="ClientBuilder"/>.
|
|
/// </summary>
|
|
/// <param name="client">A preconfigured client.</param>
|
|
public ClientBuilder(Client client)
|
|
{
|
|
_client = client;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the client id (and name) of the client.
|
|
/// </summary>
|
|
/// <param name="clientId">The new client id.</param>
|
|
/// <returns>The <see cref="ClientBuilder"/>.</returns>
|
|
public ClientBuilder WithClientId(string clientId)
|
|
{
|
|
_client.ClientId = clientId;
|
|
_client.ClientName = clientId;
|
|
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the application profile for the client.
|
|
/// </summary>
|
|
/// <param name="profile">The the profile for the application from <see cref="ApplicationProfiles"/>.</param>
|
|
/// <returns>The <see cref="ClientBuilder"/>.</returns>
|
|
public ClientBuilder WithApplicationProfile(string profile)
|
|
{
|
|
_client.Properties.Add(ApplicationProfilesPropertyNames.Profile, profile);
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds the <paramref name="scopes"/> to the list of allowed scopes for the client.
|
|
/// </summary>
|
|
/// <param name="scopes">The list of scopes.</param>
|
|
/// <returns>The <see cref="ClientBuilder"/>.</returns>
|
|
public ClientBuilder WithScopes(params string[] scopes)
|
|
{
|
|
foreach (var scope in scopes)
|
|
{
|
|
_client.AllowedScopes.Add(scope);
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds the <paramref name="redirectUri"/> to the list of valid redirect uris for the client.
|
|
/// </summary>
|
|
/// <param name="redirectUri">The redirect uri to add.</param>
|
|
/// <returns>The <see cref="ClientBuilder"/>.</returns>
|
|
public ClientBuilder WithRedirectUri(string redirectUri)
|
|
{
|
|
_client.RedirectUris.Add(redirectUri);
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds the <paramref name="logoutUri"/> to the list of valid logout redirect uris for the client.
|
|
/// </summary>
|
|
/// <param name="logoutUri">The logout uri to add.</param>
|
|
/// <returns>The <see cref="ClientBuilder"/>.</returns>
|
|
public ClientBuilder WithLogoutRedirectUri(string logoutUri)
|
|
{
|
|
_client.PostLogoutRedirectUris.Add(logoutUri);
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds the <paramref name="clientSecret"/> to the list of client secrets for the client and configures the client to
|
|
/// require using the secret when getting tokens from the token endpoint.
|
|
/// </summary>
|
|
/// <param name="clientSecret">The client secret to add.</param>
|
|
/// <returns>The <see cref="ClientBuilder"/>.</returns>
|
|
internal ClientBuilder WithClientSecret(string clientSecret)
|
|
{
|
|
_client.ClientSecrets.Add(new Secret(clientSecret));
|
|
_client.RequireClientSecret = true;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes any configured client secret from the client and configures it to not require a client secret for getting tokens
|
|
/// from the token endpoint.
|
|
/// </summary>
|
|
/// <returns>The <see cref="ClientBuilder"/>.</returns>
|
|
public ClientBuilder WithoutClientSecrets()
|
|
{
|
|
_client.RequireClientSecret = false;
|
|
_client.ClientSecrets.Clear();
|
|
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Builds the client.
|
|
/// </summary>
|
|
/// <returns>The built <see cref="Client"/>.</returns>
|
|
public Client Build()
|
|
{
|
|
if (_built)
|
|
{
|
|
throw new InvalidOperationException("Client already built.");
|
|
}
|
|
|
|
_built = true;
|
|
return _client;
|
|
}
|
|
|
|
internal ClientBuilder WithPkce()
|
|
{
|
|
_client.RequirePkce = true;
|
|
_client.AllowPlainTextPkce = false;
|
|
|
|
return this;
|
|
}
|
|
|
|
internal ClientBuilder FromConfiguration()
|
|
{
|
|
_client.Properties[ApplicationProfilesPropertyNames.Source] = ApplicationProfilesPropertyValues.Configuration;
|
|
return this;
|
|
}
|
|
|
|
internal ClientBuilder WithAllowedGrants(ICollection<string> grants)
|
|
{
|
|
_client.AllowedGrantTypes = grants;
|
|
return this;
|
|
}
|
|
|
|
internal ClientBuilder WithAllowedOrigins(params string[] origins)
|
|
{
|
|
_client.AllowedCorsOrigins = origins;
|
|
return this;
|
|
}
|
|
|
|
internal ClientBuilder AllowAccessTokensViaBrowser()
|
|
{
|
|
_client.AllowAccessTokensViaBrowser = true;
|
|
return this;
|
|
}
|
|
|
|
private static Client CreateClient(string name)
|
|
{
|
|
var client = new Client
|
|
{
|
|
ClientId = name,
|
|
ClientName = name,
|
|
RequireConsent = false
|
|
};
|
|
|
|
return client;
|
|
}
|
|
}
|
|
}
|