gpt4 book ai didi

asp.net-mvc-3 - 如何向经过身份验证但未经授权的用户显示未经授权的页面 MVC 3?

转载 作者:行者123 更新时间:2023-12-02 00:27:24 24 4
gpt4 key购买 nike

我有一个应用程序,其中一些用户属于角色,但实际上可能无法访问 URL 中的某些数据。例如下面的 url 是对所有用户开放的

/Library/GetFile/1

但是,某些用户可能无法访问 file1,但我无法使用 Authorize 属性来检测它。相反,我想将这些用户重定向到未经授权或拒绝访问的页面。我正在使用表单例份验证,我的配置是这样设置的

<authentication mode="Forms">
<forms loginUrl="~/Home/Index" timeout="2880" />
</authentication>

我的自定义错误 block 是这样的

<customErrors mode="On" defaultRedirect="Error" redirectMode="ResponseRewrite" >
<error statusCode="401" redirect="Unauthorized"/>
</customErrors>

如果用户没有访问权限,我试图返回 HttpUnauthorizedResult,但我只是被重定向到登录页面,这在这里无效,因为用户已经通过身份验证。


似乎 HttpUnauthorizedResult 将 HTTP 响应代码设置为 401,表单例份验证正在劫持并将用户发送到登录页面。

即使我已将 RegisterGlobalFilters 更新为

filters.Add(new HandleErrorAttribute
{
ExceptionType = typeof(UnauthorizedAccessException),
View = "Unauthorized",
Order = 3
});

如果我将 UnauthorizedAccessException 更改为自定义异常,则重定向会起作用,目前这就是我所做的。

最佳答案

除了我这样做之外,你的解决方案与我的相似:

  1. 创建自定义异常 UnauthorizedDataAccessException。

  2. 创建自定义异常过滤器(以便它可以记录无效访问尝试)。

  3. 在 App_start 中将我的自定义异常属性注册为全局过滤器。

  4. 创建一个标记接口(interface) ISecureOwner 并将其添加到我的实体中。

  5. 向我的存储库添加一个安全的“加载”扩展方法,如果当前用户不是所加载实体的所有者,该方法将抛出异常。为此,实体必须实现 ISecureOwner,它返回保存该实体的用户的 ID。

请注意,这只是展示了一种模式:如何实现 GetSecureUser 以及使用什么来检索数据的细节会有所不同。然而,尽管这种模式对于小型应用程序来说还可以,但它有点 hack,因为这种安全性应该在数据级别深入实现,使用数据库中的所有权组,这是另一个问题:)

    public class UnauthorizedDataAccessException : Exception
{
// constructors
}

public class UnauthorizedDataAccessAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if (filterContext.Exception.GetType() == Typeof(UnauthorizedDataAccessException))
{
// log error
filterContext.ExceptionHandled = true;
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Error", action = "UnauthorizedDataAccess" }));
}
else
{
base.OnException(filterContext);
}
}

// marker interface for entity and extension method
public interface ISecureOwner
{
Guid OwnerId { get; }
}

// extension method
public static T SecureFindOne<T>(this IRepository repository, Guid id) where T : class, ISecureOwner, new()
{
var user = GetSecureUser();
T entity = repository.FindOne<T>(id);

if (entity.OwnerId != user.GuidDatabaseId)
{
throw new UnauthorizedDataAccessException(string.Format("User id '{0}' attempted to access entity type {1}, id {2} but was not the owner. The real owner id is {3}.", user.GuidDatabaseId, typeof(T).Name, id, entity.OwnerId));
}

return entity;
}

// Register in global.asax
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
var filter = new UnauthorizedDataAccessAttribute { ExceptionType = typeof(UnauthorizedDataAccessException) };
filters.Add(filter);
filters.Add(new HandleErrorAttribute());
}

// Usage:
var ownedThing = myRepository.SecureFindOne<myEntity>(id))

关于asp.net-mvc-3 - 如何向经过身份验证但未经授权的用户显示未经授权的页面 MVC 3?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8348817/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com