웹 API에서 여러 필터를 사용한 실행 순서
최신 버전을 사용하고 있습니다.web api
.
3가지 필터 특성을 가진 일부 컨트롤러에는 주석을 달지 않습니다.
1 [Authorize]
2 [RessourceOwnerAttribute derived from AuthorizationFilterAttribute]
3 [InvalidModelStateAttribute derived from ActionFilterAttribute]
필터가 위에서 아래로 선언된 순서대로 실행되는지 확신할 수 없습니다.
다음에서 실행 순서를 정의하려면 어떻게 합니까?web api 2.1
?
https://aspnetwebstack.codeplex.com/workitem/1065 #
제가 아직도 그걸 스스로 고쳐야 하나요?
여기서 주의해야 할 몇 가지 사항:
- 필터는 작업에 대해 다음 순서로 실행됩니다.전역적으로 정의된 필터 -> 컨트롤러별 필터 -> 작업별 필터.
- 권한 부여 필터 -> 작업 필터 -> 예외 필터
이제 언급하신 것처럼 보이는 문제는 같은 종류의 필터를 여러 개 갖는 것과 관련이 있습니다(예: 다중).
ActionFilterAttribute
컨트롤러 또는 동작에 장식됩니다.이것은 반영에 근거한 주문을 보증하지 않는 경우입니다.)이 경우, 웹 API에서 사용자 정의 구현을 사용하는 방법이 있습니다.System.Web.Http.Filters.IFilterProvider
저는 다음을 시도했고 그것을 검증하기 위해 몇 가지 테스트를 했습니다.잘 될 것 같습니다.한 번 시도해 보시고 예상하신 대로 작동하는지 확인해보세요.// Start clean by replacing with filter provider for global configuration. // For these globally added filters we need not do any ordering as filters are // executed in the order they are added to the filter collection config.Services.Replace(typeof(IFilterProvider), new System.Web.Http.Filters.ConfigurationFilterProvider()); // Custom action filter provider which does ordering config.Services.Add(typeof(IFilterProvider), new OrderedFilterProvider());
public class OrderedFilterProvider : IFilterProvider { public IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor) { // controller-specific IEnumerable<FilterInfo> controllerSpecificFilters = OrderFilters(actionDescriptor.ControllerDescriptor.GetFilters(), FilterScope.Controller); // action-specific IEnumerable<FilterInfo> actionSpecificFilters = OrderFilters(actionDescriptor.GetFilters(), FilterScope.Action); return controllerSpecificFilters.Concat(actionSpecificFilters); } private IEnumerable<FilterInfo> OrderFilters(IEnumerable<IFilter> filters, FilterScope scope) { return filters.OfType<IOrderedFilter>() .OrderBy(filter => filter.Order) .Select(instance => new FilterInfo(instance, scope)); } }
//NOTE: Here I am creating base attributes which you would need to inherit from. public interface IOrderedFilter : IFilter { int Order { get; set; } } public class ActionFilterWithOrderAttribute : ActionFilterAttribute, IOrderedFilter { public int Order { get; set; } } public class AuthorizationFilterWithOrderAttribute : AuthorizationFilterAttribute, IOrderedFilter { public int Order { get; set; } } public class ExceptionFilterWithOrderAttribute : ExceptionFilterAttribute, IOrderedFilter { public int Order { get; set; } }
Kiran Challa의 답변에서 해결책에 약간의 문제가 있었습니다.이것이 제가 수정한 것입니다.
문제는 방법에 있었습니다.
private IEnumerable<FilterInfo> OrderFilters(IEnumerable<IFilter> filters, FilterScope scope)
{
return filters.OfType<IOrderedFilter>()
.OrderBy(filter => filter.Order)
.Select(instance => new FilterInfo(instance, scope));
}
를 구현하는 필터만 볼 수 있습니다.IOrderedFilter
돌려받을 것입니다.타사 속성이 삭제되어 실행되지 않았습니다.
그래서 저는 두 가지 가능한 해결책이 있었습니다.
- 상속을 사용하여 타사 특성의 확장 버전을 만들어 구현
IOrderFilter
너무. - 구현하지 않는 모든 속성을 처리하도록 방법 변경
IOrderFilter
좋아해를IOrderFilter
순서 번호가 0인 속성과 결합합니다.IOrderFilter
속성을 정렬하고 반환합니다.
두 번째 해결책은 내가 나의 것을 가져올 수 있게 해주기 때문에 더 낫습니다.IOrderFilter
구현하지 않는 타사 특성 앞의 특성IOrderFilter
.
샘플
[NonOrderableThirdPartyAttribute]
[OrderableAttributeA(Order = -1)]
[OrderableAttributeB(Order = 1)]
[OrderableAttributeC(Order = 2)]
public async Task<IHttpActionResult> Post(... request)
{
// do something
}
그래서 사형 집행은
- 주문 가능한 속성 A
- 주문 불가서드 파티 속성
- 순서 가능한 속성 B
- 순서 가능한 속성 C
그래서 여기 수정된 코드가 있습니다.
public class OrderedFilterProvider : IFilterProvider
{
public IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor)
{
// controller-specific
var controllerSpecificFilters = OrderFilters(actionDescriptor.ControllerDescriptor.GetFilters(), FilterScope.Controller);
// action-specific
var actionSpecificFilters = OrderFilters(actionDescriptor.GetFilters(), FilterScope.Action);
return controllerSpecificFilters.Concat(actionSpecificFilters);
}
private IEnumerable<FilterInfo> OrderFilters(IEnumerable<IFilter> filters, FilterScope scope)
{
// get all filter that dont implement IOrderedFilter and give them order number of 0
var notOrderableFilter = filters.Where(f => !(f is IOrderedFilter))
.Select(instance => new KeyValuePair<int, FilterInfo>(0, new FilterInfo(instance, scope)));
// get all filter that implement IOrderFilter and give them order number from the instance
var orderableFilter = filters.OfType<IOrderedFilter>().OrderBy(filter => filter.Order)
.Select(instance => new KeyValuePair<int, FilterInfo>(instance.Order, new FilterInfo(instance, scope)));
// concat lists => order => return
return notOrderableFilter.Concat(orderableFilter).OrderBy(x => x.Key).Select(y => y.Value);
}
}
asp.net core에서 IOrderedFilter를 사용하여 관리할 수 있습니다.
public class MyFilter : IActionFilter, IOrderedFilter
{
public int Order => 1; // define the order here
...
}
같은 종류의 필터가 여러 개 있는 경우 실행 순서는 글로벌 -> 컨트롤러 -> 액션입니다.
권한 부여 필터의 경우 여러 필터를 다른 수준으로 설정하면 "AND"와 결합되어 위의 실행 순서로 계산됩니다.
그리고 첫 번째 실패한 필터에서 인증 프로세스가 실패합니다.
자세한 내용은 이 게시물을 확인하시면 됩니다.
https://learn.microsoft.com/en-us/aspnet/core/security/authorization/roles?view=aspnetcore-2.1
MVC에서 여러 필터가 구현되는 경우 실행 순서는 다음과 같습니다.
- 권한 부여 필터
- 작업 필터
- 결과 필터
- 예외 필터
언급URL : https://stackoverflow.com/questions/21628467/order-of-execution-with-multiple-filters-in-web-api
'programing' 카테고리의 다른 글
스프링 부트 보안 - 우체부가 401을 무단으로 제공합니다. (0) | 2023.08.04 |
---|---|
디렉토리 구조에서 가장 큰 10개의 파일을 찾는 방법 (0) | 2023.08.04 |
케라스에서 HDF5 파일에서 모델을 로드하는 방법은 무엇입니까? (0) | 2023.08.04 |
NumberPicker에서 소프트 키보드 사용 (0) | 2023.08.04 |
포지셔닝포지셔닝화면 중앙의 요소 (0) | 2023.08.04 |