3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PONOSAdvent Calendar 2024

Day 13

ASP.NETでMagicOnionに認証機能を実装する

Last updated at Posted at 2024-12-12

はじめに

この記事はPONOS Advent Calendar 202413日目の記事です。
前回は@kerimekaさんでした!

MagicOnionは、Unityなどのリアルタイムアプリケーションで利用可能な軽量なgRPCベースのフレームワークです。
この記事では、ASP.NETの認証機能を利用してMagicOnion APIへのアクセス制限を行う方法を解説します。

使用する技術

  • ASP.NET Core 8.0
  • MagicOnion
  • JSON Web Token (JWT)
  • Unityクライアント

ゴール

  1. ASP.NET CoreでJWTベースの認証を設定。
  2. MagicOnionサービスで認証されたクライアントのみアクセス可能にする。
  3. 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 音声ファイル インポート設定」です!

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?