c# – 使用过期密码防止ODP.net连接打开
我正在使用一个使用oracle安全性来验证用户的Silverlight应用程序. (这是业务要求,因此无法更改).
我通过调用WCF Web服务来尝试使用提供的用户名和密码打开与数据库的连接.如果连接失败,我捕获异常并向用户返回一条消息,这是登录代码: [OperationContract] public LoginResult LogIn(string username,string password,DateTime preventCache) { var result = new List<string>(); try { connectionString = ConfigurationManager.ConnectionStrings["SecurityBD"].ToString(); connectionString = connectionString.Replace("[username]",username); connectionString = connectionString.Replace("[password]",passowrd) using (var connection = new Oracle.DataAccess.Client.OracleConnection()) { connection.ConnectionString = connectionString; connection.Open(); if (connection.State == System.Data.ConnectionState.Open) { connection.Close(); return new LoginResult(true,GetPermisos(username),preventCache); } else { return new LoginResult(false,null,preventCache); } } } catch (Oracle.DataAccess.Client.OracleException ex) { if (ex.Number == 1017) { return new LoginResult(new SecurityError("Wrong credentials.",ErrorType.InvalidCredentials)); } //Password expired. if (ex.Number == 28001) { return new LoginResult(new SecurityError("Password expired.",ErrorType.PasswordExpired)); } //Acount is locked. if (ex.Number == 28000) { return new LoginResult(new SecurityError("Account is locked.",ErrorType.AccountLocked)); } else { return new LoginResult(new SecurityError("An error occurred while attempting to connect." + Environment.NewLine + "Error: " + ex.ToString(),ErrorType.UndefinedError)); } } catch (Exception exg) { return new LoginResult(new SecurityError("An error occurred while attempting to connect." + Environment.NewLine + "Error: " + exg.ToString(),ErrorType.UndefinedError)); } } 如果连接因密码过期而失败,我会向用户显示相应的消息,然后提示他输入旧密码和新密码,然后将新凭据发送到我的网络服务上的ChangePassword方法. [OperationContract] public ChangePasswordResult ChangePassword(string username,string oldPasswrod,string newPassword) { string connectionString = string.Empty; try { connectionString = ConfigurationManager.ConnectionStrings["SecurityBD"].ToString(); connectionString = connectionString.Replace("[username]",passowrd) using (var connection = new OracleConnection(connectionString)) { connection.Open(); if (connection.State == System.Data.ConnectionState.Open) { connection.Close(); using (var newConnection = new Oracle.DataAccess.Client.OracleConnection(connectionString)) { newConnection.OpenWithNewPassword(Cryptography.TransportDecrypt(newPassword)); if (newConnection.State == System.Data.ConnectionState.Open) { return new ChangePasswordResult(null); } } } return new ChangePasswordResult(new SecurityError("Couldn't connect to the database.",ErrorType.UndefinedError)); } } catch (OracleException ex) { if (ex.Number == 1017) { return new ChangePasswordResult(new SecurityError("Wrong password",ErrorType.InvalidCredentials)); } //Password expired. if (ex.Number == 28001) { using (var newConnection = new Oracle.DataAccess.Client.OracleConnection(connectionString)) { try { newConnection.OpenWithNewPassword(Cryptography.TransportDecrypt(newPassword)); if (newConnection.State == System.Data.ConnectionState.Open) { return new ChangePasswordResult(null); } else { return new ChangePasswordResult(new SecurityError("No se pudo establecer una conexión con la base de datos",ErrorType.UndefinedError)); } } catch (Oracle.DataAccess.Client.OracleException oex) { if (oex.Number == 28003) return new ChangePasswordResult(new SecurityError("You'r new password does not match the security requeriments.." + Environment.NewLine + oex.Message,ErrorType.PasswordNotChanged)); else return new ChangePasswordResult(new SecurityError(oex.Message,ErrorType.UndefinedError)); } } } //Acount is locked. if (ex.Number == 28000) { return new ChangePasswordResult(new SecurityError("Account is locked.",ErrorType.AccountLocked)); } else { return new ChangePasswordResult(new SecurityError("Couldn't establish a connection." + Environment.NewLine + "Error: " + ex.Message,ErrorType.UndefinedError)); } } catch { throw; } } 执行更改密码操作后,用户仍然可以使用旧密码连接,并且无法使用新密码进行连接.只有在我重新启动应用程序后,更改才会生效. 我正在使用oracle的ODP.net驱动程序.使用Microsoft的oracle客户端,用户可以在密码更改后连接新密码和旧密码. preventCache参数仅用于验证没有类型的客户端缓存.我从客户端发送当前日期,然后从Web服务返回相同的值,以查看它是否随后的请求实际更改,并且它按预期执行. 我已经尝试监听连接的InfoMessage事件,看看是否有任何警告,但这样做可以防止密码过期异常上升,代码永远不会到达eventHandler. 我完全迷失了,这种行为对我来说似乎很奇怪,我仍然没有找出问题的根本原因. 我试过在桌面(WPF)应用程序上复制LogIn和ChangePassword方法,它的行为完全相同.所以我想问题不在于Silverlight客户端. 解决方法
好的,我已经弄明白了.使用Toad检查连接是否在执行Connection.Close()方法后提醒了opend.这种行为似乎是oracle连接池机制的一部分.
在连接字符串上包含Pooling = false解决了问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |