Hello,
I have been trying to setup a custom claim with a SQL Attribute store. I've followed numerous posts about how exactly to do this and I think I have everything setup correctly, however I am encountering a strange error that I will include below. The goal of this setup is to pull DOB information from an HR database and send it to our relying party for identity verification. the DBA team has create a stored procedure that takes sAMAccountName as an input and then returns DOB.
First here is everything that I have configured:
SQL Attribute Store: PSLocal - connection string: Data Source=DB-PSLD-P;Initial Catalog=PSData;Integrated Security=True
Custom Claims Descriptions: sAMAccountName - http://schemas.xmlsoap.org/ws/2005/05/identity/claims/samaccountname and DOB - http://schemas.xmlsoap.org/ws/2005/05/identity/claims/DOB
Custom Claim rule language to get sAMAccountName so it can be used in SQL statement below: c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
=> add(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/samaccountname"), query = ";sAMAccountName;{0}", param = c.Value);
Custom Claim rule language to use sAMAccountName claim to get DOB info using SQL: c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/samaccountname"]
=> issue(store = "PSLocal", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/DOB"), query = "EXEC [app].procGetDOBFromLogin {0}", param = c.Value);
From what I know this should work. I have the SQL attribute store defined, I get samaccountname in the claim rule language, then use samaccountname in the SQL query claim rule.
I can launch SQL management studio as my ADFS service user and connect and get the proper result using the stored procedure in the SQL claims rule. If I substitute my username in the SQL statement I get my birthday.
When I attempt to generate the claim by initiating a sign-on I see 3 errors in the ADFS 2.0 admin event log. The first of the errors is event ID 376 and I believe is the cause of the other two errors so I haven't included those in this:
An Error occurred while executing a query in SQL attribute store.
Additional Data
Connection information: POLICY3907: Server=DB-PSLD-P;Database=PSData.
Query: EXEC [App].procGetDOBFromLogin @PARAMETER0
Parameters: UserName,
User Action
Please examine the exception details to take one or more of the following actions if applicable.
Verify that the connection string to the SQL attribute store is valid.
Make sure that the SQL attribute store can be reached by the connection string and the SQL attribute store exists.
Verify that the SQL query and parameters are valid.
Exception details:
Microsoft.IdentityServer.ClaimsPolicy.Engine.AttributeStore.Sql.SqlAttributeStoreQueryExecutionException: POLICY3904: Execution of query:'EXEC [app].procGetDOBFromLogin @PARAMETER0' with parameters:'UserName,' failed. Connection information:'POLICY3907:
Server=DB-PSLD-P;Database=PSData.'. ---> System.Data.SqlClient.SqlException: Incorrect syntax near ' '.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader()
at Microsoft.IdentityServer.ClaimsPolicy.Engine.AttributeStore.Sql.SyncQueryExecutor.BeginExecuteQuery(String query, List`1 queryParameters, AsyncCallback callback, Object state)
--- End of inner exception stack trace ---
at Microsoft.IdentityServer.ClaimsPolicy.Engine.AttributeStore.Sql.SyncQueryExecutor.BeginExecuteQuery(String query, List`1 queryParameters, AsyncCallback callback, Object state)
at Microsoft.IdentityServer.ClaimsPolicy.Engine.AttributeStore.Sql.SqlAttributeStore.BeginExecuteQuery(String query, String[] queryParameterValues, AsyncCallback callback, Object state)
at Microsoft.IdentityServer.ClaimsPolicy.Language.AttributeLookupIssuanceStatement.BeginEvaluate(IEnumerable`1 matchedClaims, PolicyContext policyContext, AsyncCallback callback, Object state)
System.Data.SqlClient.SqlException: Incorrect syntax near ' '.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader()
at Microsoft.IdentityServer.ClaimsPolicy.Engine.AttributeStore.Sql.SyncQueryExecutor.BeginExecuteQuery(String query, List`1 queryParameters, AsyncCallback callback, Object state)
I guess my question is does everything look correct? The error deals with the connection string after the initial catalog statement but I don't know of any other way to write the connection string and I have verified that the ADFS service account has the proper SQL permissions. Is there anything I am missing?
As always, thanks for any help and have a good day!
Adam