4

ルーティング制約を追加した後、このルーティング制約が適用されている URL に移動すると、アプリケーションが承認属性フィルターを実行しなくなっていることに気付きました。

FilterConfig.cs

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new AuthorizeAttribute());
}

ProjectsController.cs

public class ProjectsController : Controller
{
    private IRepository<Project> repository;

    public ProjectsController()
    {
        repository = new Repository<Project>();
    }

    public ActionResult Edit(int id)
    {
        Project project = repository.FindById(id);

        if (project == null)
            return HttpNotFound();

        ProjectsEditViewModel projectVM = new ProjectsEditViewModel(project);

        return View("Edit", projectVM);
    }
}

RouteConfig.cs

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "ProjectEdit",
            url: "Projects/Edit/{id}",
            defaults: new { controller = "Projects", action = "Edit" },
            constraints: new { id = new IsValidProjectConstraint() }
        );
    }
}

IsValidProjectConstraint.cs

public class IsValidProjectConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        IRepository<Project> projectsRepository = new Repository<Project>();

        try
        {
            int iProjectId;
            Project project;

            // Check for valid id
            if (int.TryParse(values["id"].ToString(), out iProjectId))
            {
                project = projectsRepository.FindById(iProjectId);

                // Check if this project exists
                if (project == null)
                {
                    return false;
                }
            }
            else
            {
                return false;
            }

            // If we made it here everything is good
            return true;
        }
        catch (Exception ex)
        {
            Log.WriteLine(ex.ToString());
            return false;
        }
    }
}

Web.Config

<authentication mode="Forms">
  <forms loginUrl="~/SAML/saml2" timeout="2880" />
</authentication>

このルーティング制約を追加した後http://myurl/Projects/Edit/1、新しいブラウザーで に移動すると、実際には、既に認証されているかのようにページがレンダリングされます。ただし、ルーティングの制約を削除してからに移動するhttp://myurl/Projects/Edit/1と、期待どおりにログイン アクションにリダイレクトされます。

私のカスタムルート制約であろうと、単なる正規表現であろうと、ルート制約がこの問題を引き起こしているようです。

私がここに欠けているものはありますか??

編集: FormsAuthentication cookie の発行方法について言及する必要があると思います。アプリケーションは SAML サービス プロバイダーとして機能し、ID プロバイダーからの SAML 応答がアサーション コンシューマー サービスに送信されます。acs は SAML 応答を解析して検証し、次のコードを使用して認証チケットを発行します。

private void IssueAuthTicket(User userData)
{
    FormsAuthenticationTicket ticket =
        new FormsAuthenticationTicket(1, userData.UserName,
            DateTime.Now, DateTime.Now.AddMinutes(30),
            rememberMe, userData.Id.ToString());

    string ticketString = FormsAuthentication.Encrypt(ticket);

    HttpCookie cookie =
        new HttpCookie(FormsAuthentication.FormsCookieName, ticketString);

    HttpContext.Response.Cookies.Add(cookie);
}
4

1 に答える 1

2

ここでの問題は、MVC が authorize 属性の前にルーティング制約を実行することです。ここで直面していた問題は、ルートを次のように定義していたことです。

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "ProjectEdit",
        url: "Projects/Edit/{id}",
        defaults: new { controller = "Projects", action = "Edit" },
        constraints: new { id = new IsValidProjectConstraint() }
    );

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}",
        defaults: new { controller = "Home", action = "Index" }
    );

    routes.MapRoute(
        name: "404-PageNotFound",
        url: "{*url}",
        defaults: new { controller = "Errors", action = "NotFound" }
    );
}

そのため、ルーティング制約IsValidProjectConstraint()が false を返した場合、NotFoundコントローラーのアクションErrorsが実行されます。この場合、Userオブジェクトが null のときにエラーが発生したため、常に false を返していました。残念ながら[AllowAnonymous]、コントローラーにエラーページのレンダリングを許可する属性があったため、MVC がフィルターErrorsを実行していないように見えました。AuthorizeAttribute

于 2013-04-01T15:46:25.373 に答える