#java #sql-server #security #stored-procedures #login
#java #sql-сервер #Безопасность #хранимые процедуры #аутентификация
Вопрос:
Я пытаюсь войти в нашу базу данных через свою программу, но когда я это делаю, я получаю неверные учетные данные, поэтому я не уверен, с чего начать, надеюсь, кто-нибудь сможет мне помочь с этим, поскольку я раньше не работал с pwdencrypt и pwdcompare, и я не уверен, что нужно сделать, чтобы заставить его работать
Мой код:
protected String doInBackground(String... params) {
if (userid.trim().equals("Developer")|| password.trim().equals("Dev!n_234"))
isSuccess2=true;
z = getString(R.string.login_succes);
if(userid.trim().equals("")|| password.trim().equals(""))
z = getString(R.string.indsæt_rigtigt_bruger);
else
{
try {
Connection con = connectionClass.CONN();
if (con == null) {
z = getString(R.string.Forbindelses_fejl) "L1)";
} else {
CallableStatement cs = null;
String query = "{call [system].[usp_validateUserLogin] (?,?,?,?,?)}";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
CallableStatement ps = con.prepareCall(query);
ps.setString(1, userid);
ps.setString(2, password);
ps.setInt(3,72);
ps.setNull(4, Types.BOOLEAN);
ps.registerOutParameter(5, Types.VARCHAR);
cs.executeUpdate();
if(rs.next())
{
z = getString(R.string.login_succes);
isSuccess=true;
}
else
{
z = getString(R.string.Invalid_Credentials);
isSuccess = false;
}
}
}
catch (Exception ex)
{
isSuccess = false;
z = getString(R.string.Exceptions) "L2)";
Log.e("MYAPP", "exception", ex);
}
}
return z;
}
}
}
}
процедура
ALTER PROCEDURE [system].[usp_validateUserLogin]
@p_Login NVARCHAR ( 50 )
, @p_Password NVARCHAR ( 32 )
, @p_CompanyID INT
, @p_OutDetails BIT = 1
, @p_AuthenticationTicket VARCHAR(200) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @errNo INT
, @recCount INT
, @res INT
SELECT u.*
INTO #tmpLogin
FROM system.[User] AS u WITH ( NOLOCK )
WHERE ( u.Login = @p_Login )
AND ( u.Company_ID = @p_CompanyID )
AND ( pwdcompare ( @p_Password, u.Passwd ) = 1 )
AND ( u.Status = 0 ) --Active
SELECT @errNo = @@ERROR
, @recCount = @@ROWCOUNT
IF ( @errNo <> 0 )
BEGIN
RETURN 1010
END
IF ( @recCount = 1 )
BEGIN
DECLARE @userID INT
SELECT @userID = ID
FROM #tmpLogin
EXEC @res = system.usp_renewAuthenticationTicket @p_DoerTicket = ''
, @p_AuthenticationTicket = @p_AuthenticationTicket OUTPUT
, @p_UserID = @userID
, @p_CompanyID = @p_CompanyID
IF ( @res <> 0 )
RETURN @res
END
--SET @p_AuthenticationTicket = 'TESTAUTHENTICATIONTICKET0123456789'
IF ( @p_OutDetails = 1 )
BEGIN
SELECT *
FROM #tmpLogin
END
RETURN 0
END
и вот процедура регистрации пользователя
ALTER PROCEDURE [system].[usp_iudUser]
@p_ID INT = NULL OUTPUT
, @p_Login NVARCHAR ( 50 ) = NULL
, @p_Password NVARCHAR ( 32 ) = NULL
, @p_FullName NVARCHAR ( 100 ) = NULL
--, @p_LastName NVARCHAR ( 50 ) = NULL
, @p_EMail NVARCHAR ( 200 ) = NULL
, @p_Status TINYINT = NULL
, @p_Roles VARCHAR ( 200 ) = NULL
, @p_DoerTicket VARCHAR ( 200 )
AS
BEGIN
SET NOCOUNT ON;
DECLARE @doerUserID INT
, @doerCompanyID INT
EXEC system.usp_validateAuthenticationTicket @p_Ticket = @p_DoerTicket
, @p_UserID = @doerUserID OUTPUT
, @p_CompanyID = @doerCompanyID OUTPUT
MERGE INTO system.[User] AS target
USING ( SELECT @p_ID
, @doerCompanyID
, @p_Login
, @p_Password
, @p_FullName
, @p_Roles
, @p_Status
/*, @p_FirstName
, @p_LastName*/
, @p_EMail ) AS source ( ID
, CompanyID
, Login
, Password
, FullName
, Roles
, Status
/*, FirstName
, LastName*/
, EMail )
ON ( target.ID = source.ID )
AND ( target.Company_ID = source.CompanyID )
WHEN MATCHED THEN
UPDATE SET
target.Login = CASE WHEN source.Status = 200 THEN target.Login '_' CAST ( source.ID AS VARCHAR ( 10 ) ) ELSE target.Login END --Login can not be changed
, target.Passwd = ISNULL ( pwdencrypt ( source.Password ), target.Passwd )
, target.FullName = ISNULL ( source.FullName, target.FullName )
--, target.LastName = ISNULL ( source.LastName, target.LastName )
, target.EMail = ISNULL ( source.EMail, target.EMail )
, target.Roles = ISNULL ( source.Roles, target.Roles )
, target.Status = ISNULL ( source.Status, target.Status )
WHEN NOT MATCHED BY TARGET AND source.ID IS NULL THEN
INSERT ( Company_ID
, Login
, Passwd
, FullName
, Roles
, Status
/*, FirstName
, LastName*/
, EMail )
VALUES ( source.CompanyID
, source.Login
, pwdencrypt ( source.Password )
, source.FullName
, NULLIF ( RTRIM ( source.Roles ), '' )
, ISNULL ( source.Status, 0 )
/*, source.FirstName
, source.LastName*/
, NULLIF ( source.EMail, '' ) );
IF ( @@ROWCOUNT <> 1 )
BEGIN
RETURN 1010
END
IF ( @p_Id IS NULL )
SET @p_Id = SCOPE_IDENTITY ( )
RETURN 0
END
Ответ №1:
В процедуре [usp_validateUserLogin] вы используете параметр @p_OutDetails, чтобы определить, возвращаете ли вы данные вызывающей стороне, а в вызывающей стороне вы используете факт возврата записей, чтобы определить, был ли процесс успешным.
Строка ps.setString(4, null);
устанавливает значение параметра @p_OutDetails в [usp_validateUserLogin] равным null. Это отличается от того, чтобы вообще не указывать параметр, поскольку SQL Server будет использовать значение NULL вместо значения по умолчанию. Если параметр не был указан, он будет использовать значение по умолчанию (1). Кроме того, ожидаемый тип параметра — BIT, поэтому он должен использовать что-то вроде ps.SetBoolean для установки значения битовых параметров на явное значение 1 (или true).
В качестве примера, чтобы показать использование значений по умолчанию вместо указания значения NULL:
CREATE PROCEDURE TestProc
@MyString VARCHAR(10) = 'string'
AS
BEGIN
SET NOCOUNT ON
SELECT @MyString AS Param, ISNULL(@MyString, 'Was Null') AS ItsValue
END
GO
EXEC TestProc null
EXEC TestProc 'A Value'
EXEC TestProc --no params at all
Запуск этой процедуры возвращает следующее для 3 типов EXEC.
Param,ItsValue
NULL,Was Null
Param,ItsValue
A Value,A Value
Param,ItsValue
string,string
Ваш код выполняет первый способ, поэтому, когда он выполняет следующую строку, @p_OutDetails содержит NULL и пропускает этот бит.
IF ( @p_OutDetails = 1 )
BEGIN
SELECT *
FROM #tmpLogin
END
Комментарии:
1. если я использую «1» в параметре 4, я получаю неожиданный маркер параметра в позиции 38. и это вывод p_AuthenticationTicket = p_AuthenticationTicket
2. Тип параметра немного, поэтому попробуйте значение без кавычек.
3. я не могу использовать значение без qoutes, поэтому я попробовал использовать String.valueOf(test)), который является int, но это то же самое
4. поскольку битовых значений нет, но это все равно выдает мне ту же ошибку
5. Ах, вам нужно использовать ps.setboolean вместо setstring.