.NET SDK
The Guardhouse .NET SDK provides a comprehensive API for integrating Guardhouse into your .NET applications, including ASP.NET Core, Console applications, and more.
Installation
NuGet Package
dotnet add package Guardhouse.SDK
Package Manager
Install-Package Guardhouse.SDK
.csproj Reference
<PackageReference Include="Guardhouse.SDK" Version="1.0.0" />
Getting Started
Initialize Client
using Guardhouse.SDK;
using Guardhouse.SDK.Models;
var client = new GuardhouseClient(new GuardhouseOptions
{
ClientId = "YOUR_CLIENT_ID",
ClientSecret = "YOUR_CLIENT_SECRET",
Domain = "YOUR_DOMAIN" // e.g., "your-tenant.guardhouse.cloud"
});
ASP.NET Core Dependency Injection
// Program.cs
using Guardhouse.SDK;
using Guardhouse.SDK.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Add Guardhouse client
builder.Services.AddGuardhouseClient(options =>
{
options.ClientId = builder.Configuration["Guardhouse:ClientId"];
options.ClientSecret = builder.Configuration["Guardhouse:ClientSecret"];
options.Domain = builder.Configuration["Guardhouse:Domain"];
});
var app = builder.Build();
appsettings.json
{
"Guardhouse": {
"ClientId": "YOUR_CLIENT_ID",
"ClientSecret": "YOUR_CLIENT_SECRET",
"Domain": "your-tenant.guardhouse.cloud"
}
}
Inject Client
public class UserService
{
private readonly IGuardhouseClient _client;
public UserService(IGuardhouseClient client)
{
_client = client;
}
public async Task<User> GetUserAsync(string userId)
{
return await _client.Users.GetAsync(userId);
}
}
User Management
List Users
// Get all users (paginated)
var users = await _client.Users.GetAllAsync();
// With pagination
var users = await _client.Users.GetAllAsync(
page: 1,
perPage: 50
);
// With filtering and sorting
var users = await _client.Users.GetAllAsync(
page: 1,
perPage: 50,
email: "john.doe@example.com",
query: "john",
sort: "created_at",
order: SortOrder.Desc
);
// Access results
foreach (var user in users.Items)
{
Console.WriteLine($"{user.UserId}: {user.Name} ({user.Email})");
}
Console.WriteLine($"Total: {users.Total}");
Console.WriteLine($"Page: {users.Page} of {users.TotalPages}");
Get User by ID
var user = await _client.Users.GetAsync("usr_123456789");
Console.WriteLine($"User: {user.Name}");
Console.WriteLine($"Email: {user.Email}");
Console.WriteLine($"Created: {user.CreatedAt}");
Console.WriteLine($"Last Login: {user.LastLogin}");
Console.WriteLine($"Logins Count: {user.LoginsCount}");
Update User
var user = await _client.Users.GetAsync("usr_123456789");
// Update basic fields
user.Name = "John Updated Doe";
user.Email = "new.email@example.com";
user.PhoneNumber = "+1-555-987-6543";
user.Picture = "https://cdn.example.com/avatars/new.jpg";
// Update metadata
user.UserMetadata = new Dictionary<string, object>
{
{ "department", "Marketing" },
{ "employee_id", "EMP002" }
};
user.AppMetadata = new Dictionary<string, object>
{
{ "roles", new[] { "user", "moderator" } },
{ "permissions", new[] { "read:users", "write:users" } }
};
// Block/Unblock user
user.Blocked = false;
// Save changes
var updated = await _client.Users.UpdateAsync(user);
Create User
var newUser = new CreateUserRequest
{
Email = "new.user@example.com",
Password = "SecurePassword123!",
Name = "New User",
Connection = "Username-Password-Authentication",
EmailVerified = true,
UserMetadata = new Dictionary<string, object>
{
{ "department", "Engineering" }
}
};
var createdUser = await _client.Users.CreateAsync(newUser);
Delete User
await _client.Users.DeleteAsync("usr_123456789");
Current User Profile Management
Get Current User Profile
var currentUser = await _client.Users.GetMeAsync();
Console.WriteLine($"User ID: {currentUser.UserId}");
Console.WriteLine($"Name: {currentUser.Name}");
Console.WriteLine($"Email: {currentUser.Email}");
Console.WriteLine($"Email Verified: {currentUser.EmailVerified}");
Change Password
await _client.Users.ChangePasswordAsync(
currentPassword: "OldPassword123!",
newPassword: "NewSecurePassword123!",
confirmPassword: "NewSecurePassword123!"
);
Update Name
await _client.Users.UpdateNameAsync(
givenName: "John",
familyName: "Doe"
);
Update Email
await _client.Users.UpdateEmailAsync(
email: "new.email@example.com",
verifyEmail: true
);
Update Profile
await _client.Users.UpdateProfileAsync(new UpdateProfileRequest
{
Name = "John Updated Doe",
Nickname = "johndoe_new",
Picture = "https://cdn.example.com/avatars/new.jpg",
UserMetadata = new Dictionary<string, object>
{
{ "department", "Marketing" },
{ "location", "New York" }
}
});
Authentication
Get Access Token
var token = await _client.Authentication.GetAccessTokenAsync();
Console.WriteLine($"Access Token: {token.AccessToken}");
Console.WriteLine($"Token Type: {token.TokenType}");
Console.WriteLine($"Expires In: {token.ExpiresIn} seconds");
Console.WriteLine($"Scope: {token.Scope}");
Refresh Token
var newToken = await _client.Authentication.RefreshTokenAsync(refreshToken);
Revoke Token
await _client.Authentication.RevokeTokenAsync(accessToken);
User Login
var loginResult = await _client.Authentication.LoginAsync(new LoginRequest
{
Username = "user@example.com",
Password = "Password123!",
Connection = "Username-Password-Authentication"
});
Console.WriteLine($"Access Token: {loginResult.AccessToken}");
Console.WriteLine($"ID Token: {loginResult.IdToken}");
Console.WriteLine($"Refresh Token: {loginResult.RefreshToken}");
User Logout
await _client.Authentication.LogoutAsync(refreshToken);
Error Handling
Try-Catch Pattern
try
{
var user = await _client.Users.GetAsync("usr_123456789");
}
catch (GuardhouseApiException ex)
{
// API errors (4xx, 5xx)
Console.WriteLine($"API Error: {ex.Message}");
Console.WriteLine($"Code: {ex.Code}");
Console.WriteLine($"Status: {ex.StatusCode}");
Console.WriteLine($"RequestId: {ex.RequestId}");
}
catch (GuardhouseAuthenticationException ex)
{
// Authentication errors (invalid credentials, expired tokens)
Console.WriteLine($"Authentication failed: {ex.Message}");
}
catch (GuardhouseValidationException ex)
{
// Validation errors (invalid request data)
Console.WriteLine($"Validation failed: {ex.Message}");
foreach (var error in ex.ValidationErrors)
{
Console.WriteLine($" Field: {error.Field}");
Console.WriteLine($" Message: {error.Message}");
}
}
Custom Error Handling
public class CustomErrorHandler : IGuardhouseErrorHandler
{
public void HandleError(GuardhouseApiException exception)
{
// Log error
Logger.Error(exception, "Guardhouse API error");
// Send alert
AlertService.SendAlert(exception);
}
}
// Register custom error handler
var client = new GuardhouseClient(options, new CustomErrorHandler());
Configuration Options
Full Configuration
var options = new GuardhouseOptions
{
// Required
ClientId = "YOUR_CLIENT_ID",
ClientSecret = "YOUR_CLIENT_SECRET",
Domain = "YOUR_DOMAIN",
// Optional
ApiVersion = "v2",
Timeout = TimeSpan.FromSeconds(30),
RetryPolicy = new RetryPolicy
{
MaxRetries = 3,
Delay = TimeSpan.FromSeconds(1),
BackoffFactor = 2
},
LogLevel = LogLevel.Information,
EnableLogging = true
};
var client = new GuardhouseClient(options);
Retry Policy
var options = new GuardhouseOptions
{
ClientId = "YOUR_CLIENT_ID",
ClientSecret = "YOUR_CLIENT_SECRET",
Domain = "YOUR_DOMAIN",
RetryPolicy = new RetryPolicy
{
MaxRetries = 5,
Delay = TimeSpan.FromSeconds(2),
BackoffFactor = 2,
RetryableStatusCodes = new[] { 408, 429, 500, 502, 503, 504 }
}
};
Logging
Built-in Logging
var options = new GuardhouseOptions
{
ClientId = "YOUR_CLIENT_ID",
ClientSecret = "YOUR_CLIENT_SECRET",
Domain = "YOUR_DOMAIN",
LogLevel = LogLevel.Debug,
EnableLogging = true
};
Custom Logger
public class CustomLogger : IGuardhouseLogger
{
public void LogDebug(string message, params object[] args)
{
Console.WriteLine($"[DEBUG] {string.Format(message, args)}");
}
public void LogInformation(string message, params object[] args)
{
Console.WriteLine($"[INFO] {string.Format(message, args)}");
}
public LogWarning(string message, params object[] args)
{
Console.WriteLine($"[WARN] {string.Format(message, args)}");
}
public LogError(Exception exception, string message, params object[] args)
{
Console.WriteLine($"[ERROR] {string.Format(message, args)}");
Console.WriteLine($"Exception: {exception.Message}");
}
}
var client = new GuardhouseClient(options, new CustomLogger());
ASP.NET Core Integration
Authentication Middleware
// Program.cs
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.Authority = $"https://{builder.Configuration["Guardhouse:Domain"]}";
options.Audience = builder.Configuration["Guardhouse:Audience"];
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ClockSkew = TimeSpan.Zero
};
});
Authorization Policy
// Program.cs
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("ReadUsers", policy =>
policy.RequireClaim("scope", "read:users"));
options.AddPolicy("WriteUsers", policy =>
policy.RequireClaim("scope", "write:users"));
});
Protected Controller
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class UsersController : ControllerBase
{
private readonly IGuardhouseClient _client;
public UsersController(IGuardhouseClient client)
{
_client = client;
}
[HttpGet]
[Authorize(Policy = "ReadUsers")]
public async Task<IActionResult> GetUsers()
{
var users = await _client.Users.GetAllAsync();
return Ok(users);
}
[HttpGet("{userId}")]
[Authorize(Policy = "ReadUsers")]
public async Task<IActionResult> GetUser(string userId)
{
var user = await _client.Users.GetAsync(userId);
return Ok(user);
}
[HttpPut("{userId}")]
[Authorize(Policy = "WriteUsers")]
public async Task<IActionResult> UpdateUser(string userId, [FromBody] UpdateUserRequest request)
{
var user = await _client.Users.GetAsync(userId);
user.Name = request.Name;
user.Email = request.Email;
var updated = await _client.Users.UpdateAsync(user);
return Ok(updated);
}
}
Best Practices
- Use Dependency Injection: Inject
IGuardhouseClientwhere needed - Configure Retry Policy: Handle transient failures gracefully
- Implement Logging: Enable logging for debugging and monitoring
- Handle Errors: Always use try-catch for API calls
- Use Async/Await: All SDK methods are asynchronous
- Dispose Client: Implement proper disposal pattern for console apps
- Cache Responses: Cache frequently accessed user data
- Validate Tokens: Always validate JWTs on your APIs
Additional Resources
Support
For issues, questions, or contributions: