cognos自定义验证开发
众所周知,cognos8自身并不带用户管理模块,需要嵌入第三方的用户管理,项目中一般使用sunone的ldap服务器作为用户管理模块的较为常见。假如要把cognos和自己开发的门户集成的话,使用第三方的ldap服务器始终有所不便,比如增加一个用户的话要在门户的数据库中和sunone中同时增加一条记录,还要考虑数据同步的问题;再比如用户验证除了用户名密码外要增加一个验证码或者集成动态密码之类的,就显得非常复杂,因此企业在实施cognos的时候,自己开发一套用户管理程序(其实很多企业已经有了,用于单点登录),然后和cognos集成,这样做是很有必要的,下面我就简单说下这个自定义的用户管理库和cognos集成的插件的开发过程。
首先贴上我的用户管理库的表结构脚本,很简单,三个表(用户角色关系表,用户表,角色表)

CREATE TABLE [dbo].[PT_User_Role](
[ID] [int] IDENTITY(1,1) NOT NULL,
[UserID] [int] NULL,
[RoleID] [int] NULL,
CONSTRAINT [PK_User_Role] PRIMARY KEY CLUSTERED
(
[ID] ASC
)
) ON [PRIMARY]
CREATE TABLE [dbo].[PT_User](
[UserID] [int] IDENTITY(1,1) NOT NULL,
[DepID] [int] NULL,
[CardNo] [varchar](10) NULL,
[UserName] [varchar](20) NULL,
[Password] [varchar](50) NULL,
[ChineseName] [varchar](50) NULL,
[Sex] [int] NULL,
[Address] [varchar](200) NULL,
[Phone] [varchar](20) NULL,
[EMail] [varchar](50) NULL,
[Duty] [varchar](50) NULL,
[LoginFlag] [int] NULL,
[LastLogTime] [datetime] NULL,
[Status] [int] NULL,
[FullPath] [varchar](500) NULL,
[BindStatus] [int] NULL,
CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED
(
[UserID] ASC
)
) ON [PRIMARY]
CREATE TABLE [dbo].[PT_Role](
[RoleID] [int] IDENTITY(1,1) NOT NULL,
[RoleName] [varchar](50) NULL,
[Description] [varchar](500) NULL,
[RoleType] [int] NULL,
CONSTRAINT [PK_Role] PRIMARY KEY CLUSTERED
(
[RoleID] ASC
)
) ON [PRIMARY]CREATE VIEW [dbo].[pt_user_view]
AS
SELECT RoleID AS 'uid', RoleName AS 'name', RoleName AS 'givenname', 0 AS issqluser, 1 AS issqlrole
FROM dbo.PT_Role
UNION ALL
SELECT UserID AS 'uid', UserName AS 'name', ChineseName AS 'givenname', 1 AS issqluser, 0 AS issqlrole
FROM dbo.PT_User
下面开始开发集成插件,我这个也是改编自cognos8的自带的demo,只不过自带的demo用的sqlserver的系统表,不能直接拿来使用。
自带demo的路径在:D:\Program Files\cognos\c8\sdk\java\AuthenticationProvider,demo中已经有的代码我这里就不贴了,下面我会说明哪些类我做了修改,哪些类没有贴出来。
首先来看adapters目录下面的Account.java,Credential.java,Group.java,Namespace.java,NamespaceFolder.java,Role.java,TrustedCredential.java,UiClass.java,Visa.java
这些类是接口类,没有做修改,所以这里就不贴代码了。
接着来看JDBCSample这个目录下面的类,基本上全部做了修改,因此我一个一个贴,这个需要说明一下的是我的代码中采用了动态密码(用户验证的时候除了输入用户名和密码外,还绑定了一个硬件密码,类似中国移动网上营业厅手机短信二次密码),这个看客请自行去除。
先是JDBCVisa类,相当于通行证对象

package skycap.mssqlprovider;
import java.sql.Connection;
import java.sql.SQLException;
import skycap.adapters.Credential;
import skycap.adapters.TrustedCredential;
import skycap.adapters.Visa;
import skycap.adapters.Account;
import skycap.mssqlprovider.SkyCAPProvider;
import skycap.mssqlprovider.MS_JDBCDriver;
import skycap.mssqlprovider.PasspodMessage;
import skycap.mssqlprovider.QueryUtil;
import com.cognos.CAM_AAA.authentication.IBiBusHeader;
import com.cognos.CAM_AAA.authentication.ICredential;
import com.cognos.CAM_AAA.authentication.ITrustedCredential;
import com.cognos.CAM_AAA.authentication.ReadOnlyDisplayObject;
import com.cognos.CAM_AAA.authentication.SystemRecoverableException;
import com.cognos.CAM_AAA.authentication.TextDisplayObject;
import com.cognos.CAM_AAA.authentication.TextNoEchoDisplayObject;
import com.cognos.CAM_AAA.authentication.UnrecoverableException;
import com.cognos.CAM_AAA.authentication.UserRecoverableException;
public class JDBCVisa extends Visa
{
private Connection connection;
private String connectionString;
private String username;
private String password;
public JDBCVisa()
{
super();
}
public void init(SkyCAPProvider theNamespace, String theConnectionString,
String theUsername, String thePassword, String theDPassword)
throws UnrecoverableException {
connectionString = theConnectionString;
try {
connection = MS_JDBCDriver.driver.getConnection(connectionString);
PasspodMessage message = QueryUtil.ValidateUser(MS_JDBCDriver.driver, connection,
theNamespace, theUsername, thePassword, theDPassword);
if ( message.getReturnValue()== false) {
UserRecoverableException e = new UserRecoverableException(
"请输入用于身份验证的凭证."+message.getReturnMessage(), "提供的用户信息不正确.");
e.addDisplayObject(new TextDisplayObject("用户 ID:",
"CAMUsername"));
e.addDisplayObject(new TextNoEchoDisplayObject("密码:",
"CAMPassword"));
e.addDisplayObject(new TextNoEchoDisplayObject("动态密码:",
"CAMDPassword"));
throw e;
}
Account account = QueryUtil.createAccount(MS_JDBCDriver.driver,
connection, theNamespace, theUsername);
super.init(account);
QueryUtil.updateMembership(MS_JDBCDriver.driver, connection, this);
this.username = theUsername;
this.password = thePassword;
} catch (SQLException e) {
throw new UnrecoverableException("Connection Error",
"Database connection failure. Reason: " + e.toString());
}
}
public void destroy() throws UnrecoverableException
{
try
{
connection.close();
}
catch (SQLException e)
{
throw new UnrecoverableException("Disconnection Error",
"Database connection failure. Reason: " + e.toString());
}
super.destroy();
}
public Connection getConnection()
{
return connection;
}
private boolean validateConnection(String username, String password)
{
boolean bConnectionValid = false;
try
{
Connection newConnection = MS_JDBCDriver.driver.getConnection(
connectionString);
//If getConnection did not throw, we know it succeeded.
bConnectionValid = true;
this.connection.close();
this.connection = newConnection;
this.username = username;
this.password = password;
}
catch (SQLException ex)
{
}
return bConnectionValid;
}
/*
* (non-Javadoc)
*
* @see com.cognos.CAM_AAA.provider.IVisa#generateCredential(com.cognos.CAM_AAA.objectModel.IAuthenticateRequest)
*/
public ICredential generateCredential(IBiBusHeader theAuthRequest)
throws UserRecoverableException, SystemRecoverableException,
UnrecoverableException
{
if (!this.validateConnection(this.username, this.password))
{
UnrecoverableException e = new UnrecoverableException(
"Could not generate credentials for the user.",
"Visa contains invalid credentials.");
throw e;
}
Credential credentials = new Credential();
credentials.addCredentialValue("username", username);
credentials.addCredentialValue("password", password);
return credentials;
}
/*
* (non-Javadoc)
*
* @see com.cognos.CAM_AAA.authentication.IVisa#generateTrustedCredential(com.cognos.CAM_AAA.authentication.IBiBusHeader)
*/
/*
* (non-Javadoc)
*
* @see com.cognos.CAM_AAA.provider.IVisa#generateTrustedCredential(com.cognos.CAM_AAA.objectModel.IAuthenticateRequest)
*/
public ITrustedCredential generateTrustedCredential(
IBiBusHeader theAuthRequest) throws UserRecoverableException,
SystemRecoverableException, UnrecoverableException
{
boolean isValidCredentials = true;
String[] theUsername = null;
String[] thePassword = null;
// 1 - Look for credentials coming from SDK request
theUsername = theAuthRequest.getCredentialValue("username");
thePassword = theAuthRequest.getCredentialValue("password");
if (theUsername == null && thePassword == null)
{
// 2 - Look for credentials in formfield
theUsername = theAuthRequest.getFormFieldValue("CAMUsername");
thePassword = theAuthRequest.getFormFieldValue("CAMPassword");
}
if (theUsername != null && theUsername.length == 1
&& theUsername[0].equals(username) && thePassword.length == 1)
{
isValidCredentials = this.validateConnection(theUsername[0],
thePassword[0]);
}
else
{
isValidCredentials = this.validateConnection(this.username,
this.password);
}
if (!isValidCredentials)
{
UserRecoverableException e = new UserRecoverableException(
"Please type your credentials for authentication.",
"The provided credentials are invalid.");
e.addDisplayObject(new ReadOnlyDisplayObject("User ID:",
"CAMUsername", this.username));
e.addDisplayObject(new TextNoEchoDisplayObject("Password:",
"CAMPassword"));
throw e;
}
TrustedCredential tc = new TrustedCredential();
tc.addCredentialValue("username", username);
tc.addCredentialValue("password", password);
return tc;
}
}
MS_JDBCDriver 微软的jdbc驱动

package skycap.mssqlprovider;
import java.io.PrintStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;
public class MS_JDBCDriver
{
protected static MS_JDBCDriver driver = new MS_JDBCDriver();
public MS_JDBCDriver()
{
try
{
//
// Load the Microsoft SQLServer JDBC Driver.
//
//Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
}
catch (Exception e)
{
e.printStackTrace();
}
}
public String getConnectionString(String theServer, String theDatabase,String theUserName, String thePassword)
{
String connectionString = "jdbc:sqlserver://" + theServer;
connectionString += ";DatabaseName=" + theDatabase;
connectionString += ";User=" + theUserName;
connectionString += ";Password=" + thePassword;
return connectionString;
}
public void checkDbConnection(String theConnectionString)
throws SQLException
{
try
{
Connection connection = DriverManager
.getConnection(theConnectionString);
}
catch (SQLException e)
{
//
// TODO: This is a crude attempt at validating the database
// connection.
//
if (e.getErrorCode() == 0)
{
throw e;
}
}
}
public Connection getConnection(String theConnectionString) throws SQLException
{
return DriverManager.getConnection(theConnectionString);
}
public Vector query(Connection theConnection, String theSqlQuery)
throws SQLException
{
Vector retval = new Vector();
Statement stmt = theConnection.createStatement();
ResultSet result = stmt.executeQuery(theSqlQuery);
ResultSetMetaData rsmd = result.getMetaData();
// First row contains the metadata
Vector metadata = new Vector();
for (int i = 1; i <= rsmd.getColumnCount(); i++)
{
metadata.add(rsmd.getColumnName(i));
}
retval.add(metadata);
while (result.next())
{
Vector row = new Vector();
for (int i = 1; i <= rsmd.getColumnCount(); i++)
{
row.add(result.getString(i));
}
retval.add(row);
}
return retval;
}
public void dumpData(Vector theData, PrintStream thePrintStream)
{
for (int i = 0; i < theData.size(); i++)
{
Vector row = (Vector) theData.elementAt(i);
for (int j = 0; j < row.size(); j++)
{
thePrintStream.print("\t" + row.elementAt(j));
}
thePrintStream.println();
}
}
}
QueryUtil查询数据库辅助类

package skycap.mssqlprovider;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Locale;
import java.util.Vector;
import org.apache.commons.codec.digest.DigestUtils;
import skycap.adapters.Account;
import skycap.adapters.Role;
import skycap.mssqlprovider.MS_JDBCDriver;
import skycap.mssqlprovider.PasspodMessage;
import com.cognos.CAM_AAA.authentication.INamespace;
import com.cognos.CAM_AAA.authentication.IQueryOption;
import com.cognos.CAM_AAA.authentication.ISearchFilter;
import com.cognos.CAM_AAA.authentication.ISearchFilterConditionalExpression;
import com.cognos.CAM_AAA.authentication.ISearchFilterFunctionCall;
import com.cognos.CAM_AAA.authentication.ISearchFilterRelationExpression;
import com.cognos.CAM_AAA.authentication.ISortProperty;
import com.cognos.CAM_AAA.authentication.QueryResult;
public class QueryUtil
{
public static Account createAccount(MS_JDBCDriver theDriver,
Connection theConnection, INamespace theNamespace, String userName)
throws SQLException {
Vector data = theDriver.query(theConnection,
"select UserID from dbo.PT_User where UserName='" + userName
+ "'");
String userID = getSingleStringResult(data);
if (userID != null) {
String userSearchPath = "u:" + userID;
Account account = new Account(userSearchPath);
account.setUserName(userName);
getAccountProperties(theDriver, theConnection, account);
return account;
}
return null;
}
public static PasspodMessage ValidateUser(MS_JDBCDriver theDriver,
Connection theConnection, INamespace theNamespace, String userName,
String password, String dpassword) throws SQLException {
PasspodMessage result = new PasspodMessage();
String enpassword = DigestUtils.md5Hex(password).toUpperCase();
Vector data;
data = theDriver.query(theConnection,
"select UserID from dbo.PT_User where UserName='" + userName
+ "' and Password='" + enpassword + "'");
String userID = getSingleStringResult(data);
if (userID != null) {
result.setReturnValue(true);
//result = PasspodUtil.AuthUserPasspod(userName, dpassword);
} else {
result.setReturnValue(false);
result.setReturnMessage("用户名或密码错误.");
}
return result;
}
private static String getSingleStringResult(Vector theData)
{
if (theData.size() == 2)
{
Vector row = (Vector) theData.elementAt(1);
if (row.size() == 1)
{
return (String) row.elementAt(0);
}
}
return null;
}
private static String getValueFromResult(Vector theData, String theName)
{
if (theData.size() > 1)
{
//
// Search metadata for index of what we're looking for
//
Vector metadata = (Vector) theData.elementAt(0);
for (int i = 0; i < metadata.size(); i++)
{
if (theName.compareToIgnoreCase((String) metadata.elementAt(i)) == 0)
{
//
// We found it, return the data
//
Vector row = (Vector) theData.elementAt(1);
return (String) row.elementAt(i);
}
}
}
return null;
}
public static void getAccountProperties(MS_JDBCDriver theDriver,
Connection theConnection, Account theAccount) throws SQLException {
String userid = theAccount.getObjectID().substring(2);
Vector data = theDriver.query(theConnection,
"select ChineseName from dbo.PT_User where userid=" + userid);
String givename = getSingleStringResult(data);
theAccount.setGivenName(givename);
data = theDriver.query(theConnection,
"select EMail from dbo.PT_User where userid=" + userid);
String email = getSingleStringResult(data);
theAccount.setEmail(email);
theAccount.setProductLocale(Locale.SIMPLIFIED_CHINESE);
theAccount.setContentLocale(Locale.SIMPLIFIED_CHINESE);
theAccount.addName(Locale.SIMPLIFIED_CHINESE, givename);
}
private static Locale getLocale(String theLocaleID)
{
if (theLocaleID != null)
{
switch (new Integer(theLocaleID).intValue())
{
case 1033 :
return Locale.US;
case 1031 :
return Locale.GERMAN;
case 1036 :
return Locale.FRENCH;
case 1041 :
return Locale.JAPANESE;
case 2057 :
return Locale.UK;
case 1028 :
return Locale.TRADITIONAL_CHINESE;
case 1042 :
return Locale.KOREAN;
case 2052 :
return Locale.SIMPLIFIED_CHINESE;
}
}
return Locale.ENGLISH;
}
public static void updateMembership(MS_JDBCDriver theDriver,
Connection theConnection, JDBCVisa theVisa) throws SQLException
{
// Retrieve Role membership
Vector data = theDriver.query(theConnection, "select RoleName,RoleID from dbo.PT_Role");
if (data.size() > 1)
{
for (int i = 1; i < data.size(); i++)
{
Vector row = (Vector) data.elementAt(i);
String roleName = (String) row.elementAt(0);
String roleID = (String) row.elementAt(1);
String userID = theVisa.getAccount().getObjectID();
if (userID == null)
{
return;
}
userID = userID.substring(2);
Vector data2 = theDriver.query(theConnection,
"select COUNT(*) from dbo.PT_User_Role where RoleID="+roleID+" and UserId="+userID);
String isMember = getSingleStringResult(data2);
if (isMember.compareTo("1") == 0)
{
Role role = new Role("r:" + roleID);
role.addName(theVisa.getAccount().getContentLocale(),
roleName);
theVisa.addRole(role);
}
}
}
}
public static void queryMembers(MS_JDBCDriver theDriver,
Connection theConnection, ISortProperty[] theSortProperties,
Role theRole, INamespace theNamespace) throws SQLException
{
StringBuffer sqlStatement = new StringBuffer();
String roleID = theRole.getObjectID();
if (roleID == null)
{
return;
}
roleID = roleID.substring(2);
sqlStatement
.append("select u.UserID as 'uid',u.UserName as 'name',1 as issqluser,0 as issqlrole from dbo.PT_User u inner join dbo.PT_User_Role ur on u.UserID=ur.UserID where ur.RoleID="
+ roleID);
String theSortClause = new String();
if (theSortProperties != null)
{
for (int i = 0; i < theSortProperties.length; i++)
{
ISortProperty property = theSortProperties[i];
if (property.getPropertyName().compareTo("name") == 0)
{
if (theSortClause.length() > 0)
{
theSortClause += ", ";
}
theSortClause += "name";
if (property.getSortOrder() == ISortProperty.SortOrderAscending)
{
theSortClause += " ASC";
}
else
{
theSortClause += " DESC";
}
}
}
if (theSortClause.length() > 0)
{
sqlStatement.append("ORDER BY ");
sqlStatement.append(theSortClause);
}
}
Vector data = theDriver.query(theConnection, sqlStatement.toString());
if (data.size() > 1)
{
for (int i = 1; i < data.size(); i++)
{
Vector row = (Vector) data.elementAt(i);
// "SELECT [uid], [name], [issqluser], [issqlrole] FROM
// sysusers " );
String objectID = (String) row.elementAt(0);
String objectName = (String) row.elementAt(1);
String isSqlUser = (String) row.elementAt(2);
String isSqlRole = (String) row.elementAt(3);
if (isSqlUser.compareTo("1") == 0)
{
String searchPath = "u:" + objectID;
Account account = new Account(searchPath);
account.addName(Locale.getDefault(), objectName);
account.setUserName(objectName);
theRole.addMember(account);
}
else if (isSqlRole.compareTo("1") == 0)
{
String searchPath = "r:" + objectID;
Role role = new Role(searchPath);
role.addName(Locale.getDefault(), objectName);
theRole.addMember(role);
}
}
}
}
public static void query(MS_JDBCDriver theDriver, Connection theConnection,
String theSqlCondition, IQueryOption theQueryOption,
String[] theProperties, ISortProperty[] theSortProperties,
QueryResult theResult, INamespace theNamespace) throws SQLException
{
StringBuffer sqlStatement = new StringBuffer();
sqlStatement
.append("SELECT [uid],[name],[givenname],[issqluser],[issqlrole] FROM [dbo].[pt_user_view] ");
if (theSqlCondition.length() > 0)
{
sqlStatement.append("WHERE ");
sqlStatement.append(theSqlCondition);
}
long maxCount = theQueryOption.getMaxCount();
long skipCount = theQueryOption.getSkipCount();
String theSortClause = new String();
if (theSortProperties != null)
{
for (int i = 0; i < theSortProperties.length; i++)
{
ISortProperty property = theSortProperties[i];
if (property.getPropertyName().compareTo("name") == 0)
{
if (theSortClause.length() > 0)
{
theSortClause += ", ";
}
theSortClause += "name";
if (property.getSortOrder() == ISortProperty.SortOrderAscending)
{
theSortClause += " ASC";
}
else
{
theSortClause += " DESC";
}
}
}
if (theSortClause.length() > 0)
{
sqlStatement.append("ORDER BY ");
sqlStatement.append(theSortClause);
}
}
Vector data = theDriver.query(theConnection, sqlStatement.toString());
if (data.size() > 1)
{
long curSkip = 0, curMax = 0;
for (int i = 1; i < data.size(); i++)
{
Vector row = (Vector) data.elementAt(i);
boolean bIsUser = ( ( (String) row.elementAt(3) ).compareTo("1") == 0 );
boolean bIsRole = ( ( (String) row.elementAt(4) ).compareTo("1") == 0 );
//We need to handle paging information
if( bIsUser || bIsRole )
{
if( curSkip++ < skipCount ) //We need to skip skipCount first objects
continue;
else if ( curMax >= maxCount && maxCount != -1 ) //If we already have maxCount objects, we can stop looking
break;
else // curMax < maxCount - we need to keep retrieving entries
curMax++;
}
else //If the entry is neither a user nor a role, we'll skip it
continue;
String objectID = (String) row.elementAt(0);
String objectName = (String) row.elementAt(1);
String givenName = (String) row.elementAt(2);
if( bIsUser )
{
String searchPath = "u:" + objectID;
Account account = new Account(searchPath);
account.addName(Locale.getDefault(), givenName);
account.setUserName(objectName);
account.setGivenName(givenName);
theResult.addObject(account);
}
else if( bIsRole )
{
String searchPath = "r:" + objectID;
Role role = new Role(searchPath);
role.addName(Locale.getDefault(), givenName);
QueryUtil.queryMembers(theDriver, theConnection,
theSortProperties, role, theNamespace);
theResult.addObject(role);
}
}
}
}
public static String escapeSpecialChars(String str)
{
StringBuffer escapedString = new StringBuffer( str );
for( int i = 0; i < escapedString.length(); )
{
char c = escapedString.charAt(i);
switch( c )
{
case '\'':
escapedString.insert( i, "!'" );
i += 3;
break;
case '%':
escapedString.insert( i, "!%" );
i += 3;
break;
default:
i++;
break;
}
}
return escapedString.toString();
}
public static String getSqlCondition(ISearchFilter theSearchFilter)
{
StringBuffer sqlCondition = new StringBuffer();
if (theSearchFilter != null)
{
switch (theSearchFilter.getSearchFilterType())
{
case ISearchFilter.ConditionalExpression :
{
ISearchFilterConditionalExpression item = (ISearchFilterConditionalExpression) theSearchFilter;
String operator = item.getOperator();
ISearchFilter[] filters = item.getFilters();
if (filters.length > 0)
{
sqlCondition.append("( ");
sqlCondition.append(getSqlCondition(filters[0]));
for (int i = 1; i < filters.length; i++)
{
sqlCondition.append(' ');
sqlCondition.append(operator);
sqlCondition.append(' ');
sqlCondition
.append(getSqlCondition(filters[i]));
}
sqlCondition.append(" )");
}
}
break;
case ISearchFilter.FunctionCall :
{
ISearchFilterFunctionCall item = (ISearchFilterFunctionCall) theSearchFilter;
String functionName = item.getFunctionName();
if (functionName
.equals(ISearchFilterFunctionCall.Contains))
{
String[] parameter = item.getParameters();
String propertyName = parameter[0];
String value = parameter[1];
if (propertyName.compareTo("@objectClass") == 0)
{
if ("account".indexOf(value) > 0)
{
sqlCondition.append(" issqluser = 1 ");
}
else if ("role".indexOf(value) > 0)
{
sqlCondition
.append(" ( issqlrole = 1 ) ");
}
else
{
//
// Make sure this is a false statement
//
sqlCondition.append(" 1 = 0 ");
}
}
else if (propertyName.equals("@defaultName")
|| propertyName.equals("@userName")
|| propertyName.equals("@name"))
{
sqlCondition.append(" name LIKE '%" + escapeSpecialChars(value)
+ "%' ESCAPE '!'");
}
else
{
//
// We ignore the properties that are not
// supported.
//
sqlCondition.append(" 1 = 1 ");
}
}
else if (functionName
.compareTo(ISearchFilterFunctionCall.StartsWith) == 0)
{
String[] parameter = item.getParameters();
String propertyName = parameter[0];
String value = parameter[1];
if (propertyName.compareTo("@objectClass") == 0)
{
if ("account".startsWith(value))
{
sqlCondition.append(" issqluser = 1 ");
}
else if ("role".startsWith(value))
{
sqlCondition
.append(" ( issqlrole = 1 ) ");
}
else
{
//
// Make sure this is a false statement
//
sqlCondition.append(" 1 = 0 ");
}
}
else if (propertyName.compareTo("@defaultName") == 0
|| propertyName.compareTo("@userName") == 0
|| propertyName.compareTo("@name") == 0)
{
sqlCondition.append(" name LIKE '" + escapeSpecialChars(value)
+ "%' ESCAPE '!'");
}
else
{
//
// We ignore the properties that are not
// supported.
//
sqlCondition.append(" 1 = 1 ");
}
}
else if (functionName
.compareTo(ISearchFilterFunctionCall.EndsWith) == 0)
{
String[] parameter = item.getParameters();
String propertyName = parameter[0];
String value = parameter[1];
if (propertyName.compareTo("@objectClass") == 0)
{
if ("account".endsWith(value))
{
sqlCondition.append(" issqluser = 1 ");
}
else if ("role".endsWith(value))
{
sqlCondition
.append(" ( issqlrole = 1 ) ");
}
else
{
//
// Make sure this is a false statement
//
sqlCondition.append(" 1 = 0 ");
}
}
else if (propertyName.compareTo("@defaultName") == 0
|| propertyName.compareTo("@userName") == 0
|| propertyName.compareTo("@name") == 0)
{
sqlCondition.append(" name LIKE '" + escapeSpecialChars(value)
+ "%' ESCAPE '!'");
}
else
{
//
// We ignore the properties that are not
// supported.
//
sqlCondition.append(" 1 = 1 ");
}
}
else
{
//
// Ignore the funtion we don't understand.
//
sqlCondition.append(" 1 = 1 ");
}
}
break;
case ISearchFilter.RelationalExpression :
{
ISearchFilterRelationExpression item = (ISearchFilterRelationExpression) theSearchFilter;
String propertyName = item.getPropertyName();
String constraint = item.getConstraint();
String operator = item.getOperator();
if (propertyName.equals("@objectClass"))
{
if (constraint.equals("account"))
{
if (operator
.equals(ISearchFilterRelationExpression.EqualTo))
{
sqlCondition.append(" issqluser = 1 ");
}
else if (operator
.equals(ISearchFilterRelationExpression.NotEqual))
{
sqlCondition.append(" issqluser = 0 ");
}
else
{
//
// Make sure this is a false statement
//
sqlCondition.append(" 1 = 0 ");
}
}
else if (constraint.equals("role"))
{
if (operator
.equals(ISearchFilterRelationExpression.EqualTo))
{
sqlCondition
.append(" ( issqlrole = 1 ) ");
}
else if (operator
.equals(ISearchFilterRelationExpression.NotEqual))
{
sqlCondition
.append(" ( issqlrole = 0 ) ");
}
else
{
//
// Make sure this is a false statement
//
sqlCondition.append(" 1 = 0 ");
}
}
else
{
sqlCondition.append(" 1 = 0 ");
}
}
else if (propertyName.equals("@defaultName")
|| propertyName.equals("@userName")
|| propertyName.equals("@name"))
{
sqlCondition.append(" name " + operator + " '"
+ constraint + "'");
}
else
{
//
// We ignore the properties that are not supported.
//
sqlCondition.append(" 1 = 1 ");
}
}
break;
}
}
return sqlCondition.toString();
}
}
SkyCAPProvider自定义验证的入口类

package skycap.mssqlprovider;
import java.io.File;
import java.io.FileInputStream;
import java.util.Locale;
import java.util.Properties;
import skycap.adapters.Namespace;
import skycap.mssqlprovider.JDBCVisa;
import skycap.mssqlprovider.MS_JDBCDriver;
import com.cognos.CAM_AAA.authentication.IBiBusHeader;
import com.cognos.CAM_AAA.authentication.IBiBusHeader2;
import com.cognos.CAM_AAA.authentication.INamespaceAuthenticationProvider2;
import com.cognos.CAM_AAA.authentication.INamespaceConfiguration;
import com.cognos.CAM_AAA.authentication.IQuery;
import com.cognos.CAM_AAA.authentication.IQueryResult;
import com.cognos.CAM_AAA.authentication.ISearchExpression;
import com.cognos.CAM_AAA.authentication.ISearchFilter;
import com.cognos.CAM_AAA.authentication.ISearchStep;
import com.cognos.CAM_AAA.authentication.IVisa;
import com.cognos.CAM_AAA.authentication.QueryResult;
import com.cognos.CAM_AAA.authentication.SystemRecoverableException;
import com.cognos.CAM_AAA.authentication.TextDisplayObject;
import com.cognos.CAM_AAA.authentication.TextNoEchoDisplayObject;
import com.cognos.CAM_AAA.authentication.UnrecoverableException;
import com.cognos.CAM_AAA.authentication.UserRecoverableException;
import com.cognos.CAM_AAA.authentication.ISearchStep.SearchAxis;
public class SkyCAPProvider extends Namespace
implements INamespaceAuthenticationProvider2
{
private String connectionString;
/*
* @see com.cognos.CAM_AAA.provider.INamespace#init(com.cognos.CAM_AAA.provider.INamespaceConfiguration)
*/
public void init(INamespaceConfiguration theNamespaceConfiguration)
throws UnrecoverableException
{
super.init(theNamespaceConfiguration);
this.addName(Locale.SIMPLIFIED_CHINESE, theNamespaceConfiguration
.getDisplayName());
try {
//
// Read our configuration from this Cognos 8 install's
// configuration directory.
//
String configPath = theNamespaceConfiguration.getInstallLocation()
+ "/configuration";
File nsConfig = new File(configPath, "JDBC_Config_"
+ theNamespaceConfiguration.getID() + ".properties");
Properties nsProperties = new Properties();
FileInputStream input = new FileInputStream(nsConfig);
nsProperties.load(input);
String server = nsProperties.getProperty("server");
String databaseName = nsProperties.getProperty("databaseName");
String userName = nsProperties.getProperty("username");
String password = nsProperties.getProperty("password");
connectionString = MS_JDBCDriver.driver.getConnectionString(server,
databaseName, userName, password);
MS_JDBCDriver.driver.checkDbConnection(connectionString);
} catch (Exception e) {
throw new UnrecoverableException("Configuration Error",
"Provider initialization failure. Reason: " + e.toString());
}
}
/*
* @see com.cognos.CAM_AAA.provider.INamespaceAuthenticationProvider2#logon(com.cognos.CAM_AAA.provider.IBiBusHeader2)
*/
public IVisa logon(IBiBusHeader2 theAuthRequest)
throws UserRecoverableException, SystemRecoverableException,
UnrecoverableException
{
JDBCVisa visa = null;
String[] username = null;
String[] password = null;
String[] dpassword = null;
// 1 - Look for trusted credentials
username = theAuthRequest.getTrustedCredentialValue("username");
password = theAuthRequest.getTrustedCredentialValue("password");
dpassword = theAuthRequest.getTrustedCredentialValue("dpassword");
if (username == null && password == null) {
// 2 - Look for credentials coming from SDK request
username = theAuthRequest.getCredentialValue("username");
password = theAuthRequest.getCredentialValue("password");
dpassword = theAuthRequest.getCredentialValue("dpassword");
}
if (username == null && password == null) {
// 3 - Look for credentials in formfield
username = theAuthRequest.getFormFieldValue("CAMUsername");
password = theAuthRequest.getFormFieldValue("CAMPassword");
dpassword = theAuthRequest.getFormFieldValue("CAMDPassword");
}
if (username == null || password == null) {
UserRecoverableException e = new UserRecoverableException(
"请输入用于身份验证的凭证.", "提供的用户信息不正确.");
e.addDisplayObject(new TextDisplayObject("用户 ID:", "CAMUsername"));
e
.addDisplayObject(new TextNoEchoDisplayObject("密码:",
"CAMPassword"));
e.addDisplayObject(new TextNoEchoDisplayObject("动态密码:",
"CAMDPassword"));
throw e;
}
try {
//
// Create a Visa for the new user.
//
visa = new JDBCVisa();
visa.init(this, connectionString, username[0], password[0],
dpassword[0]);
} catch (UserRecoverableException ex) {
throw ex;
} catch (UnrecoverableException ex) {
// Something went wrong, probably because the user's credentials
// are invalid.
UserRecoverableException e = new UserRecoverableException(
"请输入用于身份验证的凭证.", "提供的用户信息不正确.");
e.addDisplayObject(new TextDisplayObject("用户 ID:", "CAMUsername"));
e
.addDisplayObject(new TextNoEchoDisplayObject("密码:",
"CAMPassword"));
e.addDisplayObject(new TextNoEchoDisplayObject("动态密码:",
"CAMDPassword"));
throw ex;
}
return visa;
}
/*
* @see com.cognos.CAM_AAA.provider.INamespaceAuthenticationProvider#logoff(com.cognos.CAM_AAA.provider.IVisa,
* com.cognos.CAM_AAA.provider.IBiBusHeader)
*/
public void logoff(IVisa theVisa, IBiBusHeader theAuthRequest)
{
try
{
// We can safely assume that we'll get back the same Visa that we
// issued.
JDBCVisa visa = (JDBCVisa) theVisa;
visa.destroy();
}
catch (Throwable t)
{
}
}
/*
* @see com.cognos.CAM_AAA.provider.INamespaceAuthenticationProvider#search(com.cognos.CAM_AAA.provider.IVisa,
* com.cognos.CAM_AAA.provider.IQuery)
*/
public IQueryResult search(IVisa theVisa, IQuery theQuery)
throws UnrecoverableException
{
// We can safely assume that we'll get back the same Visa that we
// issued.
JDBCVisa visa = (JDBCVisa) theVisa;
QueryResult result = new QueryResult();
try
{
ISearchExpression expression = theQuery.getSearchExpression();
String objectID = expression.getObjectID();
ISearchStep[] steps = expression.getSteps();
// It doesn't make sense to have multiple steps for this provider
// since the objects are not hierarchical.
if (steps.length != 1)
{
throw new UnrecoverableException(
"Internal Error",
"Invalid search expression. Multiple steps is not supported for this namespace.");
}
StringBuffer sqlCondition = new StringBuffer();
int searchType = steps[0].getAxis();
ISearchFilter filter = steps[0].getPredicate();
switch (searchType)
{
case SearchAxis.Self :
case SearchAxis.DescendentOrSelf :
{
if (objectID == null)
{
if (filter == null
|| this.matchesFilter( filter))
{
result.addObject(this);
// Add current namespace
}
if (searchType == SearchAxis.Self)
{
return result;
}
else
{
sqlCondition.append(QueryUtil
.getSqlCondition(filter));
}
}
else if (objectID.startsWith("u:")
&& objectID.equals(visa.getAccount()
.getObjectID()))
{
if (filter == null
|| this.matchesFilter(filter))
{
result.addObject(visa.getAccount());
// Add current user
}
return result;
}
else if (objectID.startsWith("u:")
|| objectID.startsWith("r:"))
{
String sqlID = objectID.substring(2);
sqlCondition.append(QueryUtil
.getSqlCondition(filter));
if (sqlCondition.length() > 0)
{
sqlCondition.append(" AND ");
}
sqlCondition.append("uid = " + sqlID);
}
}
break;
default :
{
sqlCondition.append(QueryUtil.getSqlCondition(filter));
}
break;
}
QueryUtil.query(MS_JDBCDriver.driver, visa.getConnection(),
sqlCondition.toString(), theQuery.getQueryOption(),
theQuery.getProperties(), theQuery.getSortProperties(),
result, this);
}
catch (Throwable t)
{
t.printStackTrace();
}
return result;
}
}
package skycap.mssqlprovider; public class PasspodMessage { private Boolean _returnvalue = false ; private String _returnmessage = "" ; public Boolean getReturnValue() { return _returnvalue; } public void setReturnValue(Boolean value) { _returnvalue = value; } public String getReturnMessage() { return _returnmessage; } public void setReturnMessage(String message) { _returnmessage = message; } } |
对于程序员来说,代码胜于言语,我想以上的代码已经可以足够表达这个过程了。完工,闪人。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
2008-07-28 BI学习书籍推荐