Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1. Allow to use well-known standard secrets.json file for storing a private key… #653

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 161 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,167 @@ var oauthAppsApi = new ApplicationApi(configuration);

It is possible to use an access token you retrieved outside of the SDK for authentication. For that, set `Configuration.AuthorizationMode` configuration property to `AuthorizationMode.BearerToken` and `Configuration.AccessToken` to the token string.

## Using secret.json for local or appsettings.Development.json or appsettings.Stagging.json etc., Program.cs example for ASPNET API Core.
``` csharp
using Microsoft.Extensions.Configuration.UserSecrets;
using Okta.Sdk.Api;
using Okta.Sdk.Client;
using System.Reflection;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddControllers();

builder.Services.AddSwaggerGen();

builder.Services.AddScoped<IUserApi, UserApi>();
builder.Services.AddScoped<IGroupApi, GroupApi>();

var app = builder.Build();

SetConfigurationFilePathForOktaApiServices();

// Configure the HTTP request pipeline.
if (!app.Environment.IsProduction())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseRouting();
app.UseHttpsRedirection();
app.MapControllers();

app.Run();

void SetConfigurationFilePathForOktaApiServices()
{
var environmentName = app.Environment.EnvironmentName;

if (string.Equals(environmentName, "Local", StringComparison.OrdinalIgnoreCase))
{
var secretsId = Assembly.GetExecutingAssembly().GetCustomAttribute<UserSecretsIdAttribute>()?.UserSecretsId;
var configFilePath = PathHelper.GetSecretsPathFromSecretsId(secretsId);

SetFilePath(configFilePath);
}
else
{
var configurationFileRoot = app.Environment.ContentRootPath;
var applicationAppSettingsLocation = Path.Combine(configurationFileRoot ?? string.Empty, string.IsNullOrEmpty(environmentName) ? "appsettings.json" : $"appsettings.{environmentName}.json");

SetFilePath(applicationAppSettingsLocation);
}
}

void SetFilePath(string filePath)
{
System.Diagnostics.Debug.Assert(!string.IsNullOrEmpty(filePath), $"{nameof(filePath)} missing parameter.");

if (File.Exists(filePath))
{
Configuration.GetConfigFilePath = () => filePath;
}
}
```

## Consume IUserApi, IGroupApi in OktaController.cs
``` csharp
using Microsoft.AspNetCore.Mvc;
using Okta.Sdk.Api;
using Okta.Sdk.Model;

namespace OktaUserManagement;

public class OktaController : Controller
{
private readonly IUserApi _userApi;
private readonly IGroupApi _groupApi;

public OktaController(IUserApi userApi, IGroupApi groupApi)
{
_userApi = userApi;
_groupApi = groupApi;
}

[HttpGet("GetUsers")]
public async Task<IEnumerable<User>> GetUsers()
{
var users = await _userApi.ListUsers(limit: 2).ToListAsync();
return users;
}

[HttpGet("GetGroups")]
public async Task<IEnumerable<Group>> GetGroups()
{
var groups = await _groupApi.ListGroups().ToListAsync();
return groups;
}
}
```

## Set okta settings in secrets.json for local development, appsettings.Stagging.json, appsetttings.XXXXX.json, appsetttings.YYYYY.json settings files for deployment environments
```json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",

"okta": {
"client": {
"connectionTimeout": 30000,
"oktaDomain": "{{yourOktaDomain}}",
"proxy": null,
"port": null,
"host": null,
"username": null,
"password": null,
"authorizationMode": "PrivateKey",
"clientId": "{{clientId}}",
"Scopes": {
"scopeId1": "okta.users.read",
"scopeId2": "okta.users.manage",
"scopeId3": "okta.groups.read",
"scopeId4": "okta.groups.manage"
},
"PrivateKey": {
"d": "{{d}}",
"p": "{{p}}",
"q": "{{q}}",
"dp": "{{dp}}",
"dq": "{{dq}}",
"qi": "{{qi}}",
"kty": "RSA",
"e": "AQAB",
"kid": "{{kid}}",
"n": "{{n}}"
}
}
}
}
```
## ASPNETCORE_ENVIRONMENT is set to local for a developer machine environment in launchSettings.json
```json
{
"profiles": {
"OktaUserManagement": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7127",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Local"
}
}
}
}
```
## Usage guide

These examples will help you understand how to use this library. You can also browse the full [API reference documentation][dotnetdocs].
Expand Down
67 changes: 47 additions & 20 deletions src/Okta.Sdk/Client/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,12 @@ protected void AddApiKeyPrefix(string key, string value)
#endregion Methods

#region Static Members

/// <summary>
/// Allows a client application/api to set a configuration file path (i.e. secrets.json or appSettings.xxxxxx.json)
/// </summary>
public static Func<string> GetConfigFilePath { get; set; }

/// <summary>
/// Merge configurations.
/// </summary>
Expand Down Expand Up @@ -832,34 +838,55 @@ public static IReadableConfiguration MergeConfigurations(IReadableConfiguration
};
return config;
}

public static Configuration GetConfigurationOrDefault(Configuration configuration = null)
{
string configurationFileRoot = Directory.GetCurrentDirectory();
var compiledConfig = new Configuration();
var configBuilder = new ConfigurationBuilder();

var homeOktaYamlLocation = HomePath.Resolve("~", ".okta", "okta.yaml");
if (GetConfigFilePath != null)
{
string applicationAppSettingsLocation = GetConfigFilePath();

var applicationAppSettingsLocation = Path.Combine(configurationFileRoot ?? string.Empty, "appsettings.json");
var applicationOktaYamlLocation = Path.Combine(configurationFileRoot ?? string.Empty, "okta.yaml");
if (!File.Exists(applicationAppSettingsLocation))
throw new FileNotFoundException($"Could not find configuration file at {applicationAppSettingsLocation}");

var configBuilder = new ConfigurationBuilder()
.AddYamlFile(homeOktaYamlLocation, optional: true)
.AddJsonFile(applicationAppSettingsLocation, optional: true)
.AddYamlFile(applicationOktaYamlLocation, optional: true)
.AddEnvironmentVariables("okta", "_", root: "okta")
.AddEnvironmentVariables("okta_testing", "_", root: "okta")
.AddObject(configuration, root: "okta:client")
.AddObject(configuration, root: "okta:testing")
.AddObject(configuration);
var builtConfig = configBuilder.AddJsonFile(applicationAppSettingsLocation)
.AddObject(configuration)
.Build();

var compiledConfig = new Configuration();
configBuilder.Build().GetSection("okta").GetSection("client").Bind(compiledConfig);
configBuilder.Build().GetSection("okta").GetSection("testing").Bind(compiledConfig);
configBuilder.Build().Bind(compiledConfig);
builtConfig.GetSection("okta").GetSection("client").Bind(compiledConfig);

return compiledConfig;
return compiledConfig;
}
else
{
string configurationFileRoot = Directory.GetCurrentDirectory();

var homeOktaYamlLocation = HomePath.Resolve("~", ".okta", "okta.yaml");

var applicationAppSettingsLocation = Path.Combine(configurationFileRoot ?? string.Empty, "appsettings.json");
var applicationOktaYamlLocation = Path.Combine(configurationFileRoot ?? string.Empty, "okta.yaml");

configBuilder.AddYamlFile(homeOktaYamlLocation, optional: true)
.AddJsonFile(applicationAppSettingsLocation, optional: true)
.AddYamlFile(applicationOktaYamlLocation, optional: true)
.AddEnvironmentVariables("okta", "_", root: "okta")
.AddEnvironmentVariables("okta_testing", "_", root: "okta")
.AddObject(configuration, root: "okta:client")
.AddObject(configuration, root: "okta:testing")
.AddObject(configuration);

var config = configBuilder.Build();
config.GetSection("okta").GetSection("client").Bind(compiledConfig);
config.GetSection("okta").GetSection("testing").Bind(compiledConfig);
config.Bind(compiledConfig);


return compiledConfig;
}
}

#endregion Static Members
}

Expand Down