Windows Authentication and SQLRoleProvider MVC3 - asp.net-mvc-3

I have an internet application that connect users with Windows authentication, when the users come to the office and logon onto Windows session (with AD informations) they're automatically logged onto the web application, i used Windows authenticationto achieve this.
So when i use #User.Identity.Nameit show the username. Now if i want to do something with the username like Roles.AddUserToRole(username, "RoleName");it throws an exception The user 'Domain\user' was not found.
My view :
#using (Html.BeginForm("AddToRH", "Account", FormMethod.Post))
{
<div class="form_settings">
<p>
<span>
#User.Identity.Name
#Html.Label("Username") :
</span>
#Html.Editor("username")
</p>
<p style="padding-top: 15px">
<span> </span>
<input type="submit" value="Enregister" class="submit" />
</p>
</div>
}
My controller :
public ActionResult AddToRH(string username) {
string[] roles = Roles.GetAllRoles();
Boolean contains = false;
foreach (string role in roles)
{
if(role.Equals("RoleName")){
contains=true;
}
}
if (!contains) {
Roles.CreateRole("RoleName");
}
Roles.AddUserToRole(username, "RoleName");
return RedirectToAction("Index","Home");
}
My web.config :
<authentication mode="Windows">
</authentication>
<membership defaultProvider="DefaultMembershipProvider">
<providers>
<add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/"/>
</providers>
</membership>

The mistake was in the provider of membership.
The type:
System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/"`
is generated by default with the project and don't use the dbo.aspnet_X table. This is why in my opinion i can't retrieve the user.
This is an article that helped me a lot:
http://weblogs.asp.net/scottgu/pages/Recipe_3A00_-Implementing-Role_2D00_Based-Security-with-ASP.NET-2.0-using-Windows-Authentication-and-SQL-Server.aspx
Change also the other provider : For Roles i used SQLRoleProvider so the type is : System.Web.Security.SqlRoleProviderand for the Profile i used : type="System.Web.Security.SqlProfileProvider"

Related

how do i access the elmah log when used in web api

I installed elmah as described here https://github.com/rdingwall/elmah-contrib-webapi
Now I am trying to access the logging but I keep getter error 404 errors.
Am I using the correct url ? Is there still some configuration missing ?
My webapi runs as follows :
http://localhost/MagnusREST/api/Customers/054036?frmt=xml
My application_start looks like this :
protected void Application_Start()
{
GlobalConfiguration.Configuration.Filters.Add(new ElmahHandleErrorApiAttribute()); //added for elmah
AreaRegistration.RegisterAllAreas();
UnityConfig.RegisterComponents();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
my webapi config remained unchanged and looks like this :
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Formatters.JsonFormatter.MediaTypeMappings.Add(
new QueryStringMapping("frmt", "json",
new MediaTypeHeaderValue("application/json")));
config.Formatters.XmlFormatter.MediaTypeMappings.Add(
new QueryStringMapping("frmt", "xml",
new MediaTypeHeaderValue("application/xml")));
//config.Formatters.Clear();
JsonMediaTypeFormatter oldformatter = config.Formatters.Where(f => f is JsonMediaTypeFormatter).FirstOrDefault() as JsonMediaTypeFormatter;
if (oldformatter != null) config.Formatters.Remove(oldformatter);
config.Formatters.Insert(0,new PartialJsonMediaTypeFormatter() { IgnoreCase = true });
}
}
Accessing logs via http://localhost/MagnusREST/api/elmah.axd does not work, via http://localhost/MagnusREST/elmah.axd does not work and http://localhost/elmah.axd does not work either.
What am I doing wrong?
This is running in visual studio 2013.
There was a missing piece in the web.config
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="elmah" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</handlers>
The elma handler needs to be added. After doing that I could access the elmah log using followin url :
http://localhost/MagnusREST/elmah.axd
You have to read the documentation and questions both for elmah and the webapi contrib it seems. Ok the first problem is passed, what will be the next ;-)
To get is fully working more is needed than the above
Add configsections
<configSections>
<sectionGroup name="elmah">
<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah"/>
<section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
<section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
<section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah"/>
</sectionGroup>
</configSections>
Add the elmah configuration you like for instance to send mails :
<elmah>
<security allowRemoteAccess="0" />
<errorMail from="xxxx" to="xxx" subject="some error" async="true"
smtpPort="25" smtpServer="xxx" userName="xxx" password="xxx"/>
</elmah>
The system.web and system.webserver need to be something like this :
<system.web>
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5.1" />
<httpHandlers>
<add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah"/>
</httpModules>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules>
<add name="Elmah.ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" />
<add name="Elmah.ErrorMail" type="Elmah.ErrorMailModule" preCondition="managedHandler" />
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="elmah" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</handlers>
</system.webServer>
Take a good look where elmah is being mentioned and add those things to your own configuration file that might look slightly different.
I also had to add this to my web.config and they it worked
<location path="elmah.axd" inheritInChildApplications="false">
<system.web>
<httpHandlers>
<add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>
<!--
See http://code.google.com/p/elmah/wiki/SecuringErrorLogPages for
more information on using ASP.NET authorization securing ELMAH.
<authorization>
<allow roles="admin" />
<deny users="*" />
</authorization>
-->
</system.web>
<system.webServer>
<handlers>
<add name="ELMAH" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" preCondition="integratedMode" />
</handlers>
</system.webServer>

web api windows authentication unauthorized on foxxl

I hope somebody can help me with the following issue, I have been working on a mvc4 web api running on .net 4.0 and ef code first. I am trying to use basic authentication in combination with the authorize attribute. It works on my Azure trial and also on Localhost but i cant get it to work on foxxl hosting and it keeps asking me for credentials which seem to be invalid when i try it on the foxxl hosting. For testing i am not using https so but this will be included in release version.
Here is some sample code that i have added for basic authentication:
Web config
<system.web>
<customErrors mode="Off" />
<compilation debug="true" targetFramework="4.0" />
<authentication mode="Windows" />
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Optimization" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages" />
</namespaces>
</pages>
<profile defaultProvider="DefaultProfileProvider">
<providers>
<add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</profile>
<membership defaultProvider="DefaultMembershipProvider">
<providers>
<add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
<roleManager defaultProvider="DefaultRoleProvider">
<providers>
<add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</roleManager>
<sessionState mode="InProc" customProvider="DefaultSessionProvider">
<providers>
<add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
</providers>
</sessionState>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<add name="BasicAuthHttpModule" type="KlantenBestand.BasicAuthHttpModule, KlantenBestand"/>
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
TestController
[Authorize]
public HttpResponseMessage Get()
{
String name = HttpContext.Current.User.Identity.Name;
return Request.CreateResponse(HttpStatusCode.OK, name);
}
BasicAuthHttpModule
public class BasicAuthHttpModule : IHttpModule
{
private const string Realm = "KlantenBestand";
private static KlantenBestandContext db = new KlantenBestandContext();
public void Init(HttpApplication context)
{
// Register event handlers
context.AuthenticateRequest += OnApplicationAuthenticateRequest;
context.EndRequest += OnApplicationEndRequest;
}
private static void SetPrincipal(IPrincipal principal)
{
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
private static bool CheckPassword(string username, string password)
{
var company = db.Companies.FirstOrDefault(u => u.EmailAdress.Equals(username));
return company != null && company.Password.Equals(Md5Hash(password));
}
private static bool AuthenticateUser(string credentials)
{
bool validated = false;
try
{
var encoding = Encoding.GetEncoding("iso-8859-1");
credentials = encoding.GetString(Convert.FromBase64String(credentials));
int separator = credentials.IndexOf(':');
string name = credentials.Substring(0, separator);
string password = credentials.Substring(separator + 1);
validated = CheckPassword(name, password);
if (validated)
{
var identity = new GenericIdentity(name);
SetPrincipal(new GenericPrincipal(identity, null));
}
}
catch (FormatException)
{
// Credentials were not formatted correctly.
validated = false;
}
return validated;
}
private static void OnApplicationAuthenticateRequest(object sender, EventArgs e)
{
var request = HttpContext.Current.Request;
var authHeader = request.Headers["Authorization"];
if (authHeader != null)
{
var authHeaderVal = AuthenticationHeaderValue.Parse(authHeader);
// RFC 2617 sec 1.2, "scheme" name is case-insensitive
if (authHeaderVal.Scheme.Equals("basic",
StringComparison.OrdinalIgnoreCase) &&
authHeaderVal.Parameter != null)
{
AuthenticateUser(authHeaderVal.Parameter);
}
}
}
// If the request was unauthorized, add the WWW-Authenticate header
// to the response.
private static void OnApplicationEndRequest(object sender, EventArgs e)
{
var response = HttpContext.Current.Response;
if (response.StatusCode == 401)
{
response.Headers.Add("WWW-Authenticate",
string.Format("Basic realm=\"{0}\"", Realm));
}
}
public void Dispose()
{
}
public static string Md5Hash(string password)
{
MD5 md5 = new MD5CryptoServiceProvider();
//compute hash from the bytes of text
md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(password));
//get hash result after compute it
byte[] result = md5.Hash;
StringBuilder strBuilder = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
//change it into 2 hexadecimal digits
//for each byte
strBuilder.Append(result[i].ToString("x2"));
}
return strBuilder.ToString();
}
}
EDIT
I also tryed adding the authentication lines to my web.config because my hosting said this would solve the issue. But when i do that and run it localhost it gives me the following error: This configuration section cannot be used at this path. This happens when the section is locked at a parent level. Locking is either by default (overrideModeDefault="Deny"), or set explicitly by a location tag with overrideMode="Deny" or the legacy allowOverride="false".
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<basicAuthentication enabled="true" />
<windowsAuthentication enabled="false" />
</authentication>
</security>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<add name="BasicAuthHttpModule" type="KlantenBestand.BasicAuthHttpModule, KlantenBestand"/>
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Look at your web.config.
<authentication mode="Windows" />
It is set to Windows Authentication. You will need to remove that line.

Razor view Type does not inherit from 'System.Web.WebPages.WebPage'

I have a problem with configuring asp.net mvc application:
[HttpException (0x80004005): Type 'ASP._Page_Currency_Index_cshtml' does not inherit from 'System.Web.WebPages.WebPage'.]
System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(VirtualPath virtualPath, Type requiredBaseType, HttpContext context, Boolean allowCrossApp) +11454171
System.Web.WebPages.BuildManagerWrapper.CreateInstanceOfType(String virtualPath) +347
System.Web.WebPages.VirtualPathFactoryManager.CreateInstanceOfType(String virtualPath) +239
System.Web.WebPages.WebPageHttpHandler.CreateFromVirtualPath(String virtualPath, IVirtualPathFactory virtualPathFactory) +57
System.Web.WebPages.WebPageRoute.DoPostResolveRequestCache(HttpContextBase context) +407
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +270
Steps that I want to do:
Move controllers with its views into separate library and put dll into bin folder.
Create virtual file provider and virtual file to get data from assembly:
public override Stream Open()
{
var resourceName = this.path;
var asmName = this.assembly.GetName().Name;
var manifestName = asmName + ".Views" + resourceName.Trim('~').Replace("/", ".");
var resourceStream = this.assembly.GetManifestResourceStream(manifestName);
return resourceStream;
}
Add this lines into web.config:
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages" />
</namespaces>
</pages>
</system.web.webPages.razor>
When user access this controller's page it is compiled correctly into the following class:
public class _Page_Currency_Index_cshtml : System.Web.Mvc.WebViewPage<GridModel<CurrencyModel>> {
And after that it fails with this error (and as I can see - he is right, Type 'ASP._Page_Currency_Index_cshtml' does not inherit from 'System.Web.WebPages.WebPage'.)
What should I do to let HttpApplication know that this page should be managed as System.Web.Mvc.WebViewPage instead of System.Web.WebPages.WebPage?
I have tried to move Views/Web.Config into bin folder, but it does not help.
Try adding this to the AppSettings in Web.Config:
<add key="webpages:Enabled" value="false" />

Clients need to delete cookies most of the times in MVC

I am having my mvc project that is working fine on my local machine. However, once posted on the server, the users can`t access the login the secong time they are trying to access the website. They have to delete the cookies. Why is that so? How can I correct that?
Global.asax.cs
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(Request.cookies[FormsAuthentication.FormsCookieName].Value);
args.user = new MyProject.Web.UI.Classes.UserPrincipal(GetUserFromCache(ticket.Name))
SourceFile: c:\Myproject\Code\MvcUI\Global.asax.cs
public void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs args)
{
if (FormsAuthentication.CookiesSupported)
{
if (null != Request.Cookies[FormsAuthentication.FormsCookieName])
{
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value);
args.User = new MyProject.Web.UI.Classes.UserPrincipal(GetUserFromCache(ticket.Name));
}
}
else
throw new HttpException("Cookieless Forms Authentication is not supported for this application.");
}
public void WindowsAuthentication_OnAuthenticate(object sender, WindowsAuthenticationEventArgs args)
{
string username = args.Identity.Name.Substring(args.Identity.Name.IndexOf("\\") + 1);
Myproject.API.User user = GetUserFromCache(username);
if (null == user)
throw new HttpException("User could not be found.");
args.User = new MyProject.Web.UI.Classes.UserPrincipal(user);
}
AccountController
[HttpPost]
public bool LogOn(string userName, string password, string returnUrl, bool rememberMe = false)
{
MyProject.API.User user = MyProject.API.User.Load(userName);
string errorMessage = "Your user name and/or password is incorrect.";
if (null != user && user.IsValidPassword(password))
{
user.LastLoginDate = DateTime.Now;
user.Save();
FormsAuthentication.SetAuthCookie(userName, rememberMe);
return true;
}
else
throw new Exception(errorMessage);
}
web.config
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=152368
-->
<configuration>
<configSections>
<section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="MvcUI.HtmlHelpers" />
<add namespace="MyProject.API" />
<add namespace="MvcUI.Models" />
</namespaces>
</pages>
</system.web.webPages.razor>
<connectionStrings>
<add name="ApplicationServices"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
<add assembly="Microsoft.ReportViewer.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
<add assembly="Microsoft.Build.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
<add assembly="System.Management, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
</assemblies>
<buildProviders>
<add extension=".rdlc" type="Microsoft.Reporting.RdlBuildProvider, Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</buildProviders>
</compilation>
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
applicationName="/" />
</providers>
</membership>
<profile>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" />
</providers>
</profile>
<roleManager enabled="false">
<providers>
<clear/>
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages"/>
</namespaces>
</pages>
<httpHandlers>
<add path="Reserved.ReportViewerWebControl.axd" verb="*" type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
validate="false" />
</httpHandlers>
</system.web>
<nhibernate>
<add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
<add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect"/>
<add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/>
<add key="hibernate.connection.connection_string" value="Server=.\SQLEXPRESS;Database=myDatabase;User=me;Pwd=password;"/>
<add key="hibernate.show_sql" value="false"/>
</nhibernate>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true"/>
<handlers>
<add name="ReportViewerWebControlHandler" preCondition="integratedMode" verb="*" path="Reserved.ReportViewerWebControl.axd" type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</handlers>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
account Model
public interface IFormsAuthenticationService
{
void SignIn(string userName, bool createPersistentCookie);
void SignOut();
}
public class FormsAuthenticationService : IFormsAuthenticationService
{
public void SignIn(string userName, bool createPersistentCookie)
{
if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
}
public void SignOut()
{
FormsAuthentication.SignOut();
}
}
The error message points to the Gloabal.asax.cs file and shown above.
Error message:
I have also included a machine key generated but it has not solved the problem,
Based on your feedback, the reason you are experiencing that error may be due to the fact you are using an auto-generated machineKey for your application (also possibly in multiple machines/app pools or even in one app pool that recycles too frequently).
Please make sure to check this one out.
Have you applied this patch?
I see you don't have ticketCompatibilityMode set as .net 4 has changed the way encryption works.
<forms
loginUrl="/Login.aspx"
timeout="2880"
ticketCompatibilityMode="Framework20"
domain="domain.com"/>
Check that you have the same machineKeys on both systems. Make sure you also apply that patch.
Because the patch modifies the encryption/signing behavior of certain features in ASP.NET, it is important that you apply it to all machines in a web-farm. If you have a mix-match of patched/un-patched systems you’ll have forms-authentication, webresource.axd, and scriptresource.axd requests succeed/fail depending on which server they hit in the farm (since the encryption used would be different across them).
I assume your users are redirected to somewhere upon reaching the login page if the request is authenticated and thus they can't access the login page after the first successful login.
If this is the case, you may want to force your users to sign out upon reaching the login page, on the first load of the page. For example (Razor syntax, C#):
#if (!IsPost && Request.IsAuthenticated)
{
FormsAuthentication.SignOut();
}
On the GET (not post) of LogOn action method. Check if user is authenticated and log out if so.
if (System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
{
FormsAuthentication.SignOut();
}
Thanks to all of you for having tried to reply to the question. Indeed they were all helpful. I solved the problem myself by adding a machinekey to the wenconfig, as well as a form name had to be there. without te form name, even the machine key was not useful

InvalidOperationException thrown regarding DotNetOpenAuth.IEmbeddedResourceRetrieval with Razor view

When my Razor view calls #Html.OpenIdSelector(... I get an InvalidOperationException:
The current IHttpHandler is not one of
types: System.Web.UI.Page,
DotNetOpenAuth.IEmbeddedResourceRetrieval.
An embedded resource URL provider must
be set in your .config file.
What exactly should I set in the config file?
Just NuGet the DotNetOpenAuth package. It will setup everything you need in your config file:
Right click on the References of your web project in the solution explorer
Add Library Package Reference...
Click on the Online tab.
In the search box type dotnetopenauth
Click Install
Everything will be automatically setup and the correct assemblies will be downloaded from the internet and added as reference.
Here's how the web.config file looks like after performing this:
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=152368
-->
<configuration>
<configSections>
<section name="uri" type="System.Configuration.UriSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<section name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection" requirePermission="false" allowLocation="true" />
</configSections>
<connectionStrings>
<add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</assemblies>
</compilation>
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
<membership>
<providers>
<clear />
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
<profile>
<providers>
<clear />
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" />
</providers>
</profile>
<roleManager enabled="false">
<providers>
<clear />
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages" />
</namespaces>
</pages>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
<legacyHMACWarning enabled="0" />
</runtime>
<uri>
<!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names),
which is necessary for OpenID urls with unicode characters in the domain/host name.
It is also required to put the Uri class into RFC 3986 escaping mode, which OpenID and OAuth require. -->
<idn enabled="All" />
<iriParsing enabled="true" />
</uri>
<system.net>
<defaultProxy enabled="true" />
<settings>
<!-- This setting causes .NET to check certificate revocation lists (CRL)
before trusting HTTPS certificates. But this setting tends to not
be allowed in shared hosting environments. -->
<!--<servicePointManager checkCertificateRevocationList="true"/>-->
</settings>
</system.net>
<dotNetOpenAuth>
<!-- This is an optional configuration section where aspects of dotnetopenauth can be customized. -->
<!-- For a complete set of configuration options see http://www.dotnetopenauth.net/developers/code-snippets/configuration-options/ -->
<openid>
<relyingParty>
<security requireSsl="false" />
<behaviors>
<!-- The following OPTIONAL behavior allows RPs to use SREG only, but be compatible
with OPs that use Attribute Exchange (in various formats). -->
<add type="DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform, DotNetOpenAuth" />
</behaviors>
</relyingParty>
</openid>
<messaging>
<untrustedWebRequest>
<whitelistHosts>
<!-- Uncomment to enable communication with localhost (should generally not activate in production!) -->
<!--<add name="localhost" />-->
</whitelistHosts>
</untrustedWebRequest>
</messaging>
<!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
<reporting enabled="true" />
</dotNetOpenAuth>
</configuration>
UPDATE:
You could implement a custom resource retrieval provider:
public class CustomResourceProvider : IEmbeddedResourceRetrieval
{
public Uri GetWebResourceUrl(Type someTypeInResourceAssembly, string manifestResourceName)
{
return new Uri("http://www.google.com");
}
}
and then register it in web.config:
<dotNetOpenAuth>
<webResourceUrlProvider type="AppName.CustomResourceProvider, AppName" />
...
</dotNetOpenAuth>
But I would recommend you using the openid-selector library for generating login forms.
I came across this problem when I was trying to get the NerdDinner OpenID working for MVC3/razor. The solution that has worked for me is:
Create this class in your solution: (this was found in one of the NerdDinner builds - http://nerddinner.codeplex.com/SourceControl/changeset/view/55257#1328982 (thanks to JasonHaley)
for some reason, this file isn't in the latest build for NerdDinner MVC3/Razor
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DotNetOpenAuth;
namespace <Your App>.Services
{
public class EmbeddedResourceUrlService : IEmbeddedResourceRetrieval
{
private static string pathFormat = "{0}/{1}/Resource/GetWebResourceUrl?assemblyName={2}&typeName={3}&resourceName={‌​4}";
//private static string pathFormat = "{0}/Resource/GetWebResourceUrl";
public Uri GetWebResourceUrl(Type someTypeInResourceAssembly, string manifestResourceName)
{
if (manifestResourceName.Contains("http"))
{
return new Uri(manifestResourceName);
}
else
{
var assembly = someTypeInResourceAssembly.Assembly;
// HACK
string completeUrl = HttpContext.Current.Request.Url.ToString();
string host = completeUrl.Substring(0,
completeUrl.IndexOf(HttpContext.Current.Request.Url.AbsolutePath));
var path = string.Format(pathFormat,
host,
HttpContext.Current.Request.ApplicationPath.Substring(1),
HttpUtility.UrlEncode(assembly.FullName),
HttpUtility.UrlEncode(someTypeInResourceAssembly.ToString()),
HttpUtility.UrlEncode(manifestResourceName));
return new Uri(path);
}
}
}
}
Then in your web.config, add this line:
<webResourceUrlProvider type="<Your App>.Services.EmbeddedResourceUrlService, <Your App>" />
just put in the DotNetOpenAuth section
you will also need this route set up: ( Html.OpenIdSelectorScripts helper method throwing NullReferenceException )
routes.MapRoute(
"OpenIdDiscover",
"Auth/Discover"
);

Resources