I am supporting a site that uses identityserver for authentication and I am trying to understand how it works.
Periodically the site becomes bit slow and from appinsights I can see the endpoint which calls RoleManager.FindByNameAsync(name) randomly becomes slow.
Appinsights shows that FindByNameAsync will call our sql db:
SELECT [t].[Id], [t].[Email], [t].[FirstName], [t].[LastName], [t].[UserName], [t].[CreatedAtUtc] AS [CreatedAt], [t].[EmailConfirmed], [t].[LastLoginUtc] AS [LastLogin], [t].[LockoutEnabled], [t].[LockoutEnd] AS [LockoutEndDateUtc], [claim].[ClaimType] AS [Type], [claim].[ClaimValue] AS [Value], [claim].[Id] AS [Id0]
FROM [UserClaims] AS [claim]
INNER JOIN (
SELECT [user].*
FROM [Users] AS [user]
WHERE [user].[Id] IN (
SELECT [claim0].[UserId]
FROM [UserClaims] AS [claim0]
WHERE ([claim0].[ClaimType] = #__type_0) AND ([claim0].[ClaimValue] = #__value_1)
)
) AS [t] ON [claim].[UserId] = [t].[Id]
The db call itself is not slow (100ms at max), so I am guessing the c# code is doing something.
How RoleManager.FindByNameAsync is integrated with identityserver?
RoleManager is a Microsoft extension and I didn't really find a setting in our config which links identityserver to this (admit that I am quite new with identityserver).
Related
In the Security/Users folder in my database, I have a bunch of security groups, include "MyApplication Users". I need to check if I am (or another user is) in this group, but I have no idea how to query for it or where I could see this information. I tried looking in the properties, but couldn't find anything. Any ideas?
Checking yourself or the current user:
SELECT IS_MEMBER('[group or role]')
A result of 1 = yes,0 = no, and null = the group or role queried is not valid.
To get a list of the users, try xp_logininfo if extended procs are enabled and the group in question is a windows group :
EXEC master..xp_logininfo
#acctname = '[group]',
#option = 'members'
For a quick view of which groups / roles the current user is a member of;
select
[principal_id]
, [name]
, [type_desc]
, is_member(name) as [is_member]
from [sys].[database_principals]
where [type] in ('R','G')
order by [is_member] desc,[type],[name]
To find the AD Group members in the Instance, we can use below query:
xp_logininfo 'DomainName\AD_GroupName', 'members'
By using this query, we can find the below states.
account name, type, privilege, mapped login name, permission path
Accepted answer from DeanG is the preferred solution for getting this info within SQL Server
You can use Active Directory tools for this. I like Active Directory Users and Computers that is part of the Remote Server Administration Tools. Follow the link to download and install the tools on Windows 7.
Once installed, you can search for a specific group name:
Then you can see group membership using the Members tab:
If you don't want to use the AD browser packaged with RSA tools, there are several others available.
You don't.
Instead you use the users and groups to grant/deny privileges, and let the engine enforce them appropiately. Attempting to roll your own security will get you nowhere fast. A banal example is when you will fail to honor the 'one deny trumps all grants' rule. And you will fail to navigate the intricacies of EXECUTE AS. Not to mention security based on module signatures.
For the record: users, roles and groups are exposed in the sys.database_principals catalog view. sys.fn_my_permissions will return the current context permissions on a specific securable.
The code that is provided on the Microsoft page here works for me, every time.
SELECT DP1.name AS DatabaseRoleName,
isnull (DP2.name, 'No members') AS DatabaseUserName
FROM sys.database_role_members AS DRM
RIGHT OUTER JOIN sys.database_principals AS DP1
ON DRM.role_principal_id = DP1.principal_id
LEFT OUTER JOIN sys.database_principals AS DP2
ON DRM.member_principal_id = DP2.principal_id
WHERE DP1.type = 'R'
ORDER BY DP1.name;
Please let me know if this works for you!
I am trying to setup client_credentials grant type in identity server 4 using the entity framework project.
I am using a sample config file to populate the database: https://github.com/IdentityServer/IdentityServer4.Demo/blob/master/src/IdentityServer4Demo/Config.cs
This data is entered into the database and I attempt to connect to the token endpoint via Insomnia, here is a screenshot of my setup:
It states invalid_client but I am not sure why, I ran a SQL profile and every time I hit this endpoint its running:
exec sp_executesql N'SELECT [x.Properties].[Id], [x.Properties].[ClientId], [x.Properties].[Key], [x.Properties].[Value]
FROM [ClientProperties] AS [x.Properties]
INNER JOIN (
SELECT TOP(1) [x8].[Id]
FROM [Clients] AS [x8]
WHERE [x8].[ClientId] = #__clientId_0
ORDER BY [x8].[Id]
) AS [t7] ON [x.Properties].[ClientId] = [t7].[Id]
ORDER BY [t7].[Id]',N'#__clientId_0 nvarchar(200)',#__clientId_0=N'client'
It's trying to perform a join on the ClientProperties table, but this table is currently empty. I am not sure if this is the problem or not.
Am I doing something wrong?
When you INNER JOIN two tables, of which one is empty (as you state), the result set will always be empty so when the client can't be retrieved by client_id, you get "invalid_client".
Putting some data, linked to your client, into it should resolve the issue.
I am working on to get the record count of every entity available in the CRM. I have seen so many solutions are available on the internet But I have searched in the database(As we have on-prem) and found one table called 'RecordCountSnapshot' has the count(and answer to my question). I am wondering can we query that table somehow and get the count.
I have tried using OData Query builder, I am able to prepare a query but unable to get the result.
Query:
Result:
We are using CRM 2015 on-prem version.
Go to Settings -> Customizations -> Developer Resources -> Service Endpoints -> Organization Data Service
Open by clicking /XRMServices/2011/OrganizationData.svc/, it is missing the definition for RecordCountSnapshot. That means this entity is not serviceable by OData. Even if you modify the other OData query url to use RecordCountSnapshotSet you will get 'Not found' error. (I tried in CRM REST builder)
1) As you are in Onpremise, You can use this query:
SELECT TOP 1000 [Count]
,[RecordCountSnapshotId]
,entityview.ObjectTypeCode, Name
FROM [YOURCRM_MSCRM].[dbo].[RecordCountSnapshot] , EntityView
where entityview.ObjectTypeCode = RecordCountSnapshot.ObjectTypeCode
and count > 0 order by count desc
2) In Odata Query Designer, you have statistics tab. Use it to get the records count.
One option to get the counts of all entities is to run this SQL query against the MSCRM database:
SELECT SO.Name, SI.rows
FROM sysindexes SI, SysObjects SO
WHERE SI.id = SO.ID AND SO.Type = 'U' AND SI.indid < 2
order by rows DESC
I have also built a command line app that's in beta testing that runs a count of all entities. If you're interested, let's chat.
I'm trying to build an XE in order to find out which of our internal apps (that don't have app names and thus show up as .Net SQLClient Data Provider) are hitting particular servers. Ideally, I'd like to get the name of the Client and Database , but not sure if I can do that in one XE.
I figured for ease of use, I'd use a histogram/asynchronous_bucketizer, and save counts of what's trying to hit and how often. However, I can't seem to get it work on 2012, much less 2008. If I use sqlserver.existing_connection it works, but only gives me the count when it connects. I want to get counts during the day and see how often it occurs from each server, so I tried preconnect_completed. Is this the right event?
Also, and part of the reason I'm using XE, is that those servers can get thousands of calls a minute.
Here's what I've come up with thus far, which works but only gives me current SSMS connections that match - obviously, I'll change that to the .Net SQLClient Data Provider.
CREATE EVENT SESSION UnknownAppHosts
ON SERVER
ADD EVENT sqlserver.existing_connection(
ACTION(sqlserver.client_hostname)
WHERE ([sqlserver].[client_app_name] LIKE 'Microsoft SQL Server Management%')
)
ADD TARGET package0.histogram
( SET slots = 50,
filtering_event_name='sqlserver.existing_connection',
source_type=1,
source='sqlserver.client_hostname'
)
WITH(MAX_DISPATCH_LATENCY =1SECONDS);
GO
Aha! It's login, not preconnect_starting or preconnect_completed.
CREATE EVENT SESSION UnknownAppHosts
ON SERVER
ADD EVENT sqlserver.login(
ACTION(sqlserver.client_hostname)
WHERE ([sqlserver].[client_app_name] LIKE 'Microsoft SQL Server Management%')
)
ADD TARGET package0.histogram
( SET slots = 50,
filtering_event_name='sqlserver.login',
source_type=1,
source='sqlserver.client_hostname'
)
WITH(MAX_DISPATCH_LATENCY =1SECONDS);
GO
Then to query it, some awesome code I made horrid:
-- Parse the session data to determine the databases being used.
SELECT slot.value('./#count', 'int') AS [Count] ,
slot.query('./value').value('.', 'varchar(20)')
FROM
(
SELECT CAST(target_data AS XML) AS target_data
FROM sys.dm_xe_session_targets AS t
INNER JOIN sys.dm_xe_sessions AS s
ON t.event_session_address = s.address
WHERE s.name = 'UnknownAppHosts'
AND t.target_name = 'Histogram') AS tgt(target_data)
CROSS APPLY target_data.nodes('/HistogramTarget/Slot') AS bucket(slot)
ORDER BY slot.value('./#count', 'int') DESC
EDIT: I think it's a problem on the subquery on the LINQ-generated query, it get all the records... But I don't know how could I fix it
I have made a simple ASP.NET MVC 2 application that does SELECT queries on a view, I get really poor performance, and while doing a simple benchmark with jMeter (10 conccurents connection) while disabling the cache (I don't want everything to rely on the non customizable/extreme OutputCache)
I see that the SQL Server get overloaded, consuming a LOT of CPU (up to 100%) and all its reserved memory space (512MB)
Here is the action code that cause the problems (manual transactions because it cause DeadLock with the other program that insert new data on the database) :
public ActionResult Index(int page = 0)
{
IronViperEntities db = new IronViperEntities();
db.Connection.Open();
DbTransaction transaction = db.Connection.BeginTransaction(IsolationLevel.ReadUncommitted);
var messages = (from globalView in db.GlobalViews orderby globalView.MessagePostDate descending select globalView).Skip(page*perPage).Take(perPage);
transaction.Commit();
db.Connection.Close();
ViewData["page"] = page;
ViewData["messages"] = messages;
return View();
}
Here is the query executed on the database :
SELECT TOP (100)
[Extent1].[MessageId] AS [MessageId],
[Extent1].[MessageUuid] AS [MessageUuid],
[Extent1].[MessageData] AS [MessageData],
[Extent1].[MessagePostDate] AS [MessagePostDate],
[Extent1].[ChannelName] AS [ChannelName],
[Extent1].[UserName] AS [UserName],
[Extent1].[UserUuid] AS [UserUuid],
[Extent1].[ChannelUuid] AS [ChannelUuid]
FROM ( SELECT [Extent1].[MessageId] AS [MessageId], [Extent1].[MessageUuid] AS [MessageUuid], [Extent1].[MessageData] AS [MessageData], [Extent1].[MessagePostDate] AS [MessagePostDate], [Extent1].[ChannelName] AS [ChannelName], [Extent1].[UserName] AS [UserName], [Extent1].[UserUuid] AS [UserUuid], [Extent1].[ChannelUuid] AS [ChannelUuid], row_number() OVER (ORDER BY [Extent1].[MessagePostDate] DESC) AS [row_number]
FROM (SELECT
[GlobalView].[MessageId] AS [MessageId],
[GlobalView].[MessageUuid] AS [MessageUuid],
[GlobalView].[MessageData] AS [MessageData],
[GlobalView].[MessagePostDate] AS [MessagePostDate],
[GlobalView].[ChannelName] AS [ChannelName],
[GlobalView].[UserName] AS [UserName],
[GlobalView].[UserUuid] AS [UserUuid],
[GlobalView].[ChannelUuid] AS [ChannelUuid]
FROM [dbo].[GlobalView] AS [GlobalView]) AS [Extent1]
) AS [Extent1]
WHERE [Extent1].[row_number] > 0
ORDER BY [Extent1].[MessagePostDate] DESC
View Code :
SELECT dbo.Messages.Id AS MessageId, dbo.Messages.Uuid AS MessageUuid, dbo.Messages.Data AS MessageData, dbo.Messages.PostDate AS MessagePostDate,
dbo.Channels.Name AS ChannelName, dbo.Users.Name AS UserName, dbo.Users.Uuid AS UserUuid, dbo.Channels.Uuid AS ChannelUuid
FROM dbo.Messages INNER JOIN
dbo.Users ON dbo.Messages.UserId = dbo.Users.Id INNER JOIN
dbo.Channels ON dbo.Messages.ChannelId = dbo.Channels.Id
I don't think the server hardware is a problem, I can run equivalent Rails/Grails application without any performance issue. (Dual Core, 3Gb of RAM)
A select count(*) on GlobalView returns ~270.000 lines, indexes are daily rebuilt and a explain show it uses all the clustered indexes.
I get an HTTP average response time of 8000ms, the SQL Server Management Studio shows an average CPU time for this SQL query of 866ms and an average logical IO of 7,592.03.
Database file size if ~180MB
I am using Windows Server 2008 R2 Enterprise Edition, ASP.NET MVC 2 with IIS 7.5 and SQL Server 2008 R2 Express Edition with Advanced Services. They are the only things running on this server.
What can I do ?
Thank you
I guess you got the query from SQL Server Profiler. Save the result, and pass it into the Database Engine Tuning Advisor. That might help you create additional indexes and statistics.
Just out of curiosity: wouldn't appending a .ToList() to the end of the var messages = ... line help?
I've found the probleme,
I replaced "orderby globalView.MessagePostDate descending" by "orderby globalView.MessageId descending", because there isn't any index on MessagePostDate, and that is muuuuch better !
Thank you