Display a message if user is unauthorised to run a stored procedure - sql-server

I am new to stored procedures and am just curious how things are done. What I would like to know is how to display a message if a user tries to execute a procedure that he has no rights on ?
From what I can fathom, SQL Server itself takes care of the message. I tried this way (inside a stored procedure) :
BEGIN
try
DELETE from MYTABLE
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() AS ErrorMessage;
END CATCH;
and it makes no difference weather I write this or not. The error is the same. Didnt figure out how to write your own message though ...

If a user tries to execute a stored procedure or user-defined function (UDF) that they have not been granted permissions to, either explicitly or implicitly through one or more role memberships, then SQL Server will handle the exception and error message. You cannot set a message within that code as by definition the user is not allowed to execute it to get any error message or error handling that would be inside of it.
If you want a custom message, you need to catch the SQL Exception from the app side (there should be an error code that you can test for indicating "Permission Denied") and then just return your custom message.

There is fix message or say default message display when you try to access unauthorized object.
There is so many security feature comes, like user, role, schema etc. If anything mismatch, you get the error "Could not find stored procedure 'guest.get_procedureName'."
suppose I was created a procedure with default schema(dbo) the name procedure1.
exec dbo.procedure1 para1value,'para2value', null,para4value etc.
exec guest.procedure1 para1value,'para2value', null,para4value etc.
Now if everything fine, first one give me data to sql side and C# side.
But the second will give me the above error.
Nothing to handle in the sqlserver side for this type of security, As above your code, try catch is same work as C#, but ideally, it only need when you explicitly want the message from sql return to show directly to ui i.e. custom logic error message, while you run the sp or when mismatch the data etc.
For the c# point of view, you can get this message in catch, so you can do like.
public method
{
try
{
.....
}
catch(Exception ex)
{
if (ex.Message.Contains("Could not find"))
//give any your custom message or throw ex
}
}

try
DoTheThing();
except
on E:Exception
ShowMessage("Something Went Wrong! : " + E.Message);
end;
This shows a custom message (of sorts) and it also gives you a means to examine the contents of the error via 'E'.
You can also handle more specific exceptions
except
on E:ESomeSpecificException
// ----
end;
--
As others have pointed out - there is no point in trying to catch the error inside the stored proc - the user doesnt have access to it ... by definition

Related

Delphi, FireDAC and custom login sequence

Using FireDac with SQL Server. For a program where I manage a databasconnection (and thus not always has a database to connect to from the beginning), I want this to happen:
The user connects and the OnLogin event is triggered.
First I want to try default values/values from a settings file
If that fails due to wrong user_name/password I want to show a password dialog
Repeat step 3. until login ok or user cancels.
There is some handling of a similar scenario in FireDacs own logindialog, but it seems very complex and the dialog is ugly (I would lika my own!), and also doesn't have a checkbox for "Use OS authentication" that I would need.
Any hints would be great!
/Anders
If you don't want to make a TFDGUIxLoginDialog dialog descendant, you can simply write a loop in which you'll be trying to open the connection handling EFDDBEngineException exception, and asking its Kind for ekUserPwdInvalid (optionally ekUserPwdExpired, or ekUserPwdWillExpire when you need to). Without the OnLogin event handler it can be something like this:
procedure TForm1.Button1Click(Sender: TObject);
var
LoginDialog: TMyLoginDialog;
begin
{ ← assign parameters from config file here }
while True do
try
FDConnection.Open; { ← try to connect }
except
on E: EFDDBEngineException do
case E.Kind of
ekUserPwdInvalid: { ← here you can show your login dialog }
begin
LoginDialog := TMyLoginDialog.Create(nil);
try
if LoginDialog.ShowModal = mrOk then
begin
{ ← assign parameters from login dialog here }
end
else
raise; { ← user cancelled login dialog }
finally
LoginDialog.Free;
end;
end;
ekUserPwdExpired: { here you can show password change dialog };
ekUserPwdWillExpire: { here you can optionally show password change dialog };
else
raise;
end;
else
raise;
end;
end;
The OnError event is no good for this task because there's no way to eat the exception from there. If you release the exception object there (to pretend login was successful and let the engine fail on something else for reconnect attempt), you may get unpredicted behavior (so as when you modify the exception object in a bad way).

Entity Framework does not catch SQL Exception

I am using stored procedures and running the stored procedures using "FromSql" feature provided by Microsoft Entity framework Core.
When there is a SQL exception Entity Framework does not catch the exception at all.
For example below, the stored procedure "GetAppSections" is missing in SQL.When I run the app In the debug mode I can locate the "missing stored proc" error deep inside the local window.
However logic never goes to the "Catch" block.Entity Framework simply runs the 'FromSql' command and returns an empty object. The "catch" block is never hit.
Any idea why Entity Framework is not catching the "missing stored proc" exception from SQL?
public virtual IEnumerable<appSection> GetSections()
{
try
{
return _context.appSections.FromSql("dbo.GetAppSections #p0",
parameters: new[] { _standarParams.userID.ToString()}).AsEnumerable();
}
catch (Exception ex)
{
// error handling code
}
}
You are returning an IEnumerable which is deferred. You need the try catch block around the code that actually accesses that IEnumerable (ToList, ForEach, etc).
See here and here

Can't correctly setup SQL Server connection in mORMot

I try to setup connection to SQL Server and catch the error
var
GFireDACConnProp : TSQLDBFireDACConnectionProperties;
GFFireDACConn: TSQLDBFireDACConnection;
begin
try
GFireDACConnProp := TSQLDBFireDACConnectionProperties.Create('MSSQL?Server=server','dbname','user','pass');
GFFireDACConn := TSQLDBFireDACConnection.Create(GFireDACConnProp);
// OR I := GFireDACConnProp.Execute('Select * from Station', []);
GFFireDACConn.Connect;
....
Error message:
Project app_.exe raised exception class Exception with message 'Object factory for class {3E9B315B-F456-4175-A864-B2573C4A2101} is
missing. To register it, you can drop component [TFDPhysXXXDriverLink]
into your project'.
What is correct way to connect to SQL Server and expose REST service?
FireDAC is more helpful than some other frameworks in that when things go wrong the exception messages often say how to fix the problem.
So, in your case, given that the message says "you can drop component [TFDPhysXXXDriverLink] into your project" the thing to try first would be to drop the relevant DriverLink component onto your form/datamodule. As you're using Sql Server, the the driver link to choose would be the TFDPhysMSSqlDriverLink, which is on the FireDAC Links tab of the Component Palette.
If you're creating a Console application, obviously there's no form or datamodule to drop the link on. In that case, create it in code:
FDPhysMSSQLDriverLink := TFDPhysMSSQLDriverLink.Create(Nil);
I know its an old thread, but if other come by, it can be fixed just by adding the FireDAC's units to your uses clause e.g.
uses
FireDAC.Phys.MSSQL, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.DApt, FireDAC.Stan.Async; // Not sure if you need them all, FireDAC will ask for them

Strange behavior with try-catch on Dynamics Ax 2012

I'm trying without success to figure out what I'm doing wrong trying to handle one exception in my code, hopefully someone can help me.
I'm reading an external database from within Ax to integrate some customers. So I loop through a series of records using a ResultSet object. at a given point I have some code that looks like this:
while (resultSet.next())
{
//some logic (...)
ttsbegin;
//This is a custom table that stores to where I want to integrate the given customer
while select integrationCompany
where integrationCompany.CRMCompany == customerInfo.parmCRMDataAreaId()
{
changeCompany(integrationCompany.ERPCompany)
{
try
{
customerInfo.createCustomer();
//.. some more logic
}
catch
{
// My catch Block, that should update the source database to set
// the processing status to "error"
ttsAbort;
}
}
}
ttsCommit;
}
And inside the customerInfo.createCustomer() method I'm explicitly throwing some exceptions (throw Exception::Error) if some requirements aren't met.
The problem is that the catch block isn't reached - the program stops without getting back to the main routine.
Does it has something to do with the transaction opening/aborting/commiting or is something else?
AX (X++) is strange here (if you are used .NET/Java like try/catch scenario).
If you have try inside the transaction, then fist catch cathes the excation (which is Enum and not sort of exception object).
From the MSDN: Exceptions Inside Transactions:
When an exception is thrown inside a ttsBegin - ttsCommit transaction block, no catch statement inside that transaction block can process the exception. Instead, the innermost catch statements that are outside the transaction block are the first catch statements to be tested.

WCF Which messages to return after catching an exception?

I am using a wcf service and I know how to catch all the exceptions I need...
But I dont know which messages should I return?
My code:
try
{
currentPosition = await locator.GetGeopositionAsync();
}
catch (FaultException<MessageError> ex)
{
MessageBox.Show(...?);
}
catch (EndpointNotFoundException ex)
{
MessageBox.Show(...?);
}
catch (CommunicationException ex)
{
...
}
catch (Exception ex)
{
...
}
I can return ex.Message but I dont want the client to know all the details, I want to show a short and helpful message.
What should I do?
I have always handled this situation in a similar way to the way that #Tim suggested in his comment. I need as much information to be saved so that I can debug the problem at a later date, but as you said, we don't want to show the end user the developer Exception messages.
Therefore the solution that I use is simply to store the information that comes from the Exception in the database and to provide the user with 'user-friendly' error messages. Make sure that you also add code to record any inner Exceptions as well if they exist. Now to address the question as to what to put in these messages... it really depends on your situation, but I generally follow this procedure.
First, I work out (either from forward thinking or from test results) which are the most likely errors to occur... off the top of my head, I'm talking about errors like 'no network access', or 'invalid user security', etc.
When I have a number of possible errors, I will attempt to catch the exact errors with a number of catch statements as you have. Inside the handlers, I check for certain Exception messages and return pre-written user friendly messages for each. Finally, I add one last generic message to display for all unforeseen error situations.

Resources