MCAuth 1.0.2
dotnet add package MCAuth --version 1.0.2
NuGet\Install-Package MCAuth -Version 1.0.2
<PackageReference Include="MCAuth" Version="1.0.2" />
<PackageVersion Include="MCAuth" Version="1.0.2" />
<PackageReference Include="MCAuth" />
paket add MCAuth --version 1.0.2
#r "nuget: MCAuth, 1.0.2"
#:package MCAuth@1.0.2
#addin nuget:?package=MCAuth&version=1.0.2
#tool nuget:?package=MCAuth&version=1.0.2
MCAuth
A library for web apps to authenticate via the user's Minecraft account. A code from Microsoft's login flow must be obtained first, which this library also helps with generating a URL to redirect to. After a successful login through Microsoft you will then receive a code, which you can then pass to this library to complete the process.
Background
In order to authenticate via a Minecraft account many HTTP requests must be made, this library aims to simplify the process by doing it all for you. Here is a detailed description of each request made behind the scenes during authentication:
- Microsoft token (requires code from Microsoft login flow)
- Xbox Live token (requires Microsoft token from previous step)
- Xbox Live XSTS token (requires Xbox Live token from previous step)
- Minecraft Token (requires both Xbox Live and XSTS token from previous steps)
- Minecraft Profile (requires Minecraft token from previous step)
Usage
Authenticating with this library is a three-step process.
Step 1 - Microsoft Login Flow
You will need to log in through Microsoft's login flow, which must be done with a specific url that can be generated with this library like so:
var client = new MCAuthClient("AZURE_CLIENT_ID", "AZURE_CLIENT_SECRET");
var redirectUrl = "https://my-app.com/login";
var url = client.GetMicrosoftLoginUrl(redirectUrl);
If you are using an ASP.NET API, you can easily redirect a user to this url in a controller like so:
[ApiController]
[Route("/api/[controller]/[action]")]
public class UserController : ControllerBase
{
[HttpGet]
public IActionResult Login()
{
var client = new MCAuthClient("AZURE_CLIENT_ID", "AZURE_CLIENT_SECRET");
var redirectUrl = "https://my-app.com/login";
var url = client.GetMicrosoftLoginUrl(redirectUrl);
return Redirect(url);
}
}
Step 2 - Authentication
After you have successfully logged in, you will be redirected to the url you provided along with
a code query parameter. With our example, the url would look something like this:
https://my-app.com/login?code=M.C503_AB1.2.U.01234567-89ab-cdef-0123-456789abcdef. Use this
code for the Authenticate method:
var client = new MCAuthClient("AZURE_CLIENT_ID", "AZURE_CLIENT_SECRET");
var code = "M.C503_AB1.2.U.01234567-89ab-cdef-0123-456789abcdef"; // retrieved from the previous step
var redirectUrl = "https://my-app.com/login"; // it's important that this is the same url used for the login flow
var result = await client.Authenticate(new MCAuthRequest(code, redirectUrl), cancellationToken);
The result contains the HTTP responses from each service mentioned earlier.
Step 3 - Additional Token (Optional)
You may want to create your own additional token that you will use to authenticate with your app. The
reason you might need this is that you likely will have your own user ID/GUID in a database which is
tied to your Minecraft ID and username. Although, if you choose to only store your Minecraft ID in
your database then you may be able to skip this step and instead authenticate directly with the Minecraft
access token returned from Authenticate. If you do choose to create your own token, our library also
has a method on the result to help during this process:
// retrieve your userId any way you'd like, but it'll most likely be by Minecraft ID
var userId = await _userRepository.GetByMinecraftId(result.MinecraftProfile.Id);
var token = result.CreateToken(new MCAuthTokenOptions("JWT_SECRET", new DateTimeDuration { Days = 1 }) {
ExtraClaims = new List<Claim> {
new(ClaimTypes.Name, userId.ToString())
// these claims are added by default, but are customizable if needed
// new(ClaimTypes.NameIdentifier, result.MinecraftProfile.Id);
// new(ClaimTypes.GivenName, result.MinecraftProfile.Name);
}
});
Again, if you are using an ASP.NET API, a full solution might look something like this:
[ApiController]
[Route("/api/[controller]/[action]")]
public class UserController : ControllerBase
{
// you probably want to retrieve the ClientId and ClientSecret with environment variables
private readonly MCAuthClient _client = new MCAuthClient("AZURE_CLIENT_ID", "AZURE_CLIENT_SECRET");
private readonly string _redirectUrl = "https://my-app.com/login";
private readonly IUserRepository _userRepository;
public UserController(IUserRepository userRepository)
{
_userRepository = userRepository;
}
[HttpGet]
public IActionResult Login()
{
var url = _client.GetMicrosoftLoginUrl(_redirectUrl);
return Redirect(url);
}
// capture the `code` query parameter on your front end and then provide it here
[HttpPost]
public async Task<IActionResult> Authenticate([FromQuery] string code, CancellationToken cancellationToken)
{
var result = await _client.Authenticate(new MCAuthRequest(code, _redirectUrl), cancellationToken);
// retrieve your userId any way you'd like, but it'll most likely be by Minecraft ID
var userId = await _userRepository.GetByMinecraftId(result.MinecraftProfile.Id);
var token = result.CreateToken(new MCAuthTokenOptions("JWT_SECRET", new DateTimeDuration { Days = 1 }) {
ExtraClaims = new List<Claim> {
new(ClaimTypes.Name, userId.ToString())
// these claims are added by default, but are customizable if needed
// new(ClaimTypes.NameIdentifier, result.MinecraftProfile.Id);
// new(ClaimTypes.GivenName, result.MinecraftProfile.Name);
}
});
return Ok(result);
}
}
Events
You also have the ability to capture HTTP requests, responses, and errors that occur in the Authenticate
method while it is still executing for each of the services that are interacted with. Each event has both
synchronous and asynchronous support. Capturing errors in events may be trivial in most cases since an
exception is thrown by the library immediately after your error event, but if you needed to execute
something before that exception is thrown you can do so.
Here are a few example use cases:
Logging
var serializerOptions = new JsonSerializerOptions { WriteIndented = true };
var logEvent = (string message, object obj, LogLevel logLevel = LogLevel.Information) => {
_Logger.Log(logLevel, $"{message}: {{0}}", JsonSerializer.Serialize(obj, serializerOptions));
};
var result = await _client.Authenticate(new MCAuthRequest(code, _redirectUrl) {
Options = new MCAuthOptions {
MicrosoftTokenEvents = new MicrosoftAuthTokenEvents {
OnRequest = request => logEvent("MicrosoftToken Request", request),
OnResponse = response => logEvent("MicrosoftToken Response", response),
OnError = error => logEvent("MicrosoftToken Error", error, LogLevel.Error)
},
XboxLiveTokenEvents = new XboxLiveAuthTokenEvents {
OnRequest = request => logEvent("XboxLive Request", request),
OnResponse = response => logEvent("XboxLive Response", response),
OnError = error => logEvent("XboxLive Error", error, LogLevel.Error)
},
XboxLiveXstsTokenEvents = new XboxLiveXstsAuthTokenEvents {
OnRequest = request => logEvent("XboxLiveXSTS Request", request),
OnResponse = response => logEvent("XboxLiveXSTS Response", response),
OnError = error => logEvent("XboxLiveXSTS Error", error, LogLevel.Error)
},
MinecraftTokenEvents = new MinecraftAuthTokenEvents {
OnRequest = request => logEvent("MinecraftToken Request", request),
OnResponse = response => logEvent("MinecraftToken Response", response),
OnError = error => logEvent("MinecraftToken Error", error, LogLevel.Error)
},
MinecraftProfileEvents = new MinecraftProfileAuthEvents {
OnRequest = request => logEvent("MinecraftProfile Request", request),
OnResponse = response => logEvent("MinecraftProfile Response", response),
OnError = error => logEvent("MinecraftProfile Error", error, LogLevel.Error)
}
}
}, cancellationToken);
Client Messages (SignalR)
var serializerOptions = new JsonSerializerOptions { WriteIndented = true };
var sendClientMessage = async (string message, object obj) => {
await _userHub.SendMessage(string.Format($"{message}: {{0}}", JsonSerializer.Serialize(obj, serializerOptions)));
};
var result = await _client.Authenticate(new MCAuthRequest(code, _redirectUrl) {
Options = new MCAuthOptions {
MicrosoftTokenEvents = new MicrosoftAuthTokenEvents {
OnRequest = async request => await sendClientMessage("MicrosoftToken Request", request),
OnResponse = async response => await sendClientMessage("MicrosoftToken Response", response),
OnError = async error => await sendClientMessage("MicrosoftToken Error", error)
},
XboxLiveTokenEvents = new XboxLiveAuthTokenEvents {
OnRequest = async request => await sendClientMessage("XboxLive Request", request),
OnResponse = async response => await sendClientMessage("XboxLive Response", response),
OnError = async error => await sendClientMessage("XboxLive Error", error)
},
XboxLiveXstsTokenEvents = new XboxLiveXstsAuthTokenEvents {
OnRequest = async request => await sendClientMessage("XboxLiveXSTS Request", request),
OnResponse = async response => await sendClientMessage("XboxLiveXSTS Response", response),
OnError = async error => await sendClientMessage("XboxLiveXSTS Error", error)
},
MinecraftTokenEvents = new MinecraftAuthTokenEvents {
OnRequest = async request => await sendClientMessage("MinecraftToken Request", request),
OnResponse = async response => await sendClientMessage("MinecraftToken Response", response),
OnError = async error => await sendClientMessage("MinecraftToken Error", error)
},
MinecraftProfileEvents = new MinecraftProfileAuthEvents {
OnRequest = async request => await sendClientMessage("MinecraftProfile Request", request),
OnResponse = async response => await sendClientMessage("MinecraftProfile Response", response),
OnError = async error => await sendClientMessage("MinecraftProfile Error", error)
}
}
}, cancellationToken);
Exceptions
MCAuthException- Occurs when an HTTP response contains an error message in the response body. Contains aHttpStatusCodeproperty. Each service has its own exception which extends from this base exception, each with custom fields which match fields from the response body for that service:MicrosoftAuthException- ContainsError,ErrorDescription, andCorrelationIdproperties which are populated from JSON response body.Messageshows details of each.XboxLiveAuthException- Contains no extra properties.Messageis populated directly from plain text response body.XboxLiveXstsAuthException- ContainsIdentity,XErr,ErrorMessage, andRedirectproperties which are populated from JSON response body.Messageshow details of each.MinecraftAuthException- Contains no extra properties.Messageis populated directly from plain text response body.MinecraftProfileAuthException- ContainsPath,ErrorType,Error,ErrorMessage, andDeveloperMessageproperties which are populated from JSON response body.Messageshows details of each.
HttpRequestException- Occurs when an HTTP request could not be made to the service. Usually because it's offline.TimeoutException- Occurs when an HTTP request times out on the service. Most likely if the service is experiencing a heavy load or large number of requests.
Known Error Codes
Microsoft Token
Reference: Redeem a code for an access token
| Error | Description |
|---|---|
| consent_required | The request requires user consent. This error is non-standard. It's usually only returned on the /authorize endpoint per OIDC specifications. Returned when a scope parameter was used on the code redemption flow that the client app doesn't have permission to request. |
| interaction_required | Non-standard, as the OIDC specification calls for this code only on the /authorize endpoint. The request requires user interaction. For example, another authentication step is required. |
| invalid_client | Client authentication failed. |
| invalid_grant | The authorization code or PKCE code verifier is invalid or has expired. |
| invalid_request | Protocol error, such as a missing required parameter. |
| invalid_resource | The target resource is invalid because it doesn't exist, Microsoft Entra ID can't find it, or it's not correctly configured. |
| invalid_scope | The scope requested by the app is invalid. |
| temporarily_unavailable | The server is temporarily too busy to handle the request. |
| unauthorized_client | The authenticated client isn't authorized to use this authorization grant type. |
| unsupported_grant_type | The authorization server doesn't support the authorization grant type. |
Xbox Live XSTS
Reference: Obtain XSTS token for Minecraft
| XErr | Description |
|---|---|
| 2148916227 | The account is banned from Xbox. |
| 2148916233 | The account does not have an Xbox account. Please sign up or login to minecraft.net first. |
| 2148916235 | The account is from a country where Xbox Live is not available/banned. |
| 2148916236 | The account needs adult verification on Xbox page. (South Korea) |
| 2148916237 | The account needs age verification on Xbox page. (South Korea) |
| 2148916238 | The account is a child and cannot proceed unless the account is added to a Family by an adult. |
| 2148916262 | TBD, happens rarely without any additional information. |
Minecraft Profile
Reference: Getting the Profile
| Error | Description |
|---|---|
| NOT_FOUND | Minecraft is not owned on this account. If you are an Xbox Game Pass user you must log into the Minecraft Launcher at least once first. |
Testing
See MCAuth.Testing library.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- Microsoft.AspNetCore.WebUtilities (>= 9.0.12)
- Microsoft.IdentityModel.Tokens (>= 8.0.1)
- System.IdentityModel.Tokens.Jwt (>= 8.0.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on MCAuth:
| Package | Downloads |
|---|---|
|
MCAuth.Testing
The testing library is used for testing purposes only. It automatically mocks HTTP requests made by the library and returns a custom response provided by you. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.2 | 34 | 2/19/2026 |
Initial 1.0.0 release