繁体   English   中英

希望REST服务上的PrincipalPermission SecurityException返回403,而不是400 Bad Request

[英]Want a PrincipalPermission SecurityException on REST service to return 403, not 400 Bad Request

我有一个装饰有PrincipalPermission要求的RESTful(WCF)服务。 如果用户不担任该角色,而是获得400 BAD REQUEST ,则我希望得到403 FORBIDDEN响应。 经过反思,这很有意义-当委托人不担任角色时,需求触发SecurityException 这与通过web.config中的<authorization>标记授予访问权限不同。

但是,一个400 BAD REQUEST没有任何意义...该请求没有格式错误,我只是没有允许拨打电话的权限。 400响应表示我可以解决该请求,然后重试,但这将永远不会成功。

如何截获或映射SecurityException到更合适的响应(最好是403 FORBIDDEN )?


装饰方式:

[PrincipalPermission(SecurityAction.Demand, Role = "FST")]
public string TestNoPermissions(string NetworkId) {
    return "Call succeeded";
}

响应:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Request Error</title>
    <style>BODY { color: #000000; ...;}</style>
  </head>
  <body>
    <div id="content">
      <p class="heading1">Request Error</p>
      <p>The server encountered an error processing the request. The exception message is 'Access is denied.'. See server logs for more details. The exception stack trace is: </p>
      <p>   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]&amp; outputs)
            at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)
            at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)
            at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc)
            at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</p>
    </div>
  </body>
</html>

您可以实现IErrorHandler来拦截SecurityException 然后提供带有状态代码的WebFaultException

public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
    if (error is SecurityException)
    {
        var faultEx = new WebFaultException<string>("Forbidden", HttpStatusCode.Forbidden)

        fault = Message.CreateMessage(version, faultEx.CreateMessageFault(), null);
    }
}

请注意,这是未经测试的-安全异常有在框架/管道中迷失的讨厌习惯,但是这个想法需要较长的评论时间。

通常,您将添加具有行为的自定义IErrorHandler,可以在您的DI代码或config中对其进行配置。

public class ErrorHandlerBehavior : IServiceBehavior
{
    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
        // not implemented
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        foreach (var dispatcherBase in serviceHostBase.ChannelDispatchers)
        {
            var dispatcher = dispatcherBase as ChannelDispatcher;

            if (dispatcher != null)
                dispatcher.ErrorHandlers.Add(new MyCustomErrorHandler());
        }
    }

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        // not implemented
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM