You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多认证源JWT Token:ASP.Net Core跨站Cookie认证技术问询

Alright, let's walk through how to implement multi-source JWT authentication for your specific setup—since you're transitioning from shared cookies and have a static-delivering Website A paired with API A, here's a practical, step-by-step approach tailored to your needs:

1. Core Architecture Adjustment

Your current setup uses shared cookies between Website A and API A for auth. To add multi-source JWT support, we'll keep Website A focused on static delivery (perfect for your future OrchardCore plans) and modify API A to:

  • Support both existing shared cookie auth and JWT auth (for smooth transition)
  • Handle multiple authentication sources (e.g., local accounts, third-party OAuth, internal systems)
  • Generate standardized JWT tokens regardless of the user's auth source
2. Multi-Source JWT Generation Flow

Step 1: Configure Multiple Auth Schemes in API A

First, set up API A to accept cookies, JWT, and any additional auth sources you need. Here's how to wire this up in Program.cs:

builder.Services.AddAuthentication(options =>
{
    // Set default schemes based on your transition needs—keep cookies as default for existing users
    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
// Keep shared cookie support for backward compatibility
.AddCookie(options =>
{
    options.Cookie.Name = "YourSharedCookieName";
    options.Cookie.Domain = ".yourdomain.com"; // Ensure cross-domain sharing
    options.Events = new CookieAuthenticationEvents
    {
        // Generate a JWT and pass it back to the client after successful cookie auth
        OnValidatePrincipal = async context =>
        {
            var jwtToken = GenerateJwtToken(context.Principal);
            context.Response.Headers.Append("X-Jwt-Token", jwtToken);
        }
    };
})
// Add JWT Bearer authentication for future requests
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        ValidAudience = builder.Configuration["Jwt:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
    };
    // Allow JWT from either Authorization header or HttpOnly cookie
    options.Events = new JwtBearerEvents
    {
        OnMessageReceived = context =>
        {
            var token = context.Request.Cookies["JwtToken"];
            if (!string.IsNullOrEmpty(token))
            {
                context.Token = token;
            }
            return Task.CompletedTask;
        }
    };
})
// Example: Add third-party auth (Google) as an additional source
.AddGoogle(options =>
{
    options.ClientId = builder.Configuration["Google:ClientId"];
    options.ClientSecret = builder.Configuration["Google:ClientSecret"];
    options.Events.OnCreatingTicket = async context =>
    {
        // Generate JWT after successful Google auth
        var jwtToken = GenerateJwtToken(context.Principal);
        context.Response.Cookies.Append("JwtToken", jwtToken, new CookieOptions
        {
            HttpOnly = true,
            Secure = true,
            SameSite = SameSiteMode.Strict,
            Domain = ".yourdomain.com"
        });
    };
});

// Don't forget to enable authorization
builder.Services.AddAuthorization();

Step 2: Build a Unified JWT Generation Utility

Create a reusable method to generate JWT tokens with consistent claims, no matter which auth source the user comes from. This ensures your API can handle all users uniformly:

private string GenerateJwtToken(ClaimsPrincipal principal)
{
    var claims = new List<Claim>
    {
        new Claim(ClaimTypes.NameIdentifier, principal.FindFirstValue(ClaimTypes.NameIdentifier)),
        new Claim("AuthSource", principal.Identity.AuthenticationType) // Tag where the user authenticated from
    };
    // Add user roles or other custom claims as needed
    var roles = principal.FindAll(ClaimTypes.Role);
    claims.AddRange(roles);

    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

    var token = new JwtSecurityToken(
        issuer: _configuration["Jwt:Issuer"],
        audience: _configuration["Jwt:Audience"],
        claims: claims,
        expires: DateTime.Now.AddHours(8),
        signingCredentials: creds);

    return new JwtSecurityTokenHandler().WriteToken(token);
}

Step 3: Update Your JS Client to Use JWT

Modify your frontend to grab the JWT after initial auth (via cookies or third-party login) and use it for subsequent API requests. Here's a simple example:

// Handle login and retrieve JWT
async function handleLogin() {
    const response = await fetch('/api/auth/login', {
        method: 'POST',
        credentials: 'include' // Send shared cookies for existing users
    });
    // Get JWT from response header or cookie
    const jwtToken = response.headers.get('X-Jwt-Token') || 
        document.cookie.split('; ').find(row => row.startsWith('JwtToken='))?.split('=')[1];
    
    // Store JWT (prefer HttpOnly cookies over localStorage for security)
    localStorage.setItem('jwtToken', jwtToken);
}

// Use JWT for API calls
async function fetchApiData() {
    const jwtToken = localStorage.getItem('jwtToken');
    const response = await fetch('/api/your-endpoint', {
        headers: {
            'Authorization': `Bearer ${jwtToken}`
        },
        credentials: 'include' // Keep for backward compatibility
    });
    const data = await response.json();
    console.log(data);
}
3. Multi-Source Authorization Logic

Once users are authenticated via any source, you can use the AuthSource claim to apply source-specific permissions. For example:

[Authorize(AuthenticationSchemes = "Bearer,Cookies")]
[HttpGet("protected-data")]
public IActionResult GetProtectedData()
{
    var authSource = User.FindFirstValue("AuthSource");
    
    if (authSource == "Google")
    {
        // Apply third-party user-specific permissions
        return Ok(new { data = "Google user-specific content" });
    }
    else if (authSource == "Cookie")
    {
        // Apply local cookie user permissions
        return Ok(new { data = "Local user content" });
    }
    
    return Forbid();
}
4. Smooth Transition & Compatibility
  • Keep shared cookie auth enabled to avoid breaking existing requests.
  • Add a middleware to automatically issue JWT tokens to cookie-authenticated users, so your frontend can switch to JWT gradually.
  • Test both auth methods side-by-side until you're ready to fully transition to JWT.
5. Critical Security Notes
  • Store your JWT secret in environment variables or a secure config system—never hardcode it.
  • Enforce HTTPS to prevent token interception.
  • Set short JWT expiration times and implement a refresh token flow for longer sessions.
  • Use HttpOnly, Secure, and SameSite=Strict cookies for JWT storage to mitigate XSS and CSRF risks.

内容的提问来源于stack exchange,提问作者identify

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:12:45