简体   繁体   English

无法从.net Core中的配置管理器获取用户机密

[英]Unable to get user secret from confiuration manager in .net core

I'm currently setting up a .net core web application, and have set up MailKit to handle it's email sending. 我当前正在设置.net核心Web应用程序,并已设置MailKit来处理其电子邮件发送。

Rather than hard coding my smtp password I went with the user secret option. 与其对我的smtp密码进行硬编码,不如使用用户密码选项。 However for some reason every time I try to retrieve the password, it comes back as null. 但是由于某种原因,每次我尝试检索密码时,密码都会返回空值。 The Error: 错误:

An unhandled exception occurred while processing the request. 处理请求时发生未处理的异常。 ArgumentNullException: Value cannot be null. ArgumentNullException:值不能为null。 Parameter name: password MoveNext in MessageServices.cs, line 56 参数名称:MessageServices.cs中第56行的密码MoveNext

I was wondering if anyone can see what I'm missing! 我想知道是否有人可以看到我所缺少的!

Here is my MessageService.cs 这是我的MessageService.cs

    public class AuthMessageSender : IEmailSender, ISmsSender
{

    public IConfiguration Configuration { get; set; }

    public AuthMessageSender()
    {
        var builder = new ConfigurationBuilder()
               .SetBasePath(Directory.GetCurrentDirectory())
               .AddJsonFile("appsettings.json");
        Configuration = builder.Build();
    }
    public async Task SendEmailAsync(string email, string subject, string message, string fullName)
    {

        try
        {
            var _email = "info@*******.co.uk";
            var _epass = Configuration["AdminPassword:Email"];
            var _dispName = "Mark ****";
            var myMessage = new MimeMessage();
            var builder = new BodyBuilder();
            myMessage.To.Add(new MailboxAddress(fullName ?? "User", email));
            myMessage.From.Add(new MailboxAddress(_dispName, _email));
            myMessage.Subject = subject;
            builder.HtmlBody = message;
            myMessage.Body = builder.ToMessageBody();

            using (SmtpClient smtp = new SmtpClient())
            {
                bool UseSSL = true;
                string Host = "just22.justhost.com";
                int Port = 465;
                await smtp.ConnectAsync(Host, Port, UseSSL).ConfigureAwait(true);
                smtp.AuthenticationMechanisms.Remove("XOAUTH2");
                smtp.Authenticate(_email, _epass); // Note: only needed if the SMTP server requires authentication
                await smtp.SendAsync(myMessage).ConfigureAwait(false);
                await smtp.DisconnectAsync(true).ConfigureAwait(false);
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }


}

    public Task SendSmsAsync(string number, string message)
    {
        // Plug in your SMS service here to send a text message.
        return Task.FromResult(0);
    }

And here is my Start.cs 这是我的Start.cs

    public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

        if (env.IsDevelopment())
        {
            // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
            builder.AddUserSecrets();
        }

        builder.AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        services.AddMvc();

        // Add application services.
        services.AddTransient<IEmailSender, AuthMessageSender>();
        services.AddTransient<ISmsSender, AuthMessageSender>();
        services.AddDistributedMemoryCache();
        services.AddSession();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public async void Configure(IApplicationBuilder app, IHostingEnvironment env,
        ILoggerFactory loggerFactory, IServiceProvider serviceProvider, ApplicationDbContext context)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();
        app.UseSession();
        app.UseIdentity();

        // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715
        app.UseFacebookAuthentication(new FacebookOptions()
        {
            AppId = Configuration["Authentication:Facebook:AppId"],
            AppSecret = Configuration["Authentication:Facebook:AppSecret"]
        });

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
        await CreateRoles(context, serviceProvider);
    }
    private async Task CreateRoles(ApplicationDbContext context, IServiceProvider serviceProvider)
    {
        var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
        var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
        // Create a list of roles with both name and normalised name attributes
        List<IdentityRole> roles = new List<IdentityRole>();
        roles.Add(new IdentityRole { Name = "Admin", NormalizedName = "ADMIN" });
        roles.Add(new IdentityRole { Name = "Member", NormalizedName = "MEMBER" });
        roles.Add(new IdentityRole { Name = "Moderator", NormalizedName = "MODERATOR" });
        // Check if the role already exists
        foreach (var role in roles)
        {
            var roleExist = await RoleManager.RoleExistsAsync(role.Name);
            if (!roleExist)
            {   // Add it if it doesn't
                context.Roles.Add(role);
                context.SaveChanges();
            }
        }
        var user = await userManager.FindByEmailAsync("mark****@gmail.com");
        if (user != null)
        {
            var gotRoles = userManager.GetRolesAsync(user);
            if (!gotRoles.Equals("Admin"))
            {
                await userManager.AddToRoleAsync(user, "Admin");
            }
        }
    }
}

I have checked to make sure the secret exists, which it does, along with Facebook Authentication secrets, which seem to work just fine. 我已经检查确定该机密确实存在,并与Facebook身份验证机密一起正常工作。

If I hard code the password, the email gets sent. 如果我对密码进行硬编码,则会发送电子邮件。 When I set break points I can see that the password is indeed null. 当我设置断点时,我可以看到密码确实为空。 I'm a bit stumped! 我有点难过!

Thanks in advance. 提前致谢。

New Answer based on information provided by @Kritner and this Link: Access to Configuration object from Startup class 基于@Kritner提供的信息以及此链接的新答案: 从Startup类访问Configuration对象

First I created a POCO that had ALL of my SMTP properties that should be out of sight, like so: 首先,我创建了一个POCO,其中包含我所有的SMTP属性,这些属性应该不可见,如下所示:

        public class SmtpConfig
{
    public string EmailDisplayName { get; set; }
    public string SmtpPassworrd { get; set; }
    public string SmtpUserEmail { get; set; }
    public string SmtpHost { get; set; }
    public int SmtpPort { get; set; }
}

Then in My Startup.cs I added this to ConfigureServices: 然后在My Startup.cs中,将其添加到ConfigureServices:

            services.Configure<SmtpConfig>(optionsSetup =>
        {
            //get from appsetings.json file
            optionsSetup.SmtpPassworrd = Configuration["SMTP:Password"];
            optionsSetup.SmtpUserEmail = Configuration["SMTP:Email"];
            optionsSetup.SmtpHost = Configuration["SMTP:Host"];
            optionsSetup.SmtpPort = Convert.ToInt32(Configuration["SMTP:Port"]);
        });

Finally I edited my messageServices to look like this: 最后,我编辑了messageServices,如下所示:

        public class AuthMessageSender : IEmailSender, ISmsSender
{
    private readonly IOptions<SmtpConfig> _smtpConfig;
    public IConfiguration Configuration { get; set; }

    public AuthMessageSender( IOptions<SmtpConfig> smtpConfig)
    {
        _smtpConfig = smtpConfig;
    }
    public async Task SendEmailAsync(string email, string subject, string message, string fullName)
    {

        try
        {
            var _email = _smtpConfig.Value.SmtpUserEmail;
            string _epass = _smtpConfig.Value.SmtpPassworrd;
            var _dispName = _smtpConfig.Value.EmailDisplayName;
            var myMessage = new MimeMessage();
            var builder = new BodyBuilder();
            myMessage.To.Add(new MailboxAddress(fullName ?? "User", email));
            myMessage.From.Add(new MailboxAddress(_dispName, _email));
            myMessage.Subject = subject;
            builder.HtmlBody = message;
            myMessage.Body = builder.ToMessageBody();

            using (SmtpClient smtp = new SmtpClient())
            {
                bool UseSSL = true;
                string Host = _smtpConfig.Value.SmtpHost;
                int Port = _smtpConfig.Value.SmtpPort;
                await smtp.ConnectAsync(Host, Port, UseSSL).ConfigureAwait(true);
                smtp.AuthenticationMechanisms.Remove("XOAUTH2");
                smtp.Authenticate(_email, _epass); // Note: only needed if the SMTP server requires authentication
                await smtp.SendAsync(myMessage).ConfigureAwait(true);
                await smtp.DisconnectAsync(true).ConfigureAwait(true);
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }


    }

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

相关问题 如何使用 .NET Core 中的 VPC 端点连接 AWS 机密管理器? - How to connect AWS secret manager using VPC endpoint in .NET Core? 从 AWS Secret Manager 访问密钥 - Access secret key from AWS Secret Manager .NET Core 2.2 - 无法从 Azure AppConfig 获取应用程序配置 - .NET Core 2.2 - Unable to get app configuration from Azure AppConfig .net core 在 ValidationAttribute 中获取用户 - .net core get user in ValidationAttribute 从ASP.NET CORE 2获取当前用户 - Get Current User From ASP.NET CORE 2 如何从.Net Core中的单独类库中获取经过身份验证的用户 - How to get the authenticated user from a separate class library in .Net Core 如何将用户配置文件从共享点获取到 asp .net 核心应用程序? - How to get user profiles from sharepoint into asp .net core app? asp.net核心授权——从Claims中获取用户角色 - asp.net core authorization - Get User Roles from Claims 存储在 Google Secret Manager 中的 DotNet 用户机密 - DotNet User secrets stored in Google Secret Manager 如何在 C# 页面 ASP.NET 核心 MVC 上使用登录管理器和用户管理器 - How to use SignIn Manager and User Manager on C# pages ASP.NET Core MVC
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM