【问题标题】:EFCore canConnect returning true for locked accountsEFCore canConnect 为锁定的帐户返回 true
【发布时间】:2020-10-23 01:21:18
【问题描述】:

我遇到了 Microsoft.EntityFrameworkCore.Infrastructure DatabaseFacade.CanConnect() 的奇怪行为,即使用户帐户被锁定,只要该帐户在应用程序生命周期内已经登录过一次,它也会返回 true。

以下是我正在遵循的步骤以及遇到的情况:

  1. 启动网络应用程序
  2. 用户导航到网页并输入他们的数据库登录名
  3. 我检查了用户详细信息是否可以使用canConnect() 连接到数据库,这会返回 true,并且页面会显示一些查询结果
  4. 我在 Oracle 中锁定了用户帐户
  5. 用户退出 Web 应用程序并刷新页面
  6. 用户刷新网页并输入他们的数据库登录名
  7. 我检查了用户详细信息是否可以使用canConnect() 连接到数据库,这会返回 true,并且页面会显示一些查询结果 - 尽管用户帐户被锁定
  8. 我重新启动 Web 应用程序(应用程序池重置/停止启动)
  9. 用户刷新网页并输入他们的数据库登录名
  10. 我检查了用户详细信息可以使用canConnect() 连接到数据库,这会引发异常,因为用户帐户被锁定

为什么如果我锁定帐户,用户可以继续连接到数据库,直到应用程序停止/启动/回收?我没有在 C# 中使用任何缓存。

我正在使用 EFCore 2.2.6Oracle.ManagedDataAccess.Core 2.19.31

Db 服务的范围是每个 http 请求:

services.AddScoped<IOracleAuthenticationModule, OracleAuthenticationModule>();

OracleAuthenticationModule:

public struct UserConnection
{
    public string User { get; set; }
    public string Password { get; set; }
    public string DataSource { get; set; }
}

public OracleDbContext InitialiseUserDb(UserConnection connection)
{
    return InitialiseDb($"Data Source={connection.DataSource};User Id={connection.User};Password={connection.Password};Persist Security Info=True;");
}

private OracleDbContext InitialiseDb(string connectionString)
{
    DbContextOptionsBuilder<OracleDbContext> optionsBuilder = new DbContextOptionsBuilder<OracleDbContext>();
    optionsBuilder.UseOracle(connectionString);

    OracleDbContext db = new OracleDbContext(optionsBuilder.Options);
    if (db.Database.CanConnect())
    {
        return db;
    }
    throw new Exception("Unable to connect to Oracle database, please verify credentials");
}

【问题讨论】:

  • 连接池的用户和锁账户的用户是一样的吗?您是否通过 ALTER USER xxx ACCOUNT LOCK 锁定了帐户。 ?
  • 不,一个用户连接帐户“ABC”,然后它被另一个帐户“ADMIN”锁定

标签: c# oracle .net-core entity-framework-core ef-core-2.2


【解决方案1】:

请记住,如果池正在执行 ALTER USER xxx ACCOUNT LOCK,以锁定池本身使用的 db 帐户,此命令不会影响池中已打开的连接 .

当您在 Oracle 中锁定用户帐户时,如果用户注销并再次登录,您的池可能没有打开新连接,而是重用在锁定发生之前已经可用的现有连接。池通常配置为重用现有连接,以避免昂贵的连接/断开操作。

这就是我认为在池尝试再次打开新连接之前锁定不会影响的原因,当您停止/启动时会发生这种情况。

试试看

https://docs.oracle.com/database/121/ODPNT/featConnecting.htm#ODPNT170

如果您可以选择检查数据库中的 v$session,当您启动应用程序并运行对数据库的第一个请求时,您会看到池打开了多少连接。

按照 Oracle 文档

当打开一个新连接时,如果连接字符串与现有池不完全匹配,则创建一个新池。在 ODP.NET 12.1.0.2 之前,只有连接字符串属性值必须匹配。现在,连接字符串本身必须完全匹配。以不同顺序为同一连接提供的关键字将被单独汇集。如果已存在具有请求签名的池,则从该池向应用程序返回一个连接。 创建连接池时,连接池服务最初会创建由 ConnectionString 属性的 Min Pool Size 属性定义的连接数。此连接数始终由连接池的连接池服务维护。 在任何给定时间,这些连接都被应用程序使用或在池中可用。

【讨论】:

  • 我正在通过一个完全独立的应用程序锁定帐户以管理 Oracle 用户。我认为这意味着我应该通过 C# 以编程方式终止用户连接,然后当用户注销应用程序时?
猜你喜欢
  • 1970-01-01
  • 2013-08-02
  • 1970-01-01
  • 1970-01-01
  • 2016-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多