今天我开始玩MVC 3 Beta.从默认MVC 3模板开始应用程序,在Home控制器中添加了一个新操作,如下所示(带有视图)
[Authorize]
public ActionResult Secured()
{
ViewModel.Message = "This is secured area, only authenticated users should be here.";
return View();
}
Run Code Online (Sandbox Code Playgroud)
现在,当我尝试导航到安全操作时,我得到404页面未找到错误.
这是我的web.config中的身份验证部分.
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
Run Code Online (Sandbox Code Playgroud)
如果我理解正确,Authorize属性应该导致401未经授权的HTTP响应,应该由身份验证处理程序拦截并将我重定向到loginUrl.哪个应该导致Account/LogOn操作.
我的MVC 2应用程序按预期工作,并将我带到Account/LogOn操作,我错过了什么?或者这是MVC 3 beta中的错误?
我的问题是AuthorizeCore方法是如何工作的?
例如,当我想创建自定义Authorize属性时,我发现很多程序员都使用这个代码
var isAuthorized = base.AuthorizeCore(httpContext);
if (!isAuthorized)
{
return false;
}
Run Code Online (Sandbox Code Playgroud)
然后他们编写自己的代码.
那么这段代码扮演的角色是什么,并且该方法仅检查管理员和计算机管理中的其他创建用户等Windows用户,如果我们自定义它以在表单身份验证中使用.
我也发现了这段代码,但我不明白为什么开发人员将用户存储在cookie和会话中而不是会话中.
在PHP中,我曾经只在会话中存储用户,并检查他是否存在于会话中.
我在asp.net core 2.0中创建了API,我正在使用混合模式身份验证.对于一些控制器JWT和一些使用Windows身份验证.
我对使用JWT授权的控制器没有任何问题.但对于我想要使用Windows身份验证的控制器,我无限期地提示使用chrome的用户名和密码对话框.
这里是我的示例控制器代码,我想使用Windows身份验证而不是JWT.
[Route("api/[controller]")]
[Authorize(AuthenticationSchemes = "Windows")]
public class TestController : Controller
{
[HttpPost("processUpload")]
public async Task<IActionResult> ProcessUploadAsync(UploadFileModel uploadFileModel)
{
}
}
Run Code Online (Sandbox Code Playgroud)
我的配置服务代码
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IISDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer("Bearer", options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false,
ValidateIssuer = false,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("blahblahKey")),
ValidateLifetime = true, //validate the expiration and not before values in the token
ClockSkew = TimeSpan.FromMinutes(5) //5 minute …Run Code Online (Sandbox Code Playgroud) 查看为ASP.NET MVC2编写的http://lukesampson.com/post/471548689/entering-and-exiting-https-with-asp-net-mvc中的示例代码,我注意到他们可以检查自定义属性是否为通过访问filterContext.ActionDescriptor和filterContext.ActionDescriptor.ControllerDescriptor分别应用于当前操作或控制器:
public class ExitHttpsIfNotRequiredAttribute : FilterAttribute, IAuthorizationFilter {
public void OnAuthorization(AuthorizationContext filterContext) {
// snip
// abort if a [RequireHttps] attribute is applied to controller or action
if(filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(RequireHttpsAttribute), true).Length > 0) return;
if(filterContext.ActionDescriptor.GetCustomAttributes(typeof(RequireHttpsAttribute), true).Length > 0) return;
// snip
}
}
Run Code Online (Sandbox Code Playgroud)
检查自定义属性的操作和控制器的ASP.NET MVC 1方法是什么?在ASP.NET MVC 1中filterContext.ActionDescriptor,我无法分辨.
我创建了一个自定义AuthorizeAttribute,用于验证在HTTP标头内发送的一些OAuth凭据.我正在使用其中一些凭据来确定谁在发出请求.一旦我在AuthorizeAttribute中解析这些信息,有没有办法将其传递出来,以便可以将数据分配给Controller的实例变量?然后我的控制器中的任何地方我都会有请求方的ID.
我搜索了很长时间来解决我的问题.我有一个自定义AuthorizeAttribute需要依赖于可以访问DbContext的"服务".遗憾的是,依赖注入在自定义AuthorizeAttribute中不起作用,并且始终为null.
我想出了一个(对我来说)可接受的解决方案.现在我想知道我的解决方案是否会导致不可预见的行为?
的Global.asax.cs
CustomAuthorizeAttribute.AuthorizeServiceFactory = () => unityContainer.Resolve<AuthorizeService>();
Run Code Online (Sandbox Code Playgroud)
CustomAuthorizeAttribute.cs
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public static Func<AuthorizeService> AuthorizeServiceFactory { get; set; }
public Privilege Privilege { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
bool authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
return false;
}
return AuthorizeServiceFactory().AuthorizeCore(httpContext, Privilege);
}
}
Run Code Online (Sandbox Code Playgroud)
AuthorizeService.cs
public class AuthorizeService
{
[Dependency]
public UserService UserService { private get; set; }
public bool AuthorizeCore(HttpContextBase httpContext, Privilege privilege) …Run Code Online (Sandbox Code Playgroud) c# entity-framework dependency-injection authorize-attribute asp.net-mvc-5
我使用ASP.NET MVC 4 Web应用程序作为一些WCF服务的前端.所有用户登录/注销和会话控制都在后端完成.MVC应用程序应该只存储具有会话ID的单个cookie.我的客户端不允许使用表单身份验证,所有内容都必须自定义.
我在web.config中设置了以下内容:
<system.web>
...
<authentication mode="None" />
</system.web>
<system.webServer>
<modules>
...
<remove name="FormsAuthentication" />
...
</modules>
</system.webServer>
Run Code Online (Sandbox Code Playgroud)
我还有一个全局过滤器:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
// Force all actions to request auth. Only actions marked with [AllowAnonymous] will be allowed.
filters.Add(new MyAuthorizeAttribute());
}
}
Run Code Online (Sandbox Code Playgroud)
在Global.asax中调用
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
Run Code Online (Sandbox Code Playgroud)
我用[AllowAnonymous]标记了每个不需要授权的控制器和操作.
现在我必须实现MyAuthorizeAttribute.我尝试了一些教程,但没有一个完全符合我的场景.
基本上,我必须为每个操作处理以下方案:
据我所知,我需要覆盖AuthorizeCore(检查我的cookie以查看会话是否存在且仍然有效)和HandleUnauthorizedRequest(将用户重定向到Home/Index而不是默认的Login页面).
对于重定向,我试过:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
base.HandleUnauthorizedRequest(filterContext);
filterContext.Result = new RedirectResult("/Home/Index/NeedsLogin");
}
Run Code Online (Sandbox Code Playgroud)
这似乎处理第二个罚款的情况(我不确定那个基本呼叫,但它是否需要?).
对于第一种情况,我需要实现AuthorizeCore.我不确定,如何正确地做到这一点.我已经看到AuthorizeAttribute有一些代码用于处理缓存情况,也许还有更多隐藏的功能,我不想打破它.
对于第三种情况,我不确定MyAuthorizeAttribute是否能够处理它.AuthorizeAttribute可以捕获Action内部发生的异常,或者我必须在我的全局错误处理程序中处理SecurityFault.SessionExpired情况吗?
我创建了一个基本的MVC 4项目.添加了HomeController和Home\Index.cshtml以及ContactUs.cshtml.在Global.asax中为ContactUs添加路由.
添加文件夹身份验证并在Auth文件夹中添加类Auth.css.
using System;
using System.Web;
using System.Web.Http;
using System.Net.Http;
namespace MvcApplicationTestProject1
{
public class AuthAttribute : AuthorizeAttribute
{
//public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
//{
// HandleUnauthorizedRequest(actionContext);
//}
protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
{
var response = actionContext.Request.CreateResponse(System.Net.HttpStatusCode.Redirect);
response.Headers.Add("Location", "http://www.google.com");
actionContext.Response = response;
}
//MVC 4 Web.Http.AuthorizeAttribute has IsAuthorized function but not AuthorizeCore
protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
{
return false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在HomeController中
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{ …Run Code Online (Sandbox Code Playgroud) 我在我的WebAPI中使用OAuth2.0 Owin(密码授权).我的初始令牌响应如下所示
{
"access_token": "_ramSlQYasdsRTWEWew.....................",
"token_type": "bearer",
"expires_in": 17999,
"permissions": {
"user": [
"Add",
"Update",
"Delete"
],
"Product": [
"Read",
"Create"
]
}
}
Run Code Online (Sandbox Code Playgroud)
我通过创建一个名为" 持有相应用户权限" 的新密钥来自定义响应permissions.
从这里我需要Resource server通过检查用户是否具有使用授权属性调用API的足够权限来验证来自我的每个请求.
我在这里找到了一个类似的例子,它涉及Dot net Core,这不适合我的情况.
困难的部分是permissionJSON Key本身就是一个复杂的ArrayList
[CustomAuthorize(PermissionItem.Product, PermissionAction.Read)]
public async Task<IActionResult> Index()
{
return View(Index);
}
public class CustomAuthorize : AuthorizeAttribute {
public AuthorizeAttribute (PermissionItem item, PermissionAction action) {
//Need to initalize the Permission Enums
}
public override void OnAuthorization (HttpActionContext …Run Code Online (Sandbox Code Playgroud) 我不知道我错过了什么,但我真的不能参考
User.Identity下OnActionExecuting(ActionExecutingContext filterContext)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Web.Routing;
.....
public class RealUserAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
/// if (User.Identity.IsAuthenticated)
Run Code Online (Sandbox Code Playgroud)
有任何线索如何修复它?