注意:我在下面的代码注释中有很多问题。我也需要这些问题的答案。
我已阅读(除其他外)以下文章:
- http://blogs.msdn.com/b/hongmeig1/archive/2012/05/11/how-to-write-a-custom-parameter-binding-to-construct-an-object-either-from-body- or-from-uri-s-query.aspx
- http://blogs.msdn.com/b/jmstall/archive/2012/05/11/webapi-parameter-binding-under-the-hood.aspx
我希望我的 web api 使用 Authorization 标头在标头中发送身份验证。我希望将此标头填充到名为AuthenticationToken
. 然后,当我进行参数绑定时,我想检索这个先前创建的AuthenticationToken
对象并将其传递给我的控制器操作。例如,如果我有以下控制器
public class MyServiceController : ApiController {
readonly ISecurityService _security;
readonly IMyService _myService;
// constructor values are injected
public MyServiceController(ISecurityService security, IMyService myService) {
_security = security;
_myService = myService;
}
public SomeData GetASpecificItem(AuthenticationToken token, int id) {
if (_security.IsAuthorized(token, Permissions.Read)) {
return myService.DoStuffToGetSomeData(token);
} else {
var msg = new HttpResponseMessage(HttpStatusCode.Forbidden);
throw new HttpResponseException(msg);
}
}
}
和下面的参数绑定类
public class AuthenticationTokenParameterBinding
: HttpParameterBinding { // do I need to inherit from a different class?
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider,
HttpActionContext actionContext,
CancellationToken cancellationToken) {
try {
AuthenticationToken token; // UPDATED: how can i get this from the data
// available from inside this method?
SetValue(actionContext, token);
// is this the correct task to return on successfull parameter binding?
return base.ExecuteBindingAsyn(metadataProvider, actionContext, cancellationToken);
} catch {
return Task<HttpResponseMessage>.Factory.StartNew(() => {
var hpm = new HttpResponseMessage(HttpStatusCode.Unauthorized);
hpm.Headers.Add("WWW-Authenticate","MyCustomScheme");
return hpm;
});
}
}
}
如果这两个实现正确,那么控制器会自动获取AuthenticationToken
授权时创建的实例。
我不知道在此过程之前在哪里进行身份验证。我也不知道如何在身份验证和授权之间传递对象。
更新:
我不能使用自定义AuthorizeAttribute
,因为授权可能针对对象:
public SaveResponse Save(AuthenticationToken user, SomeObjectThatNeedsToBeSaved obj) {
// NOTE: permissions are checked between the object and the user, not a role
if (_security.IsAuthorized(user, obj, Permission.Modify, Permission.Create)) {
// NOTE: other permissions we don't know about may need to be checked in the service call
return new SaveResponse {
Success = ISomeService.Save(user, obj); // bool return value
}
} else {
// return 403 Forbidden }
}
我需要将令牌传递给控制器操作,但我还需要在令牌传递给控制器之前对其进行身份验证。由于所有这些都不一定基于角色,因此我看不到如何从自定义内部进行身份验证AuthorizeAttribute