Asp.net WebApi의 사용자 지정 인증-엉망입니까?
WebApi의 인증에 대한 여러 리소스 (책 및 SO 답변)에서 읽고 있습니다.
특정 사용자에게만 액세스를 허용하는 사용자 정의 속성을 추가한다고 가정합니다.
사례 # 1
나는 무언가가 잘못되면 응답을 설정하는 재정의 접근 방식을 보았습니다.OnAuthorization
public class AllowOnlyCertainUsers : AuthorizeAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
if ( /*check if user OK or not*/)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
}
}
사례 # 2
그러나 나는 또한 재정의 OnAuthorization
하지만 다음을 호출 하는 유사한 예제를 보았습니다 base
.
public override void OnAuthorization(HttpActionContext actionContext)
{
base.OnAuthorization(actionContext);
// If not authorized at all, don't bother
if (actionContext.Response == null)
{
//...
}
}
그런 다음 HttpActionContext.Response
이 설정되어 있는지 확인합니다 . 설정되지 않은 경우 요청이 승인되고 사용자가 정상임을 의미합니다.
사례 # 3
그러나 나는 재정의하는이 접근 방식을 보았습니다 IsAuthorized
.
public class AllowOnlyCertainUsers : AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext context)
{
if ( /*check if user OK or not*/)
{
return true;// or false
}
}
}
사례 # 4
그리고 비슷한 예제 1을 보았지만 base.IsAuthorized (context)를 호출했습니다.
protected override bool IsAuthorized(HttpActionContext context)
{
if (something1 && something2 && base.IsAuthorized(context)) //??
return true;
return false;
}
하나 더
그리고 마침내 Dominick는 여기에서 말했습니다 .
OnAuthorization을 재정의해서는 안됩니다. [AllowAnonymous] 처리가 누락 될 수 있기 때문입니다.
질문
1) 내가 사용해야하는 방법 :
IsAuthorized
나OnAuthorization
? (또는 사용시기)2) 언제
base.IsAuthorized or
base.OnAuthorization`을 호출 해야합니까?3) 이것이 그들이 그것을 만든 방법입니까? 응답이 null이면 모든 것이 정상입니까? (케이스 # 2)
NB
나는 AuthorizeAttribute
이미 상속받은 것만 사용하고 있습니다 (사용하고 싶습니다)AuthorizationFilterAttribute
왜 ?
나는 첫 번째 단계에 있기 때문에 : http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api
어쨌든 확장 Authorize 속성을 통해 요청합니다.
어떤 방법을 사용해야합니까 : IsAuthorized 또는 OnAuthorization? (또는 사용시기)
You will extend AuthorizationFilterAttribute
if your authorization logic is not dependent on the identity established and roles. For user related authorization, you will extend and use AuthorizeAttribute
. For the former case, you will override OnAuthorization
. For the latter case, you will override IsAuthorized
. As you could see from the source code of these attributes, OnAuthorization
is marked virtual for you to override if you derive from AuthorizationFilterAttribute
. On the other hand, the IsAuthorized
method is marked virtual in AuthorizeAttribute
. I believe this is a good pointer to the intended usage.
when should I call base.IsAuthorized or base.OnAuthorization?
The answer to this question lies in how OO generally works. If you override a method, you can either completely provide a new implementation or piggy back on the implementation provided by parent and enhance the behavior. For example, take the case of IsAuthorized(HttpActionContext)
. The base class behavior is to check the user/role against what is specified in the filter vs the identity established. Say, you want to do all that but in addition, you want to check something else, may be based on a request header or something. In that case, you can provide an override like this.
protected override bool IsAuthorized(HttpActionContext actionContext)
{
bool isAuthroized = base.IsAuthorized(actionContext);
// Here you look at the header and do your additional stuff based on actionContext
// and store the result in isRequestHeaderOk
// Then, you can combine the results
// return isAuthorized && isRequestHeaderOk;
}
I'm sorry but don't understand your Q3. BTW, Authorization filter has been around for a long time and people use it for all kinds of things and sometimes incorrectly as well.
One more thing. And finally there was this guy here who said : You shouldn't override OnAuthorization - because you would be missing [AllowAnonymous] handling.
The guy who said that is the God of access control - Dominick. Obviously it will be correct. If you look at the implementation of OnAuthorization
(copied below),
public override void OnAuthorization(HttpActionContext actionContext)
{
if (actionContext == null)
{
throw Error.ArgumentNull("actionContext");
}
if (SkipAuthorization(actionContext))
{
return;
}
if (!IsAuthorized(actionContext))
{
HandleUnauthorizedRequest(actionContext);
}
}
the call to SkipAuthorization
is the part that ensures AllowAnonymous
filters are applied, that is, authorization is skipped. If you override this method, you loose that behavior. Actually, if you decide to base your authorization on users/roles, at that point you would have decided to derive from AuthorizeAttribute
. Only correct option left for you at that point will be to override IsAuthorized
and not the already overridden OnAuthorization
, although it is technically possible to do either.
PS. In ASP.NET Web API, there is another filter called authentication filter. Idea is that you use that for authentication and authorization filter for authorization, as the name indicates. However, there are lots of examples where this boundary is fudged. Lots of authroization filter examples will do some kind of authentication. Anyways, if you have time and want to understand a bit more, take a look at this MSDN article. Disclaimer: It was written by me.
Ok, my suggestion is to do the following assuming that you are using OAuth bearer tokens to protect your Web API and you are setting the allowedTime as a claim for the user when you issued the token. You can read more about token based authentication here
- Create CustomAuthorizeAttribute which derives from AuthorizationFilterAttribute
override method
OnAuthorizationAsync
and use the sample code below:public class CustomAuthorizeAttribute : AuthorizationFilterAttribute { public override Task OnAuthorizationAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken) { var principal = actionContext.RequestContext.Principal as ClaimsPrincipal; if (!principal.Identity.IsAuthenticated) { return Task.FromResult<object>(null); } var userName = principal.FindFirst(ClaimTypes.Name).Value; var userAllowedTime = principal.FindFirst("userAllowedTime").Value; if (currentTime != userAllowedTime) { actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, "Not allowed to access...bla bla"); return Task.FromResult<object>(null); } //User is Authorized, complete execution return Task.FromResult<object>(null); } }
- Now in your controllers you use CustomAuthorize attribute to protect your controllers using this authorization logic.
ASP.NET v5 Introduced a completely new Authorization System. For those who are going to Use .NET 5 i would suggest moving into Microsoft.AspNet.Authorization.
Pretty much it wraps up the mess caused by keeping both System.Web.Http.Authorize
and System.Web.Mvc.Authorize
and other older authentication implementations.
It provides a very good abstraction of Action Types(Create, Read, Update, Delete), Resources, Roles, Claims, Views, Custom Requirements and allows to build custom Handlers, combining any of the above. In addition those handlers can be used in combination also.
In ASP.NET v5 authorization now provides simple declarative role and a richer policy based model where authorization is expressed in requirements and handlers evaluate a users claims against requirements. Imperative checks can be based on simple policies or polices which evaluate both the user identity and properties of the resource that the user is attempting to access.
참고URL : https://stackoverflow.com/questions/26464848/custom-authorization-in-asp-net-webapi-what-a-mess
'Programming' 카테고리의 다른 글
Pandas 데이터 프레임에서 문자열 패턴을 포함하는 행을 필터링하는 방법 (0) | 2020.08.12 |
---|---|
Windows 용 MSysGit 대 Git (0) | 2020.08.12 |
const 문자열 대 c #의 정적 읽기 전용 문자열 (0) | 2020.08.11 |
C #에서 "사용되지 않음"및 "할당되지 않음"경고 표시 안 함 (0) | 2020.08.11 |
html5 오디오 태그를 스타일링 할 수 있습니까? (0) | 2020.08.11 |