.claude/skills/nauth-guide/SKILL.md
Guides how to integrate the NAuth package for user authentication in a .NET 8 project. Use when the user wants to add authentication, configure NAuth, use IUserClient, or understand the NAuth authentication flow.
npx skillsauth add emaginebr/NNews nauth-guideInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are an expert assistant that helps developers integrate the NAuth NuGet package for user authentication in .NET 8 Web API projects.
The user may provide a specific question or context as argument: $ARGUMENTS
If no argument is provided, present a complete overview of the NAuth integration.
When the user asks about NAuth authentication, use this knowledge base to provide accurate, contextual guidance.
Install: dotnet add package NAuth
public class NAuthSetting
{
public string ApiUrl { get; set; } // NAuth API base URL
public string JwtSecret { get; set; } // JWT signing secret (min 64 chars)
public string BucketName { get; set; } // Storage bucket name
public string? TenantId { get; set; } // If set, sends X-Tenant-Id header on requests
}
public class UserInfo
{
public long UserId { get; set; }
public string Slug { get; set; }
public string ImageUrl { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Hash { get; set; }
public bool IsAdmin { get; set; }
public DateTime? BirthDate { get; set; }
public string IdDocument { get; set; }
public string PixKey { get; set; }
public string Password { get; set; }
public int Status { get; set; } // UserStatus enum
public IList<RoleInfo> Roles { get; set; }
public IList<UserPhoneInfo> Phones { get; set; }
public IList<UserAddressInfo> Addresses { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
Same as UserInfo but without UserId, Hash, Status, CreatedAt, UpdatedAt. Used for creating new users.
public class RoleInfo { public long RoleId; public string Slug; public string Name; }
public class LoginParam { public string Email; public string Password; }
public class UserTokenResult { public string Token; public UserInfo User; }
public class ChangePasswordParam { public string OldPassword; public string NewPassword; }
public class ChangePasswordUsingHashParam { public string RecoveryHash; public string NewPassword; }
public class UserPhoneInfo { public string Phone; }
public class UserAddressInfo { public string ZipCode; public string Address; public string Complement; public string Neighborhood; public string City; public string State; }
public enum UserStatus { Active = 1, Inactive = 2, Suspended = 3, Blocked = 4 }
public interface IUserClient
{
// Session
UserInfo? GetUserInSession(HttpContext httpContext);
// User Retrieval
Task<UserInfo?> GetMeAsync(string token);
Task<UserInfo?> GetByIdAsync(long userId, string token);
Task<UserInfo?> GetByTokenAsync(string token);
Task<UserInfo?> GetByEmailAsync(string email);
Task<UserInfo?> GetBySlugAsync(string slug);
Task<IList<UserInfo>> ListAsync(int take);
// User Management
Task<UserInfo?> InsertAsync(UserInsertedInfo user);
Task<UserInfo?> UpdateAsync(UserInfo user, string token);
// Authentication
Task<UserTokenResult?> LoginWithEmailAsync(LoginParam param);
// Password
Task<bool> HasPasswordAsync(string token);
Task<bool> ChangePasswordAsync(ChangePasswordParam param, string token);
Task<bool> SendRecoveryMailAsync(string email);
Task<bool> ChangePasswordUsingHashAsync(ChangePasswordUsingHashParam param);
// File Upload
Task<string> UploadImageUserAsync(Stream fileStream, string fileName, string token);
}
public interface IRoleClient
{
Task<IList<RoleInfo>> ListAsync();
Task<RoleInfo?> GetByIdAsync(long roleId);
Task<RoleInfo?> GetBySlugAsync(string slug);
Task<RoleInfo?> InsertAsync(RoleInfo role);
Task<RoleInfo?> UpdateAsync(RoleInfo role);
Task<bool> DeleteAsync(long roleId);
}
Custom AuthenticationHandler that validates JWT tokens from the Authorization header against the NAuth API. Registered as the "BasicAuthentication" scheme.
{
"NAuth": {
"ApiURL": "http://localhost:5004",
"BucketName": "MyApp",
"JwtSecret": "your_jwt_secret_key_here_at_least_64_characters_long_for_security",
"TenantId": "my-tenant"
}
}
Docker: use "ApiURL": "http://nauth-api:80" and "JwtSecret": "${JWT_SECRET}".
using Microsoft.AspNetCore.Authentication;
using NAuth;
using NAuth.Interfaces;
using NAuth.Settings;
services.Configure<NAuthSetting>(configuration.GetSection("NAuth"));
services.AddHttpClient();
services.AddScoped<IUserClient, UserClient>();
services.AddScoped<IRoleClient, RoleClient>(); // Optional
services.AddAuthentication("BasicAuthentication")
.AddScheme<AuthenticationSchemeOptions, NAuthHandler>("BasicAuthentication", null);
app.UseCors("AllowFrontend"); // CORS before auth
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
Order matters: CORS -> Authentication -> Authorization.
Client Your API NAuth API
|-- Request + Bearer token -->| |
| |-- NAuthHandler validates ---->|
| |<-- User claims/info ---------|
| |-- [Authorize] passes |
| |-- GetUserInSession() |
|<-- Response ----------------| |
Authorization: Bearer <jwt_token> headerNAuthHandler validates JWT against NAuth APIHttpContext[Authorize] checks authentication succeededGetUserInSession(HttpContext) extracts UserInfo from claimsusing Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using NAuth.Interfaces;
[Route("api/[controller]")]
[ApiController]
public class MyController : ControllerBase
{
private readonly IUserClient _userClient;
public MyController(IUserClient userClient)
{
_userClient = userClient;
}
[HttpGet]
[Authorize]
public IActionResult GetProtectedData()
{
var userSession = _userClient.GetUserInSession(HttpContext);
if (userSession == null)
return Unauthorized("Not Authorized");
return Ok(new { message = $"Hello, {userSession.Name}!" });
}
}
[HttpGet("public")]
public IActionResult GetPublicData()
{
var userSession = _userClient.GetUserInSession(HttpContext);
var data = _myService.ListFiltered(userSession?.Roles);
return Ok(data);
}
[HttpPost]
[Authorize]
public IActionResult Create([FromBody] MyDto dto)
{
var userSession = _userClient.GetUserInSession(HttpContext);
if (userSession == null)
return Unauthorized("Not Authorized");
var result = _service.Create(dto, userSession.UserId);
return CreatedAtAction(nameof(GetById), new { id = result.Id }, result);
}
[HttpDelete("{id}")]
[Authorize]
public IActionResult Delete(int id)
{
var userSession = _userClient.GetUserInSession(HttpContext);
if (userSession == null)
return Unauthorized("Not Authorized");
if (!userSession.IsAdmin)
return Forbid();
_service.Delete(id);
return NoContent();
}
| Issue | Cause | Solution |
|-------|-------|----------|
| 401 on all requests | NAuth API unreachable | Verify NAuth:ApiURL in appsettings |
| 401 with valid token | JWT secret mismatch | Ensure JwtSecret matches NAuth API config |
| GetUserInSession returns null | Missing [Authorize] or invalid token | Add [Authorize] or check token |
| DI error for IUserClient | Missing registration | Add services.AddScoped<IUserClient, UserClient>() |
| NAuthHandler not found | Missing package | Run dotnet add package NAuth |
tools
Guides how to integrate the zTools package for ChatGPT, DALL-E image generation, file upload (S3), slug generation, email sending, and document validation in a .NET 8 project. Use when the user wants to use AI features, upload files, generate slugs, send emails, or understand zTools integration.
documentation
Generates a comprehensive, standardized README.md for any project. Use when the user wants to create or regenerate a README file following the project's documentation standard.
development
Guides how to integrate the NNews NuGet package for consuming the NNews CMS API in a .NET 8 project. Use when the user wants to consume articles, categories, tags, images, or AI-powered content generation from the NNews API.
data-ai
Creates Mermaid diagrams (.mmd) and generates PNG images from them. Use when the user wants to create flowcharts, sequence diagrams, class diagrams, ER diagrams, Gantt charts, or any other Mermaid-supported diagram.