Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (中文) » MobiLink - 服务器管理 » MobiLink 事件 » 同步事件

 

authenticate_user_hashed 连接事件

实现自定义用户验证机制。

参数

在下表中,说明部分提供 SQL 数据类型。如果您使用 Java 或 .NET 编写脚本,则应该使用相应的数据类型。请参见SQL-Java 数据类型SQL-.NET 数据类型

在 SQL 脚本中,可以使用名称或问号指定事件参数,但不能在一个脚本中混合使用名称和问号。如果使用问号,则参数必须按照如下所示的顺序并且仅当没有指定任何后继参数时才是可选的(例如,如果您想使用参数 2,则必须使用参数 1)。如果使用命名参数,则可以按照任何顺序指定任意参数子集。

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(20)。如果用户不提供口令,则值为空。 3
s.hashed_new_password BINARY(20)。如果此事件不是正用于更改用户口令,则此值为空。 4
缺省操作

使用 MobiLink 内置用户验证机制。

注释

该事件与 authenticate_user 相同,但是其口令是以散列形式传递的,与存储在 ml_user.hashed_password 列中口令的形式相同。以散列形式传递口令可以增强安全性。

将使用单向散列。单向散列接受口令并将其转换为一个字节序列,该序列(实质上)对每个可能的口令是唯一的。单向散列允许进行口令验证,而不必将实际的口令存储于统一数据库中。

在一个用户的验证序列过程中,可以调用此脚本多次。

如果同时定义了 authenticate_user 和 authenticate_user_hashed,并且两个脚本返回不同的 authentication_status 代码,则会使用其中较大的值。

另请参见
SQL 示例

典型的 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(20) )
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
Java 示例

以下对 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 );
}
.NET 示例

以下对 MobiLink 系统过程的调用在同步脚本版本 ver1 时将名为 AuthUserHashed 的 .NET 方法注册为 authenticate_user_hashed 连接事件的脚本。此语法用于 SQL Anywhere 统一数据库。

CALL ml_add_dnet_connection_script(
   'ver1',
   'authenticate_user_hashed',
   'TestScripts.Test.AuthUserHashed'
)

以下是 .NET 方法 AuthUserHashed 示例。

public string AuthUserHashed(
  ref int authStatus,
  string user,
  byte[] pwd,
  byte[] newPwd ) {
  // 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 = 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 );
}