はじめに
この記事はPONOS Advent Calendar 202413日目の記事です。
前回は@kerimekaさんでした!
MagicOnionは、Unityなどのリアルタイムアプリケーションで利用可能な軽量なgRPCベースのフレームワークです。
この記事では、ASP.NETの認証機能を利用してMagicOnion APIへのアクセス制限を行う方法を解説します。
使用する技術
- ASP.NET Core 8.0
- MagicOnion
- JSON Web Token (JWT)
- Unityクライアント
ゴール
- ASP.NET CoreでJWTベースの認証を設定。
- MagicOnionサービスで認証されたクライアントのみアクセス可能にする。
- Unityクライアントからのトークン付き通信を実装。
ステップ1: JWT認証をASP.NET Coreに追加
まず、ASP.NET CoreプロジェクトでJWT認証を設定します。
// Program.cs
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
// JWT認証の設定
var key = Encoding.UTF8.GetBytes("YourSecureKeyHere");
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "YourIssuer",
ValidAudience = "YourAudience",
IssuerSigningKey = new SymmetricSecurityKey(key)
};
});
builder.Services.AddMagicOnion();
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapMagicOnionService<MyService>();
app.Run();
ステップ2: MagicOnionで認証をチェックする
次に、MagicOnionサービスで認証済みユーザーのみがアクセスできるように設定します。
using MagicOnion;
using MagicOnion.Server;
[Authorize] // ASP.NET Coreの認証属性を使用
public class MyService : ServiceBase<IMyService>, IMyService
{
public async UnaryResult<string> GetSecureData()
{
var user = Context.GetHttpContext().User;
if (!user.Identity.IsAuthenticated)
{
throw new UnauthorizedAccessException("Unauthorized");
}
return "This is secure data!";
}
}
ステップ3: トークンを生成するエンドポイントの実装
認証用のJWTトークンを発行するAPIを実装します。
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Text;
[ApiController]
[Route("api/auth")]
public class AuthController : ControllerBase
{
[HttpPost("token")]
public IActionResult GenerateToken([FromBody] LoginRequest request)
{
if (request.Username == "user" && request.Password == "password") // 仮の認証
{
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YourSecureKeyHere"));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: "YourIssuer",
audience: "YourAudience",
expires: DateTime.Now.AddMinutes(30),
signingCredentials: creds
);
return Ok(new { token = new JwtSecurityTokenHandler().WriteToken(token) });
}
return Unauthorized();
}
}
public class LoginRequest
{
public string Username { get; set; }
public string Password { get; set; }
}
ステップ4: Unityクライアントからのトークン付きリクエスト
Unityクライアントでトークンを取得し、MagicOnion APIにリクエストを送信します。
using MagicOnion.Client;
using Grpc.Net.Client;
using System.Net.Http;
using System.Threading.Tasks;
public class UnityClient : MonoBehaviour
{
private async Task Start()
{
// トークンを取得
var httpClient = new HttpClient();
var response = await httpClient.PostAsync("https://yourserver/api/auth/token",
new StringContent("{\"username\":\"user\",\"password\":\"password\"}", Encoding.UTF8, "application/json"));
var responseBody = await response.Content.ReadAsStringAsync();
var token = JsonUtility.FromJson<TokenResponse>(responseBody).token;
// MagicOnionクライアントを作成
var channel = GrpcChannel.ForAddress("https://yourserver", new GrpcChannelOptions
{
HttpClient = new HttpClient { DefaultRequestHeaders = { Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token) } }
});
var client = MagicOnionClient.Create<IMyService>(channel);
var result = await client.GetSecureData();
Debug.Log(result);
}
[System.Serializable]
private class TokenResponse
{
public string token;
}
}
終わりに
いかがでしたでしょうか。
ASP.NETの認証機能を利用してMagicOnion APIへのアクセス制限を行う方法でした。
他にも色々な方法があると思いますので、色々実験していきたいと思います。
次回は@caramel_cafeさんの「Unity 音声ファイル インポート設定」です!