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

.NET 8控制器内Bearer Token生成失败问题求助

.NET 7升级到8后控制器中无法生成Bearer Token的解决方法

问题背景

将.NET项目从7升级至8后,使用Results.SignIn在Minimal API(Program.cs)中能正常生成Bearer Token,但在MVC控制器的RequestToken方法中执行相同逻辑时,返回结果为空,无法生成Token。

核心原因

Results.SignIn是专为Minimal API设计的结果类型,它会在Minimal API的专属管道中触发Bearer Token生成逻辑。但在MVC控制器中,直接将Results.SignIn对象包装到Ok结果返回,不会触发对应的Token生成处理——控制器的结果处理管道与Minimal API不同,无法识别并处理该类型对象。

解决方案

方案一:使用SignInManager(推荐,符合ASP.NET Core Identity设计)

通过注入SignInManager<IdentityUser>来完成登录操作,自动触发Token生成逻辑:

[HttpPost]
[Route("RequestToken")]
public async Task<IActionResult> RequestToken([FromBody] Login model) {
    try {
        var user = await _userManager.FindByNameAsync(model.DeviceName);
        if (user != null && await _userManager.CheckPasswordAsync(user, model.Password)) {
            var userRoles = await _userManager.GetRolesAsync(user);

            // 构建自定义ClaimsIdentity
            var claimsIdentity = new ClaimsIdentity(
                new Claim[] {
                    new Claim(ClaimTypes.Name, user.UserName),
                    new Claim("UniqueID", Guid.NewGuid().ToString()),
                    new Claim("TimeStamp", DateTime.UtcNow.ToString()),
                    new Claim(ClaimTypes.Role, userRoles[0])
                },
                BearerTokenDefaults.AuthenticationScheme
            );

            var authProperties = new AuthenticationProperties {
                IsPersistent = true,
                AllowRefresh = true,
                ExpiresUtc = DateTimeOffset.UtcNow.AddHours(5)
            };

            // 调用SignInManager完成登录,自动生成Bearer Token
            await _signInManager.SignInAsync(user, authProperties, claimsIdentity);

            // 返回用户信息(如需直接返回Token,需额外配置或自定义提取逻辑)
            return Ok(new {
                UserName = user.UserName,
                Role = userRoles[0]
            });
        } else {
            return BadRequest("Invalid credentials");
        }
    } catch (Exception ex) {
        return BadRequest(ex.Message);
    }
}

方案二:直接操作HttpContext的SignInAsync方法

不依赖SignInManager,直接通过HttpContext扩展方法触发Token生成:

[HttpPost]
[Route("RequestToken")]
public async Task<IActionResult> RequestToken([FromBody] Login model) {
    try {
        var user = await _userManager.FindByNameAsync(model.DeviceName);
        if (user != null && await _userManager.CheckPasswordAsync(user, model.Password)) {
            var userRoles = await _userManager.GetRolesAsync(user);

            var claimsPrincipal = new ClaimsPrincipal(
                new ClaimsIdentity(
                    new Claim[] {
                        new Claim(ClaimTypes.Name, user.UserName),
                        new Claim("UniqueID", Guid.NewGuid().ToString()),
                        new Claim("TimeStamp", DateTime.UtcNow.ToString()),
                        new Claim(ClaimTypes.Role, userRoles[0])
                    },
                    BearerTokenDefaults.AuthenticationScheme
                )
            );

            var authProperties = new AuthenticationProperties {
                IsPersistent = true,
                AllowRefresh = true,
                ExpiresUtc = DateTimeOffset.UtcNow.AddHours(5)
            };

            // 调用HttpContext的SignInAsync,触发Token生成逻辑
            await HttpContext.SignInAsync(BearerTokenDefaults.AuthenticationScheme, claimsPrincipal, authProperties);

            return Ok(new { Message = "Login successful" });
        } else {
            return BadRequest("Invalid credentials");
        }
    } catch (Exception ex) {
        return BadRequest(ex.Message);
    }
}

额外注意事项

确保在Program.cs中正确配置Bearer Token服务:

builder.Services.AddAuthentication(BearerTokenDefaults.AuthenticationScheme)
    .AddBearerToken();
builder.Services.AddAuthorization();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 08:59:59