Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用媒体格式化程序时在Web API中绕过的AuthorizeAttribute_C#_Odata_Asp.net Web Api2 - Fatal编程技术网

C# 使用媒体格式化程序时在Web API中绕过的AuthorizeAttribute

C# 使用媒体格式化程序时在Web API中绕过的AuthorizeAttribute,c#,odata,asp.net-web-api2,C#,Odata,Asp.net Web Api2,我创建了一个web api应用程序,将ODataAPI公开给前端应用程序。这样做的原因之一是能够为相同的数据返回不同的内容类型,例如Excel文件 我使用了自定义媒体格式化程序来输出Excel数据,但是,我注意到,当我从客户端调用它时,没有安全性 在进行GET时,如果没有ACCEPT头,则会检查OAuth承载令牌,并接受或撤销访问。通过控制器上的[授权]设置授权 当我进行相同的GET时,ACCEPT头被设置为请求一个Excel文件,不管令牌是什么,都会调用控制器,从而绕过控制器上的安全性 很明显

我创建了一个web api应用程序,将ODataAPI公开给前端应用程序。这样做的原因之一是能够为相同的数据返回不同的内容类型,例如Excel文件

我使用了自定义媒体格式化程序来输出Excel数据,但是,我注意到,当我从客户端调用它时,没有安全性

在进行GET时,如果没有ACCEPT头,则会检查OAuth承载令牌,并接受或撤销访问。通过控制器上的[授权]设置授权

当我进行相同的GET时,ACCEPT头被设置为请求一个Excel文件,不管令牌是什么,都会调用控制器,从而绕过控制器上的安全性

很明显,我做错了什么,但我不知道会是什么。它是同一个控制器,但由于某些原因,当ACCEPT设置为受支持的媒体类型时,它始终允许访问

下面是我的设置的简化版本

Owin启动:

[assembly: OwinStartup(typeof(Rest.Startup))]

namespace Rest
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureOAuth(app);
            HttpConfiguration config = new HttpConfiguration();
            WebApiConfig.Register(config);
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            app.UseWebApi(config);
        }

        private void ConfigureOAuth(IAppBuilder app)
        {
            OAuthAuthorizationServerOptions oauthServerOptions = new OAuthAuthorizationServerOptions
            {
                AllowInsecureHttp = true,
                TokenEndpointPath = new PathString("/token"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                Provider = new SimpleAuthorisationServerProvider()
            };

            // Token generation
            app.UseOAuthAuthorizationServer(oauthServerOptions);
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
        }
    }
}
对WebApiConfig.Register()的调用

我的媒体格式化程序(删除代码以节省空间):

示例/简化控制器:

namespace Rest.Controllers
{
    [Authorize]
    public class TestController : ApiController
    {
        private dbSDSContext db = new dbSDSContext();

        // GET: api/Test
        public IQueryable<test> GetTests()
        {
            return db.test;
        }

        // GET: api/Test/5
        [ResponseType(typeof(test))]
        public async Task<IHttpActionResult> GetTest(int id)
        {
            test test = await db.test.FindAsync(id);
            if (test == null)
            {
                return NotFound();
            }

            return Ok(test);
        }

        // PUT: api/Test/5
        [ResponseType(typeof(void))]
        public async Task<IHttpActionResult> PutTest(int id, test test)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            if (id != test.testID)
            {
                return BadRequest();
            }

            db.Entry(test).State = EntityState.Modified;

            try
            {
                await db.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!TestExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return StatusCode(HttpStatusCode.NoContent);
        }

        // POST: api/Test
        [ResponseType(typeof(test))]
        public async Task<IHttpActionResult> PostTest(test test)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            db.test.Add(test);
            await db.SaveChangesAsync();

            return CreatedAtRoute("DefaultApi", new { id = test.testID}, test);
        }

        // DELETE: api/Test/5
        [ResponseType(typeof(test))]
        public async Task<IHttpActionResult> DeleteTest(int id)
        {
            test test = await db.test.FindAsync(id);
            if (test == null)
            {
                return NotFound();
            }

            db.test.Remove(test);
            await db.SaveChangesAsync();

            return Ok(test);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }

        private bool TestExists(int id)
        {
            return db.test.Count(e => e.testID == id) > 0;
        }
    }
}
名称空间Rest.Controllers
{
[授权]
公共类TestController:ApicController
{
私有dbSDSContext db=新的dbSDSContext();
//获取:api/测试
公共IQueryable GetTests()
{
返回db.test;
}
//获取:api/Test/5
[响应类型(类型(测试))]
公共异步任务GetTest(int-id)
{
test test=wait db.test.FindAsync(id);
if(test==null)
{
返回NotFound();
}
返回Ok(测试);
}
//PUT:api/Test/5
[响应类型(typeof(void))]
公共异步任务PutTest(int-id,test-test)
{
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
if(id!=test.testID)
{
返回请求();
}
db.Entry(test).State=EntityState.Modified;
尝试
{
等待db.saveChangesSync();
}
catch(DbUpdateConcurrencyException)
{
如果(!TestExists(id))
{
返回NotFound();
}
其他的
{
投掷;
}
}
返回状态码(HttpStatusCode.NoContent);
}
//职位:api/测试
[响应类型(类型(测试))]
公共异步任务后测试(测试)
{
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
db.test.Add(测试);
等待db.saveChangesSync();
返回CreatedAtRoute(“DefaultApi”,new{id=test.testID},test);
}
//删除:api/Test/5
[响应类型(类型(测试))]
公共异步任务DeleteTest(int-id)
{
test test=wait db.test.FindAsync(id);
if(test==null)
{
返回NotFound();
}
db.test.Remove(测试);
等待db.saveChangesSync();
返回Ok(测试);
}
受保护的覆盖无效处置(布尔处置)
{
如果(处置)
{
db.Dispose();
}
基地。处置(处置);
}
私有bool TestExists(int-id)
{
返回db.test.Count(e=>e.testID==id)>0;
}
}
}

该错误是由于在受影响的控制器中使用了错误的命名空间造成的

使用WebAPI时,请确保使用:

using System.Web.Http;
而不是:

using System.Web.Mvc;

奇怪。你能用一个完全简化的例子来证实吗?我已经添加了一个简化版本的代码。当将Accept标头设置为有效的内容类型(甚至是匿名用户)时,将调用控制器。发出应用程序/json请求时不会发生这种情况,它会正确地拒绝访问。然后,您是否可以在错误调用的方法中添加一行,以检查
上下文的值。User
?我想知道在请求的生命周期中设置了什么用户,所以绕过了
授权
。@WiktorZychla感谢您的输入。事实证明,我使用的是System.Web.Mvc.AuthorizeAttribute,而不是System.Web.Http.AuthorizeAttribute。很高兴您解决了这个问题,而且框架本身并不是一个巨大的安全漏洞。
using System.Web.Http;
using System.Web.Mvc;