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

ASP.NET Core MVC自定义Cookie认证下用户资料编辑功能异常及越权访问问题求助

ASP.NET Core MVC自定义Cookie认证下用户资料编辑功能异常及越权访问问题求助

大家好,我正在做一个ASP.NET Core MVC项目练手,已经实现了用户登录、注册和登出的基础功能,但在添加编辑用户资料功能时遇到了一系列问题,想请教一下各位:

最开始的问题是,编辑用户资料的Action里,Guid类型的Id参数总是传入空Guid({00000000-0000-0000-0000-000000000000}),而不是当前登录用户的真实Id,导致ModelState无效,而且整个过程没有抛出任何异常,我不知道该怎么正确验证用户Id来让功能正常运行。另外说明一下,我用的是自己自定义的Cookie认证,没有使用Identity框架。

后来我调试了一番,调整了登录后将用户Id传递到视图和控制器的逻辑,甚至重新写了UpdateProfile方法,但又遇到了更棘手的问题:任何登录用户都可以通过修改URL里的Guid参数,访问其他用户的资料编辑页面。比如我把URL改成localhost:44334/Users/UpdateProfile/19F17789-A52D-4752-5372-08DBA10B2W69,就能进入对应用户的编辑页面。我一开始只给UpdateProfile的一个Action加了[Authorize]特性,结果没生效,后来给两个Action都加上才限制了只有登录用户能访问,但越权访问其他用户页面的核心问题还是没解决。

下面是我相关的代码,麻烦各位帮忙看看哪里出问题了:

处理登录登出的LogUsersController

public class LogUsersController : Controller
{
    private readonly ILogger<LogUsersController> _logger;
    private readonly TheAppContext _context;

    public static int CanUserLogout; //0/CANT, 1/CAN
    public static string DisplayedUsername;
    public static Guid DisplayedUserId; // Add this field

    public LogUsersController(TheAppContext context, ILogger<LogUsersController> logger)
    {
        _context = context;
        _logger = logger;
    }

    public ActionResult Expired()
    {
        CanUserLogout = 0;
        TempData["Message"] = "★ Please sign-in to gain access...";
        return RedirectToAction("Login", "Logusers");
    }

    public IActionResult Index()
    {
        return View();
    }

    public IActionResult Login()
    {
        ViewBag.msg = TempData["Message"];
        return View();
    }

    [AllowAnonymous]
    [HttpPost]
    public async Task<IActionResult> Login(Users login) //login users
    {
        if(IsValidUser(login.Username, login.Password))
        {
            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.Name, login.Username),
                new Claim(ClaimTypes.Role, "User"),
            };

            var claimsIdentity = new ClaimsIdentity(
                claims, CookieAuthenticationDefaults.AuthenticationScheme);

            var authProperties = new AuthenticationProperties
            {
                IsPersistent = false,
            };

            await HttpContext.SignInAsync(
                CookieAuthenticationDefaults.AuthenticationScheme,
                new ClaimsPrincipal(claimsIdentity),
                authProperties);

            _logger.LogInformation($"login.Id: {login.Id}");
            DisplayedUsername = "@" + login.Username;
            CanUserLogout = 1;

            return RedirectToAction("Index", "Home");
        }
        else
        {
            ViewBag.message = "Failed to login with @" + login.Username + ", please try again later..";
            return View();
        }
    }

    private bool IsValidUser(string username, string password)
    {
        var user = _context.Users.FirstOrDefault(u => u.Username == username && u.Password == password);
        if (user != null)
        {
            _logger.LogInformation("User found: Username = {Username}, Id = {UserId}", user.Username, user.Id);
            DisplayedUserId = user.Id; // Store the user's ID here
            return true;
        }
        _logger.LogInformation("Login failed for username: {Username}", username);
        return false;
    }

    [Authorize]
    public async Task<ActionResult> Logout()
    {
        await HttpContext.SignOutAsync(
            CookieAuthenticationDefaults.AuthenticationScheme);
        CanUserLogout = 0;
        return RedirectToAction("Login", "Logusers");
    }
}

_Layout.cshtml中的导航部分

<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
    <ul class="navbar-nav flex-grow-1">
        <li class="nav-item">
            <a class="nav-link text-white" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
        </li>
        <li class="nav-item">
            <a class="nav-link text-white" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
        </li>
        @if (TheApp.Controllers.LogUsersController.CanUserLogout == 1){
        <li class="nav-item">
            <a class="nav-link text-white" asp-area="" asp-controller="Logusers" asp-action="Logout">Logout</a>
        </li>
        <li class="nav-item">
            <a class="navbar-text text-white font-italic">Hello there,  @TheApp.Controllers.LogUsersController.DisplayedUsername!</a>
        </li>
        <li class="nav-item">
            <a class="nav-link text-white" asp-controller="Users" asp-action="UpdateProfile" asp-route-id="@TheApp.Controllers.LogUsersController.DisplayedUserId">Profile</a>
        </li>
        }
        else
        {
        <li class="nav-item">
            <a class="nav-link text-white" asp-area="" asp-controller="Logusers" asp-action="Login">Login</a>
        </li>
        <li class="nav-item">
            <a class="nav-link text-white" asp-area="" asp-controller="Users" asp-action="Create">Register</a>
        </li>
        }
    </ul>
</div>

处理用户注册和资料更新的UsersController

public class UsersController : Controller
{
    private readonly TheAppContext _context;

    public UsersController(TheAppContext context)
    {
        _context = context;
    }

    public IActionResult Index()
    {
        return View();
    }

    public IActionResult Create()
    {
        return View();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult Create(Users uc) //register users
    {
        _context.Add(uc);
        _context.SaveChanges();
        return View(uc);
    }

    [Authorize]
    public IActionResult UpdateProfile(Guid id)
    {
        Users user = _context.Users.SingleOrDefault(u => u.Id == id);
        if (user != null)
        {
            return View(user);
        }
        else
        {
            return NotFound();
        }
    }

    [Authorize]
    [HttpPost]
    public IActionResult UpdateProfile(Users updatedUser)
    {
        if (ModelState.IsValid)
        {
            Users existingUser = _context.Users.FirstOrDefault(u => u.Id == updatedUser.Id);
            if (existingUser != null)
            {
                existingUser.Name = updatedUser.Name;
                existingUser.Email = updatedUser.Email;
                existingUser.Username = updatedUser.Username;
                existingUser.Password = updatedUser.Password;
                existingUser.ConfirmPass = updatedUser.ConfirmPass;
                _context.SaveChanges();
                return RedirectToAction("Index", "Home");
            }
            else
            {
                return NotFound();
            }
        }
        return View(updatedUser);
    }
}

备注:内容来源于stack exchange,提问作者Tutorial Hell Veteran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 15:22:59