0

我正在尝试将身份验证和基于策略的授权添加到 .net core 3 Web API。但是,添加策略后出现一个奇怪的错误。我对.net 很陌生。我无法确定究竟是什么导致了这个错误,它(显然)是在我将策略添加到我的应用程序之后开始的,并且在添加它之前工作得很好,我不知道为什么它不工作。我将服务注册为单例并将其尝试为瞬态,但仍然没有运气。

InvalidOperationException:尝试激活“actualizer.Security.claims.transformation.UserTransformer”时无法解析“FlexibleConfiguration.Abstractions.IConfiguration”类型的服务。

Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(类型 serviceType,类型 implementationType,CallSiteChain callSiteChain,ParameterInfo[] 参数,bool throwIfCallSiteNotFound)

启动.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Okta.AspNetCore;
using Microsoft.OpenApi.Models;
using Okta.Sdk;
using Okta.Sdk.Configuration;
using Microsoft.AspNetCore.Authentication;
using actualizer.Security.claims;
using actualizer.Security.claims.transformation;

namespace actualizer {
    public class Startup {

        public Startup(IConfiguration configuration) {

            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services) {

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
            services.AddMvc(option => option.EnableEndpointRouting = false);

           services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            services.AddSwaggerGen(c => {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "Actualizer", Version = "v1" });
            });

            var client = new OktaClient(new OktaClientConfiguration {
                OktaDomain = "https://dev-xxxxxx.okta.com",
                Token = "xxxxxxxxxxxxxxxx"
            });

            services.AddSingleton<IOktaClient, OktaClient>();

            services.AddAuthentication(options => {
                options.DefaultAuthenticateScheme = OktaDefaults.ApiAuthenticationScheme;
                options.DefaultChallengeScheme = OktaDefaults.ApiAuthenticationScheme;
                options.DefaultSignInScheme = OktaDefaults.ApiAuthenticationScheme;
            })
            .AddOktaWebApi(new OktaWebApiOptions() {
                OktaDomain = "xxxxxxxxxxx"
            });

            services.AddSingleton<IClaimsTransformation, UserTransformer>();

            services.AddAuthorization(options => {
                options.AddPolicy("CanMakeAnalyticsRequests", policy => policy.RequireClaim("CanMakeAnalyticsRequests"));
            });

            services.AddCors(options => {
                options.AddPolicy("VueCorsPolicy", builder => {
                    builder
                      .AllowAnyHeader()
                      .AllowAnyMethod()
                      .AllowCredentials()
                      .WithOrigins("http://localhost:8080");
                });
            });

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostEnvironment env) {
            //Swagger MIddleware
            app.UseSwagger();
            app.UseSwaggerUI(c => {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "Actualizer");
                c.RoutePrefix = string.Empty;

            });
            if (env.IsDevelopment()) {
                app.UseDeveloperExceptionPage();
            } else {
                app.UseHsts();
            }
            app.UseCors("VueCorsPolicy");
            app.UseHttpsRedirection();
            app.UseAuthentication();
            app.UseMvc();
       }
    }
}

用户变压器.cs

using System;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using actualizer.Policy;
using FlexibleConfiguration.Abstractions;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Okta.Sdk;

namespace actualizer.Security.claims.transformation {
    public class UserTransformer : IClaimsTransformation {

        private readonly IOktaClient _oktaClient;
        IHttpContextAccessor _httpContextAccessor;

        public UserTransformer(IConfiguration config, IHttpContextAccessor httpContextAccessor, IOktaClient oktaClient) {
            _httpContextAccessor = httpContextAccessor;
            this._oktaClient = oktaClient;
        }
        public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal p) {
            var claimsIdentity = p.Identity as ClaimsIdentity;
            string _CanMakeAnalyticsRequests = "CanMakeAnalyticsRequests";

            var uid = claimsIdentity.Claims.FirstOrDefault(c => c.Type == "uid").Value;
            var user = await _oktaClient.Users.GetUserAsync(uid);

            var permissions = user.Profile["permissions"];

            if (permissions.ToString() == _CanMakeAnalyticsRequests) {
                claimsIdentity.AddClaim(new Claim(Claims.CanMakeAnalyticsRequests, string.Empty));
            }
            return p;
        }

    }
}

CanMakeAnalyticsRequests.cs

using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;

namespace actualizer.Policy.Policies {

    public class CanMakeAnalyticsRequests : AuthorizationHandler<CanMakeAnalyticsRequests>, IAuthorizationRequirement {

        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CanMakeAnalyticsRequests requirement) {

            if (context.User.Claims.Any(c => c.Type == Claims.CanMakeAnalyticsRequests)) {
                context.Succeed(requirement);
            } else {
                Console.WriteLine($"{context.User.Claims} tried to call analytics api");
                context.Fail();
            }

            return Task.CompletedTask;
        }
    }
}

索赔.cs

using System;
using System.Threading.Tasks;
using System.Linq;
using System.Collections.Generic;
namespace actualizer.Policy {
    public class Claims {
        public const string CanMakeAnalyticsRequests = nameof(CanMakeAnalyticsRequests);
    }
}
4

1 回答 1

1

该错误发生在您的UserTransformer课程中,因为您在未注册时使用FlexibleConfiguration.Abstractions了注入。IConfiguration config

我对这个包不熟悉,如果你想使用它,你需要向所有者确认它是否支持 asp.net core 3.0。

最简单的方法是使用using Microsoft.Extensions.Configuration;而不是像你using FlexibleConfiguration.Abstractions在.UserTransformer.csstartup.cs

或者只是在构造函数参数中删除IConfiguration config,因为您在代码中根本不使用它。

于 2019-12-02T02:44:08.420 回答