C#使用Web API进行自定义授权

时间:2014-03-18 08:07:16

标签: c# asp.net-mvc asp.net-web-api

我正在设计一个WebAPI项目,我的第一个控制器是LoginController。用户登录如下:

    [ActionName("Login")]
    [AcceptVerbs("PUT")]
    [HttpPost]
    public HttpResponseMessage Login(DTO.LoginDetails loginDetails)
    {
        HttpResponseMessage response = null;
        DTO.User user = null;

        try
        {
                string connectionString = string.Empty;

                //Login the user
                user = Mapper.Map<DTO.User>(loginService.Login(loginDetails.Username,
                                                               Md5.Encrypt(loginDetails.Password));

                if (user != null)
                {
                    //Create session for the user
                    DTO.Session session = new DTO.Session()
                    {
                        User = user,
                        Token = Guid.NewGuid().ToString()
                    };

                    //Create collection to store the cookie values
                    var nv = new NameValueCollection(3);
                    nv[SessionHandler.UserId] = user.Id.ToString();

                    //Create a cookie
                    var cookie = new CookieHeaderValue(SessionHandler.Session, nv)
                    {
                        Expires = DateTimeOffset.Now.AddDays(1),
                        Domain = Request.RequestUri.Host,
                        Path = "/"
                    };

                    response = Request.CreateResponse<DTO.Session>(HttpStatusCode.OK, session);
                    response.Headers.AddCookies(new CookieHeaderValue[] { cookie });
                }

                //Login failed
                else
                {
                    response = Request.CreateErrorResponse(HttpStatusCode.Unauthorized, new HttpError("User or connectionstring is null or empty"));
                }
            }
        }
        catch (Exception ex)
        {
            response = Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
            logService.Logger().Error("Login failed", ex);
        }

        return response;
    }

我还有一个DelegatingHandler,它从每个请求中获取上述cookie。目前它只是从请求中获取cookie。

用户存储在数据库表中,并根据此表进行验证。表中的每个用户都有4个显式权限(CRUD),以确定他是否可以对实体(客户,产品等)执行操作。

所以我的问题:

  1. 成功登录后将用户存储在MemoryCache中是否是一个好主意,这样我就可以避免往数据库的往返以验证用户是否已经过身份验证?

  2. 如何使用自定义Authorize属性确保用户有权对实体执行操作?该代码应该是控制器还是服务级别?

  3. 登录控制器用[AllowAnonymous]修饰,而所有其他控制器都不是。但是我的DelegatingHandler是系统范围的。我应该将控制器移动到他们自己的区域并将登录控制器留在主区域吗?

1 个答案:

答案 0 :(得分:0)

  1. 不确定。最好让用户先缓存并从缓存中获取用户,如果错过了数据库(通过存储在cookie和db中的密钥 - 比如LastSessionId)。
  2. 最好是用户(或代码中的Session)类从GenericPrincipal接口派生并覆盖/添加一些代码来管理Roles集合。所以IsInRole方法适合你(由AuthorizeAttribute使用)。 IUserPrincipal是您自己的界面,用于添加所需的行为/数据。所以它的自定义属性无关紧要,它可以在控制器级别正常工作

     class UserPrincipal : GenericPrincipal, IUserPrincipal
    
  3. 我认为不是:)