- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有这种自定义授权配置。问题是我想检查子模块以及它是否有权限。我还有一个登录 Controller ,我在其中构建声明等,并添加它们。但我想我也在这里遗漏了一些东西。我想我应该向当前的主体添加声明,但我不知道如何:
这是我在登录 Controller 中的登录 Action
[HttpGet("login")]
public IActionResult Login()
{
var userName = _httpContextAccessor.HttpContext.User.Identity.Name.GetUserNameFromHttpContext();
var user = _userClient.GetUserByUserName(userName);
var loggedIUserDto = new LoggedInUserDto {UserName = userName};
var claims = new List<Claim>();
if (user == null)
{
return Unauthorized($"User {userName} does not exits in DB");
}
var userModulesWithSubmodules = _loginClient.GetUserModulesWithSubmodules(userName);
loggedIUserDto.UserModulesWithSubmodules = userModulesWithSubmodules;
if (userModulesWithSubmodules.Count == 0)
{
return Conflict($"User {userName} has no modules");
}
foreach (var module in userModulesWithSubmodules)
{
foreach (var submodule in module.Submodules)
{
var submoduleActionList = new List<string>();
if (submodule.CanAdd)
{
submoduleActionList.Add("CanAdd");
}
if (submodule.CanEdit)
{
submoduleActionList.Add("CanEdit");
}
if (submodule.CanRead)
{
submoduleActionList.Add("CanRead");
}
if (submodule.CanDelete)
{
submoduleActionList.Add("CanDelete");
}
claims.Add(new Claim(ClaimTypes.Name, user.UserName));
claims.Add(new Claim(submodule.SubmoduleName, string.Join(',', submoduleActionList)));
}
}
var claimsIdentity = new ClaimsIdentity(claims);
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
Thread.CurrentPrincipal = claimsPrincipal;
return Ok(loggedIUserDto);
}
客户授权
public class CustomAuthorize : AuthorizeAttribute
{
private SubmoduleActionType _submoduleActionType;
private SubmoduleType _submoduleType;
public SubmoduleActionType ActionType;
public SubmoduleType Type {
get => _submoduleType;
set
{
_submoduleType = value;
Policy = $"{_submoduleType.ToString()};{_submoduleActionType.ToString()}";
}
}
public CustomAuthorize(SubmoduleActionType submoduleActionType, SubmoduleType submoduleType)
{
_submoduleActionType = submoduleActionType;
_submoduleType = submoduleType;
}
}
下面是我的需求类:
public class SubmoduleTypeRequirement : IAuthorizationRequirement
{
public SubmoduleActionType? ActionType { get; set; }
public SubmoduleType? Type { get; set; }
public SubmoduleTypeRequirement(SubmoduleActionType actionType, SubmoduleType type)
{
Type = type;
ActionType = actionType;
}
}
这是我的处理程序类
public class SubmoduleAuthorizationHandler : AuthorizationHandler<SubmoduleTypeRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, SubmoduleTypeRequirement submoduleRequirement)
{
if (!submoduleRequirement.ActionType.HasValue)
{
throw new ArgumentException("No action type provided");
}
if (!submoduleRequirement.Type.HasValue)
{
throw new ArgumentException("No submodule type provided");
}
if (!context.User.HasClaim(uc => uc.Type == submoduleRequirement.Type.ToString()))
{
context.Fail();
return Task.FromResult(0);
}
var grantedRights = Convert.ToString(context.User.FindFirst(c => c.Type == submoduleRequirement.Type.ToString()));
if (grantedRights.Contains(submoduleRequirement.ActionType.ToString()))
{
context.Succeed(submoduleRequirement);
}
return Task.FromResult(0);
}
}
最后是策略类:
public class SubmodulePolicy : IAuthorizationPolicyProvider
{
public SubmodulePolicy(IOptions<AuthorizationOptions> options)
{
DefaultPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
}
public DefaultAuthorizationPolicyProvider DefaultPolicyProvider { get; }
public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{
var submoduleTypeAndAction = policyName.Split(";");
var submoduleTypeString = submoduleTypeAndAction[0];
var actionTypeString = submoduleTypeAndAction[1];
var submoduleTypeParsed = System.Enum.TryParse(submoduleTypeString, out SubmoduleType submoduleType);
var actionTypeParsed = System.Enum.TryParse(actionTypeString, out SubmoduleActionType submoduleActionType);
if (actionTypeParsed && submoduleTypeParsed)
{
var policy = new AuthorizationPolicyBuilder();
policy.AddRequirements(new SubmoduleTypeRequirement(submoduleActionType, submoduleType));
return Task.FromResult(policy.Build());
}
if (!actionTypeParsed || !submoduleTypeParsed)
{
throw new ArgumentException("Cannot parse action or submoduleType from Policy");
}
return DefaultPolicyProvider.GetPolicyAsync(policyName);
}
public Task<AuthorizationPolicy> GetDefaultPolicyAsync()
{
return DefaultPolicyProvider.GetDefaultPolicyAsync();
}
}
问题是我的代码从未到达我的 GetPolicy。它总是转到 GetDefaultPolicyAsync 方法。甚至属性也不会被触发。我应该在某处注册自定义属性吗?我不信。无论我在互联网上找到什么,即使在官方文档中也总是有一个参数,但我需要两个。
哦,这是我在启动类中的配置
services.AddTransient<IAuthorizationPolicyProvider, SubmodulePolicy>();
services.AddSingleton<IAuthorizationHandler, SubmoduleAuthorizationHandler>();
services.AddAuthorization();
知道哪里出了问题吗?只有一个论点有什么限制吗?我也在考虑用过滤器替换它。
编辑:
根据我的启动类(class)的要求。只是评论 - jwt 配置被禁用,因为我在获取带有常量的 json 文件时遇到问题(获取文件时提示我输入用户名和密码 - iis 服务器)。这个 web api 结合了 angular 2+ (v7)
我的启动类:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public IContainer ApplicationContainer { get; private set; }
// This method gets called by the runtime. Use this method to add services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddJsonOptions(options => options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver());
services.AddTransient<IAuthorizationPolicyProvider, SubmodulePolicy>();
services.AddSingleton<IAuthorizationHandler, SubmoduleAuthorizationHandler>();
//var appSettingsSection = Configuration.GetSection("Settings");
//services.Configure<AppSettings>(appSettingsSection);
//var appSettings = appSettingsSection.Get<AppSettings>();
//var key = Encoding.ASCII.GetBytes(appSettings.Secret);
//services
// .AddAuthentication(auth =>
// {
// auth.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
// auth.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
// })
// .AddJwtBearer(jwtBearer =>
// {
// jwtBearer.RequireHttpsMetadata = false;
// jwtBearer.SaveToken = true;
// jwtBearer.TokenValidationParameters = new TokenValidationParameters
// {
// ValidateIssuerSigningKey = true,
// IssuerSigningKey = new SymmetricSecurityKey(key),
// ValidateIssuer = false,
// ValidateAudience = false
// };
// });
services.AddAuthorization();
services.Configure<IISServerOptions>(options =>
{
options.AutomaticAuthentication = true;
});
services.AddHttpContextAccessor();
var container = new ContainerBuilder();
container.RegisterType<PermissionsClient>()
.As<IPermissionsClient>()
.WithParameter("baseServiceUrl", Configuration.GetSection("Settings")["BaseApiUrl"])
.WithParameter("clientCertThumbprint", Configuration.GetSection("Settings")["BaseApiClientThumbPrint"])
.SingleInstance();
container.RegisterType<LoginClient>()
.As<ILoginClient>()
.WithParameter("baseServiceUrl", Configuration.GetSection("Settings")["BaseApiUrl"])
.WithParameter("clientCertThumbprint", Configuration.GetSection("Settings")["BaseApiClientThumbPrint"])
.SingleInstance();
container.RegisterType<UserClient>()
.As<IUserClient>()
.WithParameter("baseServiceUrl", Configuration.GetSection("Settings")["BaseApiUrl"])
.WithParameter("clientCertThumbprint", Configuration.GetSection("Settings")["BaseApiClientThumbPrint"])
.SingleInstance();
container.RegisterType<SenderClient>()
.As<ISenderClient>()
.WithParameter("baseServiceUrl", Configuration.GetSection("Settings")["BaseApiUrl"])
.WithParameter("clientCertThumbprint", Configuration.GetSection("Settings")["BaseApiClientThumbPrint"])
.SingleInstance();
container.Populate(services);
ApplicationContainer = container.Build();
return new AutofacServiceProvider(ApplicationContainer);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseMvc();
}
}
最佳答案
我已经设法让它工作了。问题出在我创建的属性中。这很奇怪,因为这里有文档 https://learn.microsoft.com/pl-pl/aspnet/core/security/authorization/iauthorizationpolicyprovider?view=aspnetcore-2.2
无论如何,在属性的 setter 中设置策略名称的 parrt 现在似乎对我有用。我不知道为什么。在我发现(尽管当你继承某些东西时这是显而易见的)除了我的自定义参数之外,我还可以传递一个策略名称之后,我再次尝试对其进行测试。当我将策略名称硬编码到我的自定义属性时,GetPolicyAsync 方法中的断点突然被击中。所以我尝试过类似的东西
public class CustomAuthorize : AuthorizeAttribute
{
private const string _policyName = "SubmodulePolicy"
private SubmoduleActionType _submoduleActionType;
private SubmoduleType _submoduleType;
public SubmoduleActionType ActionType;
public SubmoduleType Type { get; set;}
public CustomAuthorize(SubmoduleActionType submoduleActionType, SubmoduleType submoduleType)
{
_submoduleActionType = submoduleActionType;
_submoduleType = submoduleType;
Policy = $"{_policyName}-{submoduleActionType.ToString()}-{submoduleType.ToString()}"
}
}
突然间它开始工作了。另一件事是,在登录 Controller 中,您可以向用户添加声明,但如果这是此处的 Windows 身份验证
public class SubmoduleAuthorizationHandler : AuthorizationHandler<SubmoduleTypeRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, SubmoduleTypeRequirement submoduleRequirement)
{
if (!submoduleRequirement.ActionType.HasValue)
{
throw new ArgumentException("No action type provided");
}
if (!submoduleRequirement.Type.HasValue)
{
throw new ArgumentException("No submodule type provided");
}
if (!context.User.HasClaim(uc => uc.Type == submoduleRequirement.Type.ToString()))
{
context.Fail();
return Task.FromResult(0);
}
var grantedRights = Convert.ToString(context.User.FindFirst(c => c.Type == submoduleRequirement.Type.ToString()));
if (grantedRights.Contains(submoduleRequirement.ActionType.ToString()))
{
context.Succeed(submoduleRequirement);
}
return Task.FromResult(0);
}
}
在 http 上下文中,您将获得不同的上下文,然后我在登录方法中进行更新。所以我不得不使用这个 Add custom claims to identity when using Windows authentication并在此处填充声明而不是登录方法。最后一个对很多人来说可能很明显,但对我来说却不是。也许我的冒险也会帮助某人。
关于c# - ASP.NET Core 自定义授权属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56378992/
我试图对 ASP.Net MVC 有一个高层次的理解,我开始意识到它看起来很像原始的 ASP 脚本。过去,我们将“模型”/业务逻辑代码组织到 VBScript 类或 VB COM 组件中。 当然,现在
我已经搜索了一段时间,但似乎找不到答案。 我想在我的旋转木马中显示一个计数器,左边是当前项目(工作),左边是项目总数。 我的代码:
. 最佳答案 Scott Gu 称这些为代码块。这就是我的看法。 http://weblogs.asp.net/scottgu/archive/2010/04/06/new-lt-gt-syntax
我有一个使用 Visual Studio 2010/.net 4/VB 制作的网站。 我真的很喜欢我发现的 FAQ 系统的布局,因为它很简单,但它是经典的 asp。所以,显然,我不能包括我的母版页布局
好吧,对于你们许多人来说,这个问题可能有一个非常明显的答案,但它让我难住了。 我有一个 asp.net Web 表单,上面有两个控件(嗯,不止这两个,但我们将重点关注这些) - 第一个是 asp:dr
当我将 ASP.NET 复选框控件设置为 asp.net 更新面板的异步回发触发器时,EventName 属性是什么? 最佳答案 我相信它是 CheckedChanged。 关于asp.net - a
我有一个用经典 asp 编写的(巨大的)网站。现在我必须切换到 vb.net (razor)。有没有办法将这两个结合起来直到切换完成? 有没有办法让应用程序与经典的 asp 和 vb.net 一起工作
I am creating a products page, where the user selects an option in a radiobuttonlist for example, an
我最近将一个经典的 ASP 应用程序转换为 ASP.NET 3.5,但我觉得我的经典 ASP 版本要快一些(我不知道可能买家会后悔)。 所以你们能帮我解决这个问题吗,让我知道哪个更快,asp、asp.
从本周开始,我被要求开始学习如何使用 ASP 开发网站。我通过 XNA 对 C# 有一定的经验,所以这部分对我来说并不是什么麻烦。 我一直在关注Music Store Tutorial这需要我设置一个
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 8 年前。 Improve this ques
我想将一些表单变量发布到经典 ASP 页面中。我不想改变经典的 ASP 页面,因为需要完成大量的工作,以及消耗它们的页面数量。 经典的 ASP 页面需要将表单变量 Username 和 Userpas
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
在某种程度上,这可能是一个异端问题。我们有一个大型站点,其中许多页面仍在ASP中。通常,并没有真正动态的,而是包括(通过SSI或Server.Execute)定期重新生成的HTML块。看起来好像是一个
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 9 年前。 Improve this ques
我有一个遗留的 ASP 应用程序——在不久的某个时候——需要迁移到 ASP.Net 2.0(以与也在 2.0 中的其他应用程序兼容)。 对于这类事情是否有最佳实践,即作为第一步将当前 html、vbs
我目前在一家公司工作,该公司使用 ASP.NET Webforms 和旧 ASP 页面的组合进行 Web 开发。这对于他们当前的项目来说效果很好,但我想说服/建议他们切换到 ASP.NET MVC,因
我有一个经典的 asp 应用程序。我想将该页面的竞赛表格发布到 Asp.Net 表格。原因是我想在进入数据库之前使用我在 Asp.Net 页面中内置的大量逻辑进行验证,而我对 asp 不太了解。更不用
我知道在 ASP.NET MVC 中,您可以拥有移动 View 并执行类似 Index.mobile.cshtml 的操作。和 _Layout.mobile.cshtml并且服务器知道将这些 View
我需要从一些服务器端 c#.net 代码中调用经典 asp 页面上的 VBscript 函数 - 有谁知道一种干净的方法来做到这一点?在 .net 中重写函数不是一种选择。 我会再解释一下这个问题..
我是一名优秀的程序员,十分优秀!