14

First of all, I already checked here: ASP.Net Identity how to set target DB?

I'm now getting this error

CREATE DATABASE permission denied in database 'master'.

On this line of code:

Dim user As User = manager.Find(Trim(Username.Text), Trim(Password.Text))

Full error:

[SqlException (0x80131904): CREATE DATABASE permission denied in database 'master'.]
System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) +3249852
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) +345
System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) +4927
System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite) +1287
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource
1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite) +367
System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +386
System.Data.Entity.Infrastructure.Interception.InternalDispatcher1.Dispatch(TTarget target, Func3 operation, TInterceptionContext interceptionContext, Action3 executing, Action3 executed) +965
System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand command, DbCommandInterceptionContext interceptionContext) +505
System.Data.Entity.SqlServer.<>c__DisplayClass1a.b__19(DbConnection conn) +136
System.Data.Entity.SqlServer.SqlProviderServices.UsingConnection(DbConnection sqlConnection, Action1 act) +347
System.Data.Entity.SqlServer.SqlProviderServices.UsingMasterConnection(DbConnection sqlConnection, Action
1 act) +916
System.Data.Entity.SqlServer.SqlProviderServices.CreateDatabaseFromScript(Nullable1 commandTimeout, DbConnection sqlConnection, String createDatabaseScript) +117
System.Data.Entity.SqlServer.SqlProviderServices.DbCreateDatabase(DbConnection connection, Nullable
1 commandTimeout, StoreItemCollection storeItemCollection) +212
System.Data.Entity.Migrations.Utilities.DatabaseCreator.Create(DbConnection connection) +172
System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase) +175
System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration) +116
System.Data.Entity.Internal.DatabaseCreator.CreateDatabase(InternalContext internalContext, Func3 createMigrator, ObjectContext objectContext) +121
System.Data.Entity.Database.Create(DatabaseExistenceState existenceState) +169
System.Data.Entity.CreateDatabaseIfNotExists
1.InitializeDatabase(TContext context) +257
System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action) +72
System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization() +483
System.Data.Entity.Internal.RetryAction1.PerformAction(TInput input) +177
System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action
1 action) +274
System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) +37
System.Data.Entity.Internal.Linq.InternalSet1.Initialize() +76
System.Data.Entity.Internal.Linq.InternalSet
1.get_InternalContext() +21
System.Data.Entity.Infrastructure.DbQuery1.System.Linq.IQueryable.get_Provider() +59
System.Data.Entity.QueryableExtensions.FirstOrDefaultAsync(IQueryable
1 source, Expression1 predicate, CancellationToken cancellationToken) +208
System.Data.Entity.QueryableExtensions.FirstOrDefaultAsync(IQueryable
1 source, Expression`1 predicate) +172

Microsoft.AspNet.Identity.EntityFramework.d__6c.MoveNext() +502
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +13855856
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +61
Microsoft.AspNet.Identity.CultureAwaiter1.GetResult() +48
Microsoft.AspNet.Identity.<FindAsync>d__12.MoveNext() +357
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +13855856
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +61
Microsoft.AspNet.Identity.AsyncHelper.RunSync(Func
1 func) +348
MyApp.Login_identity.UserLogin_Click(Object sender, EventArgs e) in C:\MyApp\Login_identity.aspx.vb:168
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +11747645
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +150
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3360

I changed the DbContext initialization in AppModel.vb to my existing connection string conn1, which points to the SQL Server database I already converted to the new identity tables.

My connection string:

<add name="conn1" 
     connectionString="data source=(local)\sqlexpress;Initial Catalog=myapp;User Id=sa;Password=XXXX;" 
     providerName="System.Data.SqlClient" />

AppModel.vb:

Imports Microsoft.AspNet.Identity
Imports Microsoft.AspNet.Identity.EntityFramework
Imports System.Collections.Generic
Imports System.ComponentModel.DataAnnotations
Imports System.Data.Entity
Imports System.Linq
Imports System.Web

Namespace AspnetIdentitySample.Models
    Public Class ApplicationUser
        Inherits IdentityUser
        ' HomeTown will be stored in the same table as Users
        Public Property HomeTown() As String
            Get
                Return m_HomeTown
            End Get
            Set(value As String)
                m_HomeTown = Value
            End Set
        End Property
        Private m_HomeTown As String
        Public Overridable Property ToDoes() As ICollection(Of ToDo)
            Get
                Return m_ToDoes
            End Get
            Set(value As ICollection(Of ToDo))
                m_ToDoes = Value
            End Set
        End Property
        Private m_ToDoes As ICollection(Of ToDo) 

        ' FirstName & LastName will be stored in a different table called MyUserInfo
        Public Overridable Property MyUserInfo() As MyUserInfo
            Get
                Return m_MyUserInfo
            End Get
            Set(value As MyUserInfo)
                m_MyUserInfo = Value
            End Set
        End Property
        Private m_MyUserInfo As MyUserInfo 
    End Class

    Public Class MyUserInfo
        Public Property Id() As Integer
            Get
                Return m_Id
            End Get
            Set(value As Integer)
                m_Id = Value
            End Set
        End Property
        Private m_Id As Integer
        Public Property FirstName() As String
            Get
                Return m_FirstName
            End Get
            Set(value As String)
                m_FirstName = Value
            End Set
        End Property
        Private m_FirstName As String
        Public Property LastName() As String
            Get
                Return m_LastName
            End Get
            Set(value As String)
                m_LastName = Value
            End Set
        End Property
        Private m_LastName As String
    End Class

    Public Class ToDo
        Public Property Id() As Integer
            Get
                Return m_Id
            End Get
            Set(value As Integer)
                m_Id = Value
            End Set
        End Property
        Private m_Id As Integer
        Public Property Description() As String
            Get
                Return m_Description
            End Get
            Set(value As String)
                m_Description = Value
            End Set
        End Property
        Private m_Description As String
        Public Property IsDone() As Boolean
            Get
                Return m_IsDone
            End Get
            Set(value As Boolean)
                m_IsDone = Value
            End Set
        End Property
        Private m_IsDone As Boolean
        Public Overridable Property User() As ApplicationUser
            Get
                Return m_User
            End Get
            Set(value As ApplicationUser)
                m_User = Value
            End Set
        End Property
        Private m_User As ApplicationUser 
    End Class
    Public Class MyDbContext
        Inherits IdentityDbContext(Of ApplicationUser)
        Public Sub New()
            MyBase.New("conn1") 'DefaultConnection
        End Sub

        Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
            MyBase.OnModelCreating(modelBuilder)

            ' Change the name of the table to be Users instead of AspNetUsers
            modelBuilder.Entity(Of IdentityUser)().ToTable("Users")
            modelBuilder.Entity(Of ApplicationUser)().ToTable("Users")
        End Sub

        Public Property ToDoes() As DbSet(Of ToDo)
            Get
                Return m_ToDoes
            End Get
            Set(value As DbSet(Of ToDo))
                m_ToDoes = Value
            End Set
        End Property
        Private m_ToDoes As DbSet(Of ToDo)

        Public Property MyUserInfo() As DbSet(Of MyUserInfo)
            Get
                Return m_MyUserInfo
            End Get
            Set(value As DbSet(Of MyUserInfo))
                m_MyUserInfo = Value
            End Set
        End Property
        Private m_MyUserInfo As DbSet(Of MyUserInfo)
    End Class


End Namespace

UPDATE

Based on a comment I also checked here.

I don't really get why this is a role issue, since I'm reusing a connection string that is already working fine with updating other (non-identity related) tables. Also I don't get why the error refers to the master table as I'd expect that I'm not trying to connect to that in any way by the manager.Find method.

Anyway, the user through which I'm currently testing is already assigned to the sysadmin role:

enter image description here

UPDATE 2

Ok, thanks to Jeremy's comment below I'm a step closer...I needed to add user IIS APPPOOL\.NET v4.5 to role sysadmin, because that was the user connecting as shown in SQL Server profiler (although I'm unsure about the security risks when adding this user to this role). Anyway, the Find method no longer throws an error and using SQL Server profiler I see the SQL statement is fired when I execute this code Dim user As User = manager.FindByName(Trim(Username.Text))

exec sp_executesql N'SELECT TOP (1) 
[Extent1].[Id] AS [Id], 
[Extent1].[ApplicationId] AS [ApplicationId], 
[Extent1].[MobileAlias] AS [MobileAlias], 
[Extent1].[IsAnonymous] AS [IsAnonymous], 
[Extent1].[LastActivityDate] AS [LastActivityDate], 
[Extent1].[MobilePIN] AS [MobilePIN], 
[Extent1].[LoweredEmail] AS [LoweredEmail], 
[Extent1].[LoweredUserName] AS [LoweredUserName], 
[Extent1].[PasswordQuestion] AS [PasswordQuestion], 
[Extent1].[PasswordAnswer] AS [PasswordAnswer], 
[Extent1].[IsApproved] AS [IsApproved], 
[Extent1].[IsLockedOut] AS [IsLockedOut], 
[Extent1].[CreateDate] AS [CreateDate], 
[Extent1].[LastLoginDate] AS [LastLoginDate], 
[Extent1].[LastPasswordChangedDate] AS [LastPasswordChangedDate], 
[Extent1].[LastLockoutDate] AS [LastLockoutDate], 
[Extent1].[FailedPasswordAttemptCount] AS [FailedPasswordAttemptCount], 
[Extent1].[FailedPasswordAttemptWindowStart] AS [FailedPasswordAttemptWindowStart], 
[Extent1].[FailedPasswordAnswerAttemptCount] AS [FailedPasswordAnswerAttemptCount], 
[Extent1].[FailedPasswordAnswerAttemptWindowStart] AS [FailedPasswordAnswerAttemptWindowStart], 
[Extent1].[Comment] AS [Comment], 
[Extent1].[Email] AS [Email], 
[Extent1].[EmailConfirmed] AS [EmailConfirmed], 
[Extent1].[PasswordHash] AS [PasswordHash], 
[Extent1].[SecurityStamp] AS [SecurityStamp], 
[Extent1].[PhoneNumber] AS [PhoneNumber], 
[Extent1].[PhoneNumberConfirmed] AS [PhoneNumberConfirmed], 
[Extent1].[TwoFactorEnabled] AS [TwoFactorEnabled], 
[Extent1].[LockoutEndDateUtc] AS [LockoutEndDateUtc], 
[Extent1].[LockoutEnabled] AS [LockoutEnabled], 
[Extent1].[AccessFailedCount] AS [AccessFailedCount], 
[Extent1].[UserName] AS [UserName]
FROM [dbo].[AspNetUsers] AS [Extent1]
WHERE ((UPPER([Extent1].[UserName])) = (UPPER(@p__linq__0))) OR ((UPPER([Extent1].[UserName]) IS NULL) AND (UPPER(@p__linq__0) IS NULL))',N'@p__linq__0 nvarchar(4000)',@p__linq__0=N'flo@outlook.com'

The strange thing is: when I execute it directly in SQL Server Management Studio I get a record returned, but in my code the variable user is Nothing....What can it be?

Community
  • 1
  • 1
Adam
  • 6,041
  • 36
  • 120
  • 208
  • http://blog.techdreams.org/2007/11/create-database-permission-denied-sql.html https://menononnet.wordpress.com/2011/03/07/create-database-permission-denied-in-database-master-microsoft-sql-server-error-262/ – Pரதீப் Aug 07 '15 at 02:54
  • Stacktrace indicates that ASP.Net Identity / Entity Framework tries to create a database. Is this what you would expect? In other words - does the database "myapp" already exist on your sql server? – larsts Aug 31 '15 at 12:08
  • It is indeed NOT what I would expect. The database myapp already exists. It is as if the custom database connection string I pass here is ignored: `Public Sub New() MyBase.New("conn1") 'DefaultConnection End Sub` – Adam Aug 31 '15 at 12:57
  • The error refers to the master database, not the master table. – StingyJack Aug 31 '15 at 21:18
  • @StingyJack: what is it doing with the master database? And how can I solve this? – Adam Sep 01 '15 at 00:03
  • The reason the master database contains server wide information, including all databases in the system. https://msdn.microsoft.com/en-us/library/ms187837.aspx This is why it is "involved" when creating a database. – larsts Sep 01 '15 at 08:46
  • This definately seems to be a permissions issue. Entity Framework does not "see" the myapp database when connecting to the server. I would create a new login on the server, give it sysadmin, and use this in your connection string. – larsts Sep 01 '15 at 08:49
  • Incidentally, you might want to do a search for "SQL Server security best practices". – Andrew Morton Sep 02 '15 at 08:45
  • It is trying to create a new DB because you have Context set up in such a way that it recreates the Database rather than update it via migrations. But like others said, it is a permission issue indeed – Zoran P. Sep 06 '15 at 07:58
  • @ZoranP. `you have Context set up in such a way that it recreates the Database rather than update it via migrations`....I'm not sure what else I could do here? And is this necessarily a bad thing? – Adam Sep 06 '15 at 12:33
  • @Flo it all depends on the project, but I mostly use migrations and do not recreate DB as it's bad practice when you are further in development, because you lose all data that you've input for testing. – Zoran P. Sep 07 '15 at 07:31

5 Answers5

4

Try this, if your application pool is running under a NETWORK SERVICE identity. Then give SysAdmin Role for “NT AUTHORITY\NETWORK SERVICE”:

enter image description here

Or give SysAdmin to which ever account running the app pool.

If that doesn't work, check if any of these solutions help: CREATE DATABASE permission denied in database 'master' (EF code-first)

Edit:

Its not very secure to give all these accounts sysAdmin. After you get this working tighten up the SQL security to just dbReader and dbWriter roles.

And what is going wrong with the FindByName method?

Now there is no exception and the problem is that no data is returned I think there is still something going on with permissions.

Since you're using SQL Authentication in the Connection String, can you try it with Windows Integrated? Otherwise try using the appPool IIS accounts credentials in your connection string and see if that yields a clue as to whats wrong?

Community
  • 1
  • 1
Jeremy Thompson
  • 61,933
  • 36
  • 195
  • 321
  • I added sysadmin role to “NT AUTHORITY\NETWORK SERVICE”. But it did not help...where do I see which account is running the application pool? The post you refer to did not solve it for me btw :( – Adam Sep 04 '15 at 14:45
  • 1
    ITs TIME!! To pull our SQL Server Profiler! And do a trace, what's going on in there? who is executing - you know, is it getting impersonated? Lets find out!!! – Jeremy Thompson Sep 04 '15 at 14:47
  • Thanks! I'm a step closer, I've updated my post (see update 2). If you could have a look? Is it secure to add this role? And what is going wrong with the FindByName method? – Adam Sep 04 '15 at 22:24
  • Where is your update? I don't see any new comment or updated answer? – Adam Sep 05 '15 at 23:23
  • Ok, I'll test this asap. I'll reward you the bounty now anyway as otherwise it'll expire and your answer comes closest to solving this :) Hopefully you'll be able to help me fully resolve this. Thanks! – Adam Sep 06 '15 at 14:18
1

You connection string contains "User Id=sa;Password=XXXX", thus that connection is attempting to use SQL Server authentication. Your SSMS login property's title bar appears to be identifying a Windows account, which implies there is a belief that Windows Authentication should be used. And yet the connection is attempting to use SQL Server authentication (not Windows authentication). If not already configured, SQL Server's authentication mode can be changed to support both SQL Authentication and Windows Authentication ("Mixed Mode" authentication) see https://msdn.microsoft.com/en-us/library/ms188670.aspx.

Alternatively, the connection string can be changed to use Windows authentication/integrated security, per https://msdn.microsoft.com/en-us/library/jj653752(v=vs.110).aspx#integratedsecurity

Bill
  • 198
  • 1
  • 5
  • Nope, that's not it...I already have both Windows and SQL Server authentication enabled for this server. User sa has all permissions already. What else can it be? – Adam Aug 15 '15 at 20:51
  • Replace the CREATE DATABASE statement with SELECT USER. If 'dbo' is returned, your login is a member of the sysadmin role. If some name other than 'dbo' is returned (including 'sa'), your account is not a member of the sysadmin role. If 'sa' is returned, it's likely the sa account was renamed and a new account named 'sa' was created (and the new 'sa' account is not a member of the syadmin role). It should also be possible for a sysadmin to deny themselves or another sysadmin account permissions (b/c access denied trumps all), but a sysadmin (aka the DBO user) can remove that deny. – Bill Aug 20 '15 at 02:56
  • Ok sorry for the delay but I've been trying to figure this out....where can I replace that statement? It's wrapped somewhere in compiled code I guess behind the `manager.Find` method. Please advice.... – Adam Aug 27 '15 at 19:39
  • I don't think you can replace that statement in your setup. But you could do a manual connection in SSMS with the information in the connection string to check whether your sa account is ok. I.e. connect in management stuido with sql authentication using your sa account. – larsts Sep 01 '15 at 08:53
0

Why instead to utilize an identity field don´t you utilize a HASH value in a NVARCHAR() field?

For instance: you may get an individual data from user (or a join of his fields), calculate a HASH from .NET Cryptography library and set that NVARCHAR() with the data.

This way (and supposing you´re utilizing SHA-512 HASH) you will be able to have a Base64 string of an individual data, like an Identity itself.

But, if your goal is have an identity to the momentum, you may get the user data, plus the current datetime, calculate its HASH and save this data as the record´s identity.

David BS
  • 1,822
  • 1
  • 19
  • 35
  • I really want to make use of the methods provided by the Identity framework instead of workarounds. I'm not sure what you mean by `have an identity to the momentum` though...what does that mean? – Adam Sep 04 '15 at 13:34
  • In my SQL database I have some records that MUST reflect a kind of identity based on date and time in a rigid format: yyyymmddhhmmmss (like 20150904121752). Some searches are made using that kind of string. What I do? I convert it to HASH and find the HASH code inside SQL - a kind of timestamp. Remember also that Identity can change in a database clean/compression routines. – David BS Sep 04 '15 at 13:45
  • `Remember also that Identity can change in a database clean/compression routines`? You mean in general with the ASP.NET Identity framework? If so: what are the implications of this? – Adam Sep 04 '15 at 13:50
  • The implication is that you may have a kind or reordering in some specific situations, like when you utilize the reindexing/shrink database. I don´t remember exactly those situations are, but I had a HUGE problem in past using it. You may try or the solution above OR create a NVARCHAR field and set the IDENTITY there as an option (all NVARCHAR fields can be set as Identity). But even this last, I guess I had problems in past - because of it I utilize HASHES. – David BS Sep 04 '15 at 14:03
  • I´m not sure if we´re talking about the same thing, but this report may help you: http://sqlmag.com/t-sql/should-i-use-identity-or-not . Sorry if I´m not helping you exactly in what you need. – David BS Sep 04 '15 at 14:05
  • Ah, we're not talking about the same thing, I'm talking about ASP.NET Identity, the new version of the aspnet membership tables. Thanks anyway. – Adam Sep 04 '15 at 14:22
  • Wow, sorry to let you waste your time. Best regards. – David BS Sep 04 '15 at 14:29
0

You should probably use a different SQL account than "sa" but the default database for sa is master. The Find method is likely using the default database for the user even though myapp is defined in the connection string.

Change the default database for sa to myapp, here:

enter image description here

smoore4
  • 4,520
  • 3
  • 36
  • 55
  • Hi, thank you, but the default database for user sa was already set to myapp....still the same error occurs. – Adam Sep 04 '15 at 13:33
-1

Your user should be added to the dbcreator role.

Otherwise you're not allowed to create new databases.

Sysadmin/public are not enough.

Ismail Hassani
  • 442
  • 5
  • 14
  • 2
    Sysadmin does not have permission to create databases? – StingyJack Aug 31 '15 at 20:37
  • No it doesn't. I've had this issue every time I forgot to add it. :D – Ismail Hassani Aug 31 '15 at 20:45
  • @IsmailHassani Thanks, but when I try to add the role 'dbcreator' to my user 'sa' I get the error `Cannot use the special principal 'sa'`, I found his post that mentions it's already a member of the sysadmin group, which trumps all other groups: http://stackoverflow.com/questions/14188629/cannot-use-the-special-principal-sa so what can I do? (I tried adding roles to this user both when logging as user 'sa' as well as via Windows Authentication) – Adam Aug 31 '15 at 20:56
  • actually, that should suggest that you can create a new database from the Management Studio. Have you tried this? – Ismail Hassani Aug 31 '15 at 21:04
  • I assume also that your sa account is granted access and enabled? – Ismail Hassani Aug 31 '15 at 21:05
  • 2
    Sysadmin is the highest role of access and can perform any activity on the server. https://msdn.microsoft.com/en-us/library/ms188659(v=sql.105).aspx. The out of the box 'sa' user already has dbcreator implicitly, so something else is wrong with your setup. Are there any messages in the SQL or windows event logs? – StingyJack Aug 31 '15 at 21:13
  • my bad idd, I forgot he's using the sa account. – Ismail Hassani Aug 31 '15 at 21:17
  • Sysadmin role is indeed enough to create new databases, this answer is just wrong. – larsts Sep 01 '15 at 08:50