实现自定义用户验证机制。
在下表中,说明部分提供 SQL 数据类型。如果您使用 Java 或 .NET 编写脚本,则应该使用相应的数据类型。 请参见SQL-Java 数据类型和SQL-.NET 数据类型。
在 SQL 脚本中,可以按名称或使用问号指定事件参数。不建议使用问号,建议您使用命名参数。不能在一个脚本中混合使用名称和问号。如果使用问号,则参数必须按照如下所示的顺序并且仅当没有指定任何后继参数时才是可选的(例如,如果您想使用参数 2,则必须使用参数 1)。如果使用命名参数,则可以按照任何顺序指定任意参数子集。
SQL 脚本的参数名称 | 说明 | 顺序(不建议用于 SQL) |
---|---|---|
s.authentication_status | INTEGER。这是一个 INOUT 参数。 | 1 |
s.remote_id | VARCHAR(128)。MobiLink 远程 ID。只有在使用命名参数时才能引用远程 ID。 | 不适用 |
s.username | VARCHAR(128)。MobiLink 用户名。 | 2 |
s.hashed_password | BINARY(32)。如果用户不提供口令,则值为空。 | 3 |
s.hashed_new_password | BINARY(32)。如果此事件不是正用于更改用户口令,则此值为空。 | 4 |
使用 MobiLink 内置用户验证机制。
该事件与 authenticate_user 相同,但是其口令是以散列形式传递的,与存储在 ml_user.hashed_password 列中口令的形式相同。以散列形式传递口令可以增强安全性。
将使用单向散列。单向散列接受口令并将其转换为一个字节序列,该序列(实质上)对每个可能的口令是唯一的。单向散列允许进行口令验证,而不必将实际的口令存储于统一数据库中。
由于 MobiLink 不同版本间散列质量的增量式提升,在一个用户的验证序列过程中可以调用此脚本多次。
如果同时定义了 authenticate_user 和 authenticate_user_hashed,并且两个脚本返回不同的 authentication_status 代码,则会使用其中较大的值。
典型的 authenticate_user_hashed 脚本是对某个存储过程的调用。该调用中参数的顺序必须与上面的顺序匹配。以下示例调用 ml_add_connection_script,将事件指派给名为 my_auth 的存储过程。
CALL ml_add_connection_script( 'ver1', 'authenticate_user_hashed', 'call my_auth ( {ml s.authentication_status}, {ml s.username}, {ml s.hashed_password})' ) |
以下 SQL Anywhere 存储过程使用用户名和口令进行验证。该过程只检查所提供的用户名是否为 ULEmployee 表中列出的一个员工 ID。该过程假定 Employee 表中有一个名为 hashed_pwd 的 binary(20) 列。
CREATE PROCEDURE my_auth( inout @authentication_status integer, in @user_name varchar(128), in @hpwd binary(32) ) BEGIN IF EXISTS ( SELECT * FROM ulemployee WHERE emp_id = @user_name and hashed_pwd = @hpwd ) THEN message 'OK' type info to client; RETURN 1000; ELSE message 'Not OK' type info to client; RETURN 4000; END IF END |
以下对 MobiLink 系统过程的调用在同步脚本版本 ver1 时将名为 authUserHashed 的 Java 方法注册为 authenticate_user_hashed 事件的脚本。
CALL ml_add_java_connection_script( 'ver1', 'authenticate_user_hashed', 'ExamplePackage.ExampleClass.authUserHashed') |
以下是 Java 方法 authUserHashed 示例。它调用检查用户口令(并在需要时更改用户口令)的 Java 方法。
public String authUserHashed( ianywhere.ml.script.InOutInteger authStatus, String user, byte pwd[], byte newPwd[] ) throws java.sql.SQLException { // A real authenticate_user_hashed handler // would handle more auth code states. _curUser = user; if( checkPwdHashed( user, pwd ) ) { // Authorization successful. if( newPwd != null ) { // Password is being changed. if( changePwdHashed( user, pwd, newPwd ) ) { // Authorization OK and password change OK. // Use custom code. authStatus.setValue( 1001 ); } else { // Auth OK but password change failed. // Use custom code java.lang.System.err.println( "user: " + user + " pwd change failed!" ); authStatus.setValue( 1002 ); } } else { authStatus.setValue( 1000 ); } } else { // Authorization failed. authStatus.setValue( 4000 ); } return ( null ); } |
以下对 MobiLink 系统过程的调用在同步脚本版本 ver1 时将名为 AuthUserHashed 的 .NET 方法注册为 authenticate_user_hashed 连接事件的脚本。此语法用于 SQL Anywhere 统一数据库。
CALL ml_add_dnet_connection_script( 'ver1', 'authenticate_user_hashed', 'TestScripts.Test.AuthUserHashed' ) |
以下是 .NET 方法 AuthUserHashed 示例。
namespace TestScripts { public class Test { string _curUser = null; public string AuthUserHashed( ref int authStatus, string user, byte[] pwdHash, byte[] newPwdHash ) { // A real authenticate_user_hashed handler // would handle more auth code states. _curUser = user; if( CheckPwdHashed( user, pwdHash ) ) { // Authorization successful. if( newPwdHash != null ) { // Password is being changed. if( ChangePwdHashed( user, pwdHash, newPwdHash ) ) { // Authorization OK and password change OK. // Use custom code. authStatus = 1001; } else { // Auth OK but password change failed. // Use custom code System.Console.WriteLine( "user: " + user + " pwd change failed!" ); authStatus = 1002; } } else { authStatus = 1000; } } else { // Authorization failed. authStatus = 4000; } return ( null ); }}} |
![]() |
使用DocCommentXchange讨论此页。
|
版权 © 2012, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.1 |