Problems with IIS and Custom Membership Provider + Custom Role Provider - asp.net-mvc

I have developed my own classes for Custom Membership and Role providers.
Everything works locally. Nonetheless, after deploying the solution to IIS for testing, my login action seems to work (at least, the action validates the username+password and the user appears to be authenticated) but whenever I try to access actions that are decorated with annotations like
[Authorize(Roles="Employee, Admin")]
I keep getting redirected to the login page, as if the user didn't have the necessary role (he does, though).
So locally, the application succeeds in validating users and checking the authenticated user's roles before executing actions (thus, I assume that my methods on both classes are correct) but on IIS it looks like the role provider isn't working properly. Anyone happens to know where might I be wrong or how can I get a better view on my problem?
In my Web.Config:
<system.web>
(...)
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
<membership defaultProvider="CustomMembershipProvider">
<providers>
<clear />
<add name="CustomMembershipProvider" type="MyApplication.Infrastructure.CustomMembershipProvider" connectionStringName="DBEntities" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="CustomRoleProvider">
<providers>
<clear />
<add name="CustomRoleProvider" type="MyApplication.Infrastructure.CustomRoleProvider" connectionStringName="DBEntities" applicationName="/" />
</providers>
</roleManager>
(...)
</system.web>
Thanks in advance.
EDIT: Aditional Info.
I just modified one of my actions' anotation to simply [Authorize] and it works. So, I believe that the authentication works and the problem must be related to the Role provider.
I'm using Entity Framework for my Data Model, the con. string is as follows:
I managed to register a user and log in using the that newly created account, which would mean that the DB connection and the Custom Membership Provider(?) are working properly.
A "#foreach (String str in Roles.GetRolesForUser(User.Identity.Name)){#str} prints the roles locally and doesn't print anything when deployed.

Ok, I fixed it. Here's the explanation in case someone needs it in the future:
After narrowing out the causes (as seen in my edits), I figured out that the problem must be related to my CustomRoleProvider.
That class has methods like this one:
public override string[] GetRolesForUser(string Username)
{
List<string> roles = new List<string>();
using (DBEntities _db = new DBEntities())
{
try
{
var dbRoles = from r in _db.UserRole
where r.Users.Username == Username
select r;
foreach (var role in dbRoles)
{
roles.Add(role.Role.Name);
}
}
catch
{
}
}
return roles.ToArray();
}
So I was catching an exception and not doing anything with it. I removed the try-catch block, and got this message:
There is already an open DataReader associated with this Command which must be closed first.
A bit of stackoverflowing and I found this: There is already an open DataReader associated with this Command which must be closed first
Turns out my local connection string had MultipleActiveResultSets=true but the connection string on my publish settings didn't. I modified my publish settings and voilĂ , seems to be working now.
I don't really know the advantages/disadvantages of having that setting, but it is working and I really need to move on. Thank you all for your help anyway.

I have had the similar issue. After adding machineKey to web.config everything works all right.
<system.web>
<machineKey validationKey="2E417D4AC04F20FA6CE1CF1EFE23FBF1695BF6981B605B1B8628D2182C43D0B10E48C4A83FDCE0D1D6300095D9EE1B8746A37E2C3256554405983DCAA7622875" decryptionKey="FA6D35C22BF7E5E9E4438052B924CCC017521137C5EB017D07C7038B80C5F726" validation="SHA1" decryption="AES" />
</system.web>

Related

Using Active Directory Membership Provider for Site Authentication

I have an MVC site that I am in the process of converting from Forms to Federated Authentication. I am able to connect to the ADFS server and verify authentication. However the site currently uses an ActiveDirectoryMembershipProvider to verify the roles of the users as different roles permit different access.
I can not figure out how to populate the MembershipProvider so that I can user things such as this:
User.IsInRole(#"MY-ROLE")
and this:
[Authorize(Roles = "MY-ROLE")]
I have this snippet in my web.config which works for forms authentication but isn't working in my federated site:
<membership defaultProvider="ADMembershipProvider">
<providers>
<clear />
<add name="ADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider" connectionProtection="Secure" attributeMapUsername="sAMAccountName" connectionStringName="ADConn" connectionUsername="LotusLDAPUser" connectionPassword="LotusLDAPUser" />
</providers>
</membership>
I have read a lot of MSDN docs and am still having trouble so please don't just answer with a link to docs. I would appreciated some sample code.
UPDATE:
I added a RoleProvider to my web.config. The role provider was being used in the forms application version successfully, so I believe the values are correct I just missed adding it to the web.config of the federated version. Here is what I have:
<roleManager enabled="true" defaultProvider="ActiveDirectoryRoleProvider" cacheRolesInCookie="true" cookieName=".ADLibraryROLES" cookiePath="/" cookieTimeout="1440" cookieRequireSSL="false" cookieSlidingExpiration="true" createPersistentCookie="true" cookieProtection="All">
<providers>
<clear />
<add name="ActiveDirectoryRoleProvider" connectionStringName="ADConn" connectionUsername="LotusLDAPUser" connectionPassword="LotusLDAPUser" attributeMapUsername="sAMAccountName" type="MyNamespace.ActiveDirectoryRoleProvider" />
</providers>
</roleManager>
It is still returning false for
User.IsInRole(#"MY-ROLE")
and
[Authorize(Roles = "MY-ROLE")]
For a user I know to my in "MY-ROLE"
The problem was that I wasn't setting the Session Token Cookie. In the forms authentication version I had the code:
FormsAuthentication.SetAuthCookie(user.UserName, true);
When testing the Federated version I wasn't setting the authentication cookie, this line is needed:
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(token);
Where token is a SessionSecurityToken created from my Claim.

Umbraco 7 Custom Membership Provider use both Umbraco Users and external Members

how can i use in Umbraco 7 the internal Users and roles who use the BackOffice and my custom users and roles (which comes from an external SQL database.
i want log in umbraco backoffice with the umbraco users as it is and with seperate Login want use external users. i have already changed the web.config
<add name="mynewMembershipProvider" type="mynewMembershipProvider, mynew"
<add name="mynewrovider" type="mynewrsRoleProvider"/>
when i go now to my custom Login i can Login my custom user . but when i try
User.Identity.IsAuthenticated
or
User.IsInRole("xyz")
umbraco is always looking at the umbraco roles.
what did i have done wrong
best regards Michael
If I understand you correctly, you are leaving CMS and back office Users as-is, and you want to allow Member login on the public facing side of your site with a custom provider?
Did you set the default provider to your new membership provider?
<membership defaultProvider="mynewMembershipProvider">
...
</membership>
The default provider in the membership section should always point to the provider being used for public-facing Members - the backoffice interally asks for the UsersMembershipProvider every time it needs to authenticate, so changing the default will not affect it at all.
It is also possible depending on your set up (I haven't tried this) that if you did not include a <clear/> directive then the original Umbraco member provider is causing problems.
Here is a full working <membership> section using a custom BCrypt hashing provider from an Umbraco 7 install of mine:
<membership defaultProvider="BCryptMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add
name="BCryptMembershipProvider"
type="cFront.Web.Security.BCryptMembershipProvider"
connectionStringName="umbracoDbDSN"
requiresUniqueEmail="0"
/>
<add name="UsersMembershipProvider" type="umbraco.providers.UsersMembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" passwordFormat="Hashed" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="BCryptRoleProvider">
<providers>
<clear />
<add name="BCryptRoleProvider" type="cFront.Web.Security.BCryptRoleProvider"
connectionStringName="umbracoDbDSN"
availableRoles="SuperUser,Administrator,Manager,User"
/>
</providers>
</roleManager>

using windows authentication with active directory groups as roles

I've read several questions on this topic,
such as here, here, here and here;
but none have provided a working solution in my case.
What I want to do:
Implement Windows authentication for a web app that is only used by our own employees. This way they should not need to log into the app, but already be authenticated by way of having logged into windows.
Also, I need to restrict certain areas of the app, based on Active Directory Security Groups that the user may be assigned to.
So I want to be able to decorate Controllers / Actions with
[Authorize(Roles="SomeRole")]
What I've tried:
I have
<authentication mode="Windows" />
in my web.config. And I have added several permutations of a <roleManager> as found in some of the posts linked to above. Currently I have this role manager
<roleManager defaultProvider="WindowsProvider"
enabled="true"
cacheRolesInCookie="false">
<providers>
<add
name="WindowsProvider"
type="System.Web.Security.WindowsTokenRoleProvider" />
</providers>
</roleManager>
as found in this post.
As it is, if I decorate a controller with [Authorize], I can access it fine.
However:
I can see in my user settings on the network, that I am part of a AD security group called "IT". But if I decorate the same controller with [Authorize(Roles="IT")] I get the blank screen that is is served by the asp.net development server for a 401 not authorized. This is unexpected. I would think that I should be able to view the page as I am logged in to windows and am part of the group "IT".
Most everything I am finding on this topic make it sound very simple to accomplish what I'm trying to do, but I am clearly missing something here.
For dev I am using IISExpress
with development server properties of the MVC project set up so that
Anonymous Authentication is Disabled and Windows Authentication is Enabled.
The web config is deployed using our TFS build server to test and release servers for which authentication is also setup as above and works in those locations as well.
In my web.config I have.
<system.web>
....
<authentication mode="Windows" />
<authorization>
<deny users="?" />
</authorization>
<roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider">
<providers>
<clear />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
....
</system.web>
I can use
[Authorize(Roles = #"DOMAIN\ADGroup")]
Public ActionResult Index()
{...}
or
public ActionResult Index()
{
var User = System.Web.HttpContext.Current.User;
if (User.IsInRole("DOMAIN\\ADGroup"))
{
return RedirectToAction("IRSAdmin");
}
return View();
}
After i remember to logoff and log back in so the permission i was given to the AD group were applied.

ASP.Net SQLExpress: Cannot open user default database. Login failed

I have 2 SQL express databases: one for my application data and another for the MembershipProvider data. When I attempt to use the CreateUserWizard control, I get the following error:
Error: Login failed for user 'SFP\Susan'.
I can connect to thesee the DB in the server explorer and all its tables and data. What is the problem?
Thanks in advance
It sounds like the MembershipProvider connection is not correctly set up in your web.config file. It should look something like this (with "MyAwesomeDatabaseConnectionName" being the name of the configured connection string, in the connectionStrings section of the file):
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="MyAwesomeDatabaseConnectionName"
applicationName="MyAwesomeApp"/>
</providers>
</membership>
Also, it looks like you are configured for Windows authentication, but if your membership data is in a database, you'll want to configure for Forms authentication:
<authentication mode="Forms">
<forms loginUrl="~/myloginpage.aspx"
defaultUrl="~/myhomepage.aspx" />
</authentication>

My CustomRoleProvider doesn't seem to be used for controlling access to the application

I've set up my application to use a custom role provider by adding some lines to the Web.config file, like so:
<roleManager enabled="true" defaultProvider="AspNetSqlRoleProvider">
<providers>
<!-- <clear/>-->
<add name="CustomRoleProvider"
connectionStringName="Custom"
applicationName="Custom"
type="Authorization.CustomRoleProvider" />
</providers>
</roleManager>
I've created an empty Authorization.CustomRoleProvider class and added references to it.
Now my code has one simple test case in it, like so:
[Authorize (Roles= "Admin")]
public ActionResult Index(Model model)
As far as I can tell, none of the code I've written so far is being called (if it would, it would raise an exception on account of methods not being implemented). Am I messing something up in my configuration?
You should change your default provider name to match your provider name of "CustomRoleProvider":
<roleManager enabled="true" defaultProvider="CustomRoleProvider">

Resources