【问题标题】:Restrict area/controller to authenticated users将区域/控制器限制为经过身份验证的用户
【发布时间】:2014-01-07 17:27:47
【问题描述】:

我正在用 C# 构建一个 web api,这是我第一次使用 C# 构建一个 web api。没有什么特别的事情发生;我们调用存储过程,并将结果作为 JSON 返回。

我需要限制对经过身份验证的用户的访问。我将[Authorize] 添加到控制器中,即使用户已经通过身份验证,它也可以重定向到登录页面。 [Authorize] 没有按预期工作。有一个现有的应用程序,所以我不能更改任何全局设置。我该怎么办?

下面的代码示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

using XXXX.XXXX.Web.Areas.api.Models;

namespace XXXX.XXXX.Web.Areas.api.Controllers
{
    [Authorize]
    public class ReportController : Controller
    {
        //
       // GET: /api/Report/

        public ActionResult Index()
        {

             return View();
        }

        //
        // GET: /api/Report/RiskRatingSnapshot
        public JsonResult  RiskRollForward(string type)
        {

            var GET = Request.QueryString;

            if (type != "Details") type = "";

            var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["PaynetDatabase"].ConnectionString);
            var command = new SqlCommand("procPrptAPDPortMgrRollForwardDetails", connection)
            {
                CommandType = CommandType.StoredProcedure
            };

            command.Parameters.AddWithValue("@subid", 0);
            command.Parameters.AddWithValue("@portfolio", GET["portfolio"]);
            command.Parameters.AddWithValue("@currentDateKey", GET["currentDateKey"]);
            command.Parameters.AddWithValue("@priorDateKey", GET["priorDateKey"]);
            command.Parameters.AddWithValue("@exposureFrom", GET["exposureFrom"]);
            command.Parameters.AddWithValue("@exposureTo", GET["exposureTo"]);
            command.Parameters.AddWithValue("@APDSensitivity", GET["APDSensitivity"]);



             if (type == "Details")
            {

                command.Parameters.AddWithValue("@groupId", GET["groupId"]);
                connection.Open();
                SqlDataReader reader = command.ExecuteReader();

                var table = pack(reader);
                connection.Close();

                return Json(table, JsonRequestBehavior.AllowGet);
            /*************************************************************
            --Example:
            DECLARE @return_value int

            EXEC    @return_value = [dbo].[procPrptAPDPortMgrRollForwardDetails]
                    @subid = 0,
                    @portfolio = N'52,53',
                    @currentDateKey = 20111001,
                    @priorDateKey = 20110701,
                    @APDSensitivity = 0.25,
                    @exposureFrom = 0,
                    @exposureTo = 1000000000,
                    @groupId = 2


            GO
            **************************************************************/
            }
            return null;
        }

        private List<DetailsReport> pack(SqlDataReader reader)
        {
            List<DetailsReport> table = new List<DetailsReport>();
            while (reader.Read())
            {
                DetailsReport row = new DetailsReport();

                row.customer_number = reader["customer_number"].ToString();
                row.customer_name = reader["customer_name"].ToString();
                row.portfolio = Convert.ToInt32( reader["portfolio"].ToString() );
                row.portname = reader["portname"].ToString();
                row.state = reader["state"].ToString();
                row.exposure_cur = reader["exposure_cur"].ToString();
                row.exposure_chg = reader["exposure_chg"].ToString();
                row.number_of_lenders = Convert.ToInt32( reader["number_of_lenders"].ToString() );
                row.member_lender_business_unit = reader["member_lender_business_unit"].ToString();
                row.LastKnownDel = reader["LastKnownDel"].ToString();
                row.CurDelStatus = reader["CurDelStatus"].ToString();
                row.PayNet_absolutePD_4q = reader["PayNet_absolutePD_4q"].ToString();
                row.APD_4QChg = reader["4QAPD_Chg"].ToString();
                row.PD_chg_wtd_cur_exp = reader["PD_chg_wtd_cur_exp"].ToString();
                row.expWtdPD_cur = reader["ExpWtdPD_cur"].ToString();
                row.expWtdPD_chg = reader["expWtdPD_chg"].ToString();


                table.Add(row);

            }

            return table;
        }
    }

 }

【问题讨论】:

  • 你对我的问题不是很清楚......你是说[Authorize] 将用户重定向到登录页面,这是它应该做的,但它恰好一个用户,即使他们已经通过了身份验证?
  • @MikeMarks 是的,每次我访问上述控制器的 url 时,我都会被重定向到登录页面,EVEN 当我登录时。

标签: c# asp.net asp.net-mvc-3


【解决方案1】:

我通过实现我自己的从 ActionFilterAttribute 继承的类并在其中执行验证来做了类似的事情(在这种情况下,检查当前用户是否在 AD 组中)。通过覆盖 OnActionExecuting 方法,您可以访问 HttpActionContext,我认为这在您想要实现的过程中发生得足够早。然后,您可以抛出 HttpResponseException 并包含如下自定义消息:

         var msg = string.Format("User {0} attempted to use {1} but is not a member of the AD group.", id, actionContext.Request.Method);
        _logger.Info(msg);
        throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Unauthorized)
        {
            Content = new StringContent(msg),
            ReasonPhrase = msg
        });

希望这会有所帮助! MSDN上有演练here

编辑:不久前我在这个线程here 中给出了一个更好的例子。

【讨论】:

    【解决方案2】:

    扩展[Authorize] 以满足您的需求。下面提供了一个示例:

    控制器

    确保在您的控制器中包含新的辅助类,并使用[Helper.Authorize] 代替[Authorize]

    using XXXX.Online.Web.Areas.api.Helpers;
    

    扩展[授权]

    using System;
    using System.Web;
    using System.Web.Mvc;
    using XXXX.Online.Session;
    using XXXX.Online.Enums;
    
     namespace XXXX.Online.Web.Areas.api.Helpers
    {
        [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
        public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
        {
            public override void OnAuthorization(AuthorizationContext filterContext)
            {
               try
               {
                   PayNet.Online.Web.Security.CheckSession(System.Web.HttpContext.Current);
               }
               catch
               {
                   // Get the redirection URL for the request from the system.web/authentication section in the the web.config.
                   var authenticationSection = (System.Web.Configuration.AuthenticationSection)System.Configuration.ConfigurationManager.GetSection("system.web/authentication");
                   System.Web.Configuration.FormsAuthenticationConfiguration formsAuthentication = authenticationSection.Forms;
                   string currentLoginUrl = formsAuthentication.LoginUrl;
    
                   HttpContext.Current.Response.Redirect(currentLoginUrl, true);
               }
          }
       }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-10-09
      • 2019-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-02
      • 2020-11-15
      • 2018-03-18
      • 1970-01-01
      相关资源
      最近更新 更多