身份4,程序化登录

时间:2019-05-08 06:15:25

标签: c# .net-core identityserver4

运行.NET Core 2.0

尝试在Identity 4服务器中创建“自动登录”功能。 “自动登录”来自通过电子邮件发送的链接,我的网站所有者希望人们能够单击该链接,并自动进入其帐户,而无需输入密码。我确实有一些安全保护措施,此处未列出。

除了一个例外,我一切正常。我没有得到期望看到的身份验证cookie。这是相关的代码。

var user = await _userManager.FindByNameAsync(userName);
await this._eventService.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id.ToString(), user.UserName));
await _signInManager.SignInAsync(user, isPersistent: false);
return Redirect(returnUrl);

永远不会设置授权cookie,因此该站点未被授权。当我似乎无法弄清楚我缺少什么。

我的Startup.cs

protected readonly Model_ProgramSettings _programSettings;
protected readonly Model_SecuritySection _securitySection;
public IConfiguration _configuration { get; }
public IHostingEnvironment _environment { get; }

public Startup(IConfiguration configuration, IHostingEnvironment environment)
{
    ServicePointManager.SecurityProtocol &= ~(SecurityProtocolType.Tls | SecurityProtocolType.Tls11);

    _configuration = configuration;
    _environment = environment;

    _securitySection = new Model_SecuritySection();
    _configuration.GetSection("SecuritySection").Bind(_securitySection);

    _programSettings = new Model_ProgramSettings();
    _configuration.GetSection("ProgramSettings").Bind(_programSettings);
}

public void ConfigureServices(IServiceCollection services)
{
    IdentityModelEventSource.ShowPII = true;

    #region Configuration
    services.Configure<Model_BaseSettings>(_configuration.GetSection("ProgramSettings"));
    services.Configure<Model_ProgramSettings>(_configuration.GetSection("ProgramSettings"));
    services.Configure<Model_ConnectionStrings>(_configuration.GetSection("ConnectionStrings"));
    services.Configure<Model_SecuritySection>(_configuration.GetSection("SecuritySection"));
    services.Configure<Model_SmtpSection>(_configuration.GetSection("SmtpSection"));
    #endregion

    #region Identity
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(_configuration.GetConnectionString("SqlIdentity"))
   );

    services.AddIdentity<ApplicationUser, IdentityRole>(options =>
    {
        options.Password.RequireDigit = false;
        options.Password.RequiredLength = 4;
        options.Password.RequireLowercase = false;
        options.Password.RequireNonAlphanumeric = false;
        options.Password.RequireUppercase = false;
        options.User.RequireUniqueEmail = false;
        options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 #`~!%^*()+-={}|[]:;<>?s,.'_@&";
    })
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();
    #endregion

    #region Data Services
    services.AddScoped<IMarketAreaService, MarketAreaService>();
    services.AddScoped<IRealignService, RealignService>();
    services.AddScoped<ISubscriberService, SubscriberService>();
    services.AddScoped<IToDoService, ToDoService>();
    services.AddScoped<IUserService, UserService>();
    services.AddScoped<IMiscDataService, MiscDataService>();
    #endregion

    services.AddTransient<IEmailService, EmailService>();
    services.AddTransient<IErrorService, ErrorService>();

    #region Security
    services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(_programSettings.DataProtectionKeys));
    #endregion

    #region Swagger
    services.AddTransient<IProfileService, CustomProfileService>();

    services.AddSwaggerGen(options =>
    {
        options.SwaggerDoc("v1", new Info { Title = $" {this._programSettings.Site} STS", Version = "v1" });
    });
    #endregion

    services.AddMvc()
        .AddJsonOptions(options =>
        options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore
    );

    var policy = new CorsPolicyBuilder();
    policy.AllowAnyHeader();
    policy.AllowCredentials();
    policy.AllowAnyMethod();
    policy.WithOrigins(this._securitySection.WithOrigins.ToArray<string>());

    services.AddCors(options =>
    {
        options.AddPolicy("CorsPolicy", policy.Build());
    });

    var builder = services.AddIdentityServer(options =>
        {
            options.Events.RaiseErrorEvents = true;
            options.Events.RaiseInformationEvents = true;
            options.Events.RaiseFailureEvents = true;
            options.Events.RaiseSuccessEvents = true;
        })
    .AddInMemoryIdentityResources(new List<IdentityResource>
    {
        new IdentityResources.OpenId(),
        new IdentityResources.Profile(),
    })
    .AddInMemoryApiResources(new List<ApiResource>
    {
        new ApiResource($"API-{this._programSettings.Site}", $"this._programSettings.Site} API")
    })
    .AddInMemoryClients(new List<Client>
    {
        new Client
        {
            ClientId = $"STS-{this._programSettings.Site}",
            ClientName = $"{this._programSettings.Site} STS",
            AllowedGrantTypes = GrantTypes.Code,
            RequirePkce = true,
            RequireClientSecret = false,
            AllowAccessTokensViaBrowser = true,
            RequireConsent = false,
            RedirectUris = this._securitySection.RedirectUris,
            PostLogoutRedirectUris = this._securitySection.PostLogoutRedirectUris,
            AllowedCorsOrigins = new List<string> { this._securitySection.AllowFrom },
            AbsoluteRefreshTokenLifetime = 60 * 60 * 24 * 30,
            AccessTokenLifetime = 60 * 60,
            AuthorizationCodeLifetime = 60 * 5,
            AllowedScopes =
            {
                IdentityServerConstants.StandardScopes.OpenId,
                IdentityServerConstants.StandardScopes.Profile,
                $"API-{this._programSettings.Site}"
            },
        }
    })
    .AddAspNetIdentity<ApplicationUser>()
    .AddProfileService<CustomProfileService>();


    builder.AddDeveloperSigningCredential();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
{
    app.UseMiddleware<ExceptionMiddleware>();
    app.UseStaticFiles();

    app.UseIdentityServer();
    app.Use(async (context, next) =>
    {
        context.Response.Headers.Add("X-Frame-Options", $"ALLOW-FROM {this._securitySection.AllowFrom}");
        context.Response.Headers.Add("P3P", "CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"");
        await next();
    });
    app.UseCsp(csp =>
    {
        csp
        .AllowFrames
        .FromSelf()
        .From(this._securitySection.AllowFrom);
    });

    app.UseSwagger();
    app.UseSwaggerUI(options =>
    {
        options.SwaggerEndpoint("/swagger/v1/swagger.json", $" {this._programSettings.Site} STS");
    });

    app.UseCors("CorsPolicy");
    app.UseMvcWithDefaultRoute();
    app.UseMvc();
}

我的控制器声明:

private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IIdentityServerInteractionService _interaction;
private readonly IClientStore _clientStore;
private readonly IAuthenticationSchemeProvider _schemeProvider;
private readonly IEventService _eventService;
private readonly IEmailService _emailService;
private readonly IUserService _userService;
private readonly ISubscriberService _subscriberService;
private readonly IMarketAreaService _marketAreaService;
private readonly IDataProtector _dataProtector;
private readonly Model_ProgramSettings _programSettings;

public AccountController(
    UserManager<ApplicationUser> userManager,
    SignInManager<ApplicationUser> signInManager,
    IIdentityServerInteractionService interaction,
    IClientStore clientStore,
    IAuthenticationSchemeProvider schemeProvider,
    IEventService eventService,
    IOptions<Model_ProgramSettings> baseSettings,
    IUserService userService,
    IEmailService emailService,
    IDataProtectionProvider dataProtectionProvider,
    ISubscriberService subscriberService,
    IMarketAreaService marketAreaService)
{
    this._userManager = userManager;
    this._signInManager = signInManager;
    this._interaction = interaction;
    this._clientStore = clientStore;
    this._schemeProvider = schemeProvider;
    this._eventService = eventService;
    this._emailService = emailService;
    this._userService = userService;
    this._subscriberService = subscriberService;
    this._programSettings = baseSettings.Value;
    this._marketAreaService = marketAreaService;
    this._dataProtector = dataProtectionProvider.CreateProtector(_programSettings.Customer);
}

1 个答案:

答案 0 :(得分:0)

我的建议是将该方案传递给SignIn的扩展方法,以便它知道要使用哪个处理程序。

var principal = new ClaimsPrincipal(identity);
await this.HttpContext.SignInAsync("idsrv", principal, props);
相关问题