Update 1: If i set the session via ajax request, this session is not available to me when the js does does a refresh of the current action. Now, if i setup a session via non ajax requests then these are available inside other controller even ajax actions as well.
Update 2: By removing and adding the session helped with this issue
<modules runAllManagedModulesForAllRequests="true">
<remove name="Session" />
<add name="Session" type="System.Web.SessionState.SessionStateModule"/>
</modules>
I am setting up a new site, this uses forms authentication that i am validating against the active directory. On successful authentication, i put the user class in the session and it is available to me when i check it right away.
//login user and put the user in session
AuthenticationHelper.LoginUser(user, loginModel.IsRememberMe);
//just checking
var userFromSession = AuthenticationHelper.GetUserFromSession();
public static void LoginUser(User user, bool isRememberMe)
{
//login user and put user in the session
//log off first
LogOff();
//add user to session
AddUserToSession(user);
//sign in
if (!isRememberMe)
{
//Set cookie
FormsAuthentication.SetAuthCookie(user.UserId, false);
/*
GenericIdentity identity = new GenericIdentity(user.UserId);
string[] roles = { person.PersonaType };
GenericPrincipal principal = new GenericPrincipal(identity, roles);
HttpContext.Current.User = principal;
*/
}
else
{
//Create Persistent cookie
var ticket = new FormsAuthenticationTicket(user.UserId, isRememberMe, 1);
var encrypted = FormsAuthentication.Encrypt(ticket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrypted);
authCookie.Expires = System.DateTime.Now.AddYears(1);
if (HttpContext.Current != null)
{
HttpContext.Current.Response.Cookies.Add(authCookie);
}
}
}
public static void AddUserToSession(User user)
{
if (HttpContext.Current != null && HttpContext.Current.Session != null)
{
HttpContext.Current.Session["SignedInUser"] = user;
}
}
public static User GetUserFromSession()
{
User user = null;
if (HttpContext.Current != null && HttpContext.Current.Session != null)
{
user = (User) HttpContext.Current.Session["SignedInUser"];
}
return user;
}
However, when i refresh the page at the same very moment after login, my session is coming back as null. In this case Request.IsAuthenticated is true and User.Identity.Name has my user name in it.
I have the following in the web.config as well.
What am i missing here?
Here is the full web.config. Either i am missing something from the web.config or something is interfering with my session.
<?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=301880
-->
<configuration>
<!-- Move site specific app settings to their own environment config file inside Configs folder. Keep common settings here -->
<appSettings file="Configs\AppSettings_CurrentSprint.config">
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<machineKey validationKey="" validation="SHA1" decryption="AES" />
<sessionState mode="InProc" timeout="20" />
<authentication mode="Forms">
<forms loginUrl="~/EPT/Home" name="SalesSupport.ASPXFORMSAUTH" enableCrossAppRedirects="true" timeout="20" slidingExpiration="true" />
<!-- timeout="600" -->
</authentication>
<membership>
<providers>
<clear />
</providers>
</membership>
<profile>
<providers>
<clear />
</providers>
</profile>
<customErrors mode="Off" />
<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" />
<add namespace="System.Web.Optimization" />
</namespaces>
</pages>
</system.web>
<system.webServer>
<urlCompression doStaticCompression="true" doDynamicCompression="true" />
<validation validateIntegratedModeConfiguration="false" />
<!--Had to set this for it to work on IIS 7-->
<modules runAllManagedModulesForAllRequests="true" />
<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" />
</handlers>
<staticContent>
<!--Required to get IIS to compress javascript files-->
<remove fileExtension=".js" />
<mimeMap fileExtension=".js" mimeType="text/javascript" />
</staticContent>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Related
I'm taking over a solution from a previous developer. In it are two projects. Both started as web forms. He added mvc to the one project and it works. I added mvc to the other one and no matter what I do I get 404s for all of my routing. I've compared everything I can think of between the two projects, spent the last day googling for an answer and can't figure out why it isn't working. This is running in visual studio 2017 with iisexpress, mvc 5.2.3.
Here's my web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="glimpse" type="Glimpse.Core.Configuration.Section, Glimpse.Core" />
</configSections>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="Glimpse" type="Glimpse.AspNet.HttpModule, Glimpse.AspNet" preCondition="integratedMode" />
</modules>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<add name="Glimpse" path="glimpse.axd" verb="GET" type="Glimpse.AspNet.HttpHandler, Glimpse.AspNet" preCondition="integratedMode" />
</handlers>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET,POST" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
</system.webServer>
<glimpse defaultRuntimePolicy="On" endpointBaseUri="~/Glimpse.axd"></glimpse>
<system.web>
<webServices>
<protocols>
<add name="HttpGet" />
<add name="HttpPost" />
</protocols>
</webServices>
<compilation debug="true" targetFramework="4.6.1">
<assemblies>
<add assembly="System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
<add assembly="System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
<add assembly="System.Web.Extensions.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<add assembly="System.Web.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</assemblies>
</compilation>
<identity impersonate="true" />
<httpRuntime maxRequestLength="30720" requestValidationMode="2.0"/>
<httpModules>
<add name="Glimpse" type="Glimpse.AspNet.HttpModule, Glimpse.AspNet" />
</httpModules>
<authorization>
<allow users="*" />
</authorization>
<customErrors mode="Off">
<error statusCode="404" redirect="~/Errors/PageNotFound.aspx" />
</customErrors>
<authentication mode="Windows" />
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">
<tagMapping>
<add tagType="System.Web.UI.WebControls.CompareValidator" mappedTagType="Sample.Web.UI.Compatibility.CompareValidator, Validators, Version=1.0.0.0" />
<add tagType="System.Web.UI.WebControls.CustomValidator" mappedTagType="Sample.Web.UI.Compatibility.CustomValidator, Validators, Version=1.0.0.0" />
<add tagType="System.Web.UI.WebControls.RangeValidator" mappedTagType="Sample.Web.UI.Compatibility.RangeValidator, Validators, Version=1.0.0.0" />
<add tagType="System.Web.UI.WebControls.RegularExpressionValidator" mappedTagType="Sample.Web.UI.Compatibility.RegularExpressionValidator, Validators, Version=1.0.0.0" />
<add tagType="System.Web.UI.WebControls.RequiredFieldValidator" mappedTagType="Sample.Web.UI.Compatibility.RequiredFieldValidator, Validators, Version=1.0.0.0" />
<add tagType="System.Web.UI.WebControls.ValidationSummary" mappedTagType="Sample.Web.UI.Compatibility.ValidationSummary, Validators, Version=1.0.0.0" />
</tagMapping>
</pages>
<trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />
<globalization requestEncoding="utf-8" responseEncoding="utf-8" />
<!-- Glimpse: This can be commented in to add additional data to the Trace tab when using WebForms
<trace writeToDiagnosticsTrace="true" enabled="true" pageOutput="false"/> -->
<httpHandlers>
<add path="glimpse.axd" verb="GET" type="Glimpse.AspNet.HttpHandler, Glimpse.AspNet" />
</httpHandlers>
</system.web>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.2.1.0" newVersion="3.2.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization maxJsonLength="50000000" />
</webServices>
</scripting>
</system.web.extensions>
</configuration>
Global.asax.cs
protected void Application_Start(object sender, EventArgs e)
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*allaspx}", new { allaspx = #".*\.aspx(/.*)?" });
routes.IgnoreRoute("{*allasmx}", new { allasmx = #".*\.asmx(/.*)?" });
routes.IgnoreRoute("");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
I finally got it working by adding this class to the Areas>API folder.
public class APIAreaRegistration : AreaRegistration
{
public override string AreaName => "API";
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"API",
"API/{controller}/{action}/{id}",
new {action = "Index", id = UrlParameter.Optional}
);
}
}
I'm trying to make a way of the user stays logged in a website, but after some time (a couple of hours), the user needs to login again.
This is the code that I'm using:
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
ExpireTimeSpan = TimeSpan.FromDays(30),
SlidingExpiration = true
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
#region Facebook Authentication
var facebookAuthenticationOptions = new FacebookAuthenticationOptions
{
AppId = Util.GetConfigValue("FacebookAppID"),
AppSecret = Util.GetConfigValue("FacebookAppSecret"),
SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie
};
"email,user_about_me,user_birthday,user_hometown,user_location,user_website,user_relationships,user_mobile_phone"
.Split(',')
.ToList()
.ForEach(scope => facebookAuthenticationOptions.Scope.Add(scope));
facebookAuthenticationOptions.Provider = new FacebookAuthenticationProvider()
{
OnAuthenticated = async context =>
{
context.Identity.AddClaim(new Claim("FacebookAccessToken", context.AccessToken));
foreach (var claim in context.User)
{
var claimType = string.Format("urn:facebook:{0}", claim.Key);
var claimValue = claim.Value.ToString();
if (!context.Identity.HasClaim(claimType, claimValue))
context.Identity.AddClaim(new Claim(claimType, claimValue, "XmlSchemaString", "Facebook"));
}
}
};
app.UseFacebookAuthentication(facebookAuthenticationOptions);
#endregion
}
Here is the code of the AccountController:
// occurs when user authorize app in facebook
public async Task<ActionResult> Callback(string returnUrl)
{
var result = await AuthenticationManager.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie);
if (result == null || result.Identity == null)
{
TempData[Constants.ALERT] = "Error";
return RedirectToAction("Index", "Home");
}
// insert or update user info in database
var user = userService.GenerateUser(result.Identity.Claims);
if (!user.Active || user.IsLocked)
{
TempData[Constants.ALERT] = "Error";
return RedirectToAction("Index", "Home");
}
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = CreateClaimsIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = false }, identity);
return RedirectToLocal(returnUrl);
}
private ClaimsIdentity CreateClaimsIdentity(User user, string authenticationType)
{
var result = new ClaimsIdentity(authenticationType, ClaimTypes.Name, ClaimTypes.Role);
result.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString(), "http://www.w3.org/2001/XMLSchema#string"));
result.AddClaim(new Claim(ClaimTypes.Name, user.Mail, "http://www.w3.org/2001/XMLSchema#string"));
result.AddClaim(new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"));
result.AddClaim(new Claim("AspNet.Identity.SecurityStamp", Guid.NewGuid().ToString()));
result.AddClaim(new Claim(Constants.SUPER_USER, user.Super.ToString()));
return result;
}
and here the web.config:
<?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=301880
-->
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
<connectionStrings>
<add name="QueroShowConn" connectionString="Data Source=..." providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="FacebookAppID" value="..." />
<add key="FacebookAppSecret" value="..." />
</appSettings>
<system.web>
<customErrors mode="On">
<error statusCode="404" redirect="/Error/NotFound" />
<error statusCode="403" redirect="/Error/Authentication" />
</customErrors>
<compilation targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<globalization enableClientBasedCulture="true" uiCulture="auto:pt-BR" culture="auto:pt-BR" />
</system.web>
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="403"/>
<remove statusCode="404"/>
<error statusCode="403" responseMode="ExecuteURL" path="/Error/Authentication"/>
<error statusCode="404" responseMode="ExecuteURL" path="/Error/NotFound"/>
</httpErrors>
<modules runAllManagedModulesForAllRequests="true">
<remove name="FormsAuthenticationModule"/>
</modules>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Ninject" publicKeyToken="c7192dc5380945e7" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.2.0.0" newVersion="3.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Practices.ServiceLocation" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.3.0.0" newVersion="1.3.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNet.Identity.Core" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
Any ideias about what is going on?
I installed Elmah.io properly but it doesnt work.
Visual studio gives 6 messages like; Could not find schema information for the element 'security' and 'errorlog' and 'elmah' and 'type' and logid and 'allowremoteaccess' .
how can i make it work?
<configuration>
<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>
<connectionStrings>
<add name="deneme" providerName="System.Data.SqlClient"
connectionString="Data Source=THERMALTAKE\SQLSERVER2012;Initial Catalog=Tanimlama;Integrated Security=true;"/>
</connectionStrings>
<appSettings>
<add key="webpages:Version" value="3.0.0.0"/>
<add key="webpages:Enabled" value="false"/>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5"/>
<httpRuntime targetFramework="4.5"/>
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880"/>
</authentication>
<membership defaultProvider="CustomMembershipProvider">
<providers>
<clear/>
<add name="CustomMembershipProvider" type="membership_kendiyazdigim.Security.CustomMembershipProvider" connectionStringName="deneme"
maxInvalidPasswordAttempts="5" applicationName="/" enablePasswordRetrieval="false" passwordAttemptWindow="10" requiresQuestionAndAnswer="false"
enablePasswordReset="true" requiresUniqueEmail="true" cacheTimeoutInMinutes="5"/>
</providers>
</membership>
<roleManager defaultProvider="CustomRoleProvider" enabled="true">
<providers>
<clear/>
<add name="CustomRoleProvider" type="membership_kendiyazdigim.Security.CustomRoleProvider" cacheTimeoutInMinutes="5"/>
</providers>
</roleManager>
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah"/>
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah"/>
</httpModules></system.web>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-5.1.0.0" newVersion="5.1.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler"/>
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler"/>
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" preCondition="managedHandler"/>
</modules>
</system.webServer><elmah>
<security allowRemoteAccess="false"/>
<errorLog type="Elmah.Io.ErrorLog, Elmah.Io" LogId="8b3ab986-ccfe-4099-ac3c-790942e77488"/>
</elmah><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>
</location></configuration>
and this is my global logger filter...
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new ElmahHandledErrorLoggerFilter());
}
}
public class ElmahHandledErrorLoggerFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
if(context.ExceptionHandled)
{
ErrorSignal.FromCurrentContext().Raise(context.Exception);
}
}
}
I've got an ASP.NET MVC application which is a passive RP with ADFS 2.0. This application redirects all unauthorised users to ADFS. Upon successful login, users are redirected back to the web app with a token that contains their claims. Nothing really new here.
What I want to do now is to call a WCF service with issued token so this service does not need to go back to ADFS and do all that security handshaking again.
After hours and hours of researching I am finally able to call the service, however, when I use the following code within my service, my user is still not authenticated:
public string GetName()
{
var user = Thread.CurrentPrincipal.Identity as ClaimsIdentity;
if (user != null && user.IsAuthenticated)
{
return user.FindFirst(x => x.Type == ClaimTypes.NameIdentifier).Value;
}
return "Unable to find your username. Something went wrong .... sorry!";
}
I am aware that this topic has hundreds and hundreds of articles and other stackoverflow questions but I have had no luck in finding why my user is not authenticated even though I can successfully call my service.
Some other code and configuration details you might need to help with this:
Web App
Service call
var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
binding.Security.Message.IssuedKeyType = SecurityKeyType.BearerKey;
binding.Security.Message.EstablishSecurityContext = true;
binding.Security.Message.IssuerAddress = new EndpointAddress("https://fs.server.com/adfs/services/trust");
var endpoint = new EndpointAddress("https://" + "localhost/service" + "/user.svc");
var factory = new ChannelFactory<IUser>(binding, endpoint);
factory.Credentials.SupportInteractive = false;
factory.Credentials.UseIdentityConfiguration = true;
var context = (BootstrapContext)((ClaimsIdentity)Thread.CurrentPrincipal.Identity).BootstrapContext;
var channel = factory.CreateChannelWithIssuedToken(context.SecurityToken, endpoint);
ViewBag.Username = channel.GetName();
((IServiceChannel)channel).Close();
return View();
Web.config
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</configSections>
<appSettings>
<add key="webpages:Version" value="2.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="PreserveLoginUrl" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="ida:FederationMetadataLocation" value="https://fs.server.com:49160/FederationMetadata/2007-06/FederationMetadata.xml" />
<add key="ida:Issuer" value="https://fs.server.com:49160/adfs/ls/" />
<add key="ida:ProviderSelection" value="productionSTS" />
</appSettings>
<system.identityModel>
<identityConfiguration saveBootstrapContext="true">
<audienceUris>
<add value="https://localhost/rp_poc" />
</audienceUris>
<issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
<authority name="https://fs.server.com/adfs/services/trust">
<keys>
<add thumbprint="723C3A29732FC61F3BE96487E8560F749D1D8256" />
</keys>
<validIssuers>
<add name="http://fs.server.com/adfs/services/trust" />
</validIssuers>
</authority>
</issuerNameRegistry>
</identityConfiguration>
</system.identityModel>
<system.identityModel.services>
<federationConfiguration>
<cookieHandler requireSsl="true" />
<wsFederation passiveRedirectEnabled="true" issuer="https://fs.server.com:49160/adfs/ls/" realm="https://localhost/rp_poc" requireHttps="true" />
</federationConfiguration>
</system.identityModel.services>
<system.web>
<authentication mode="None" />
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" requestValidationMode="4.5" />
<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>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<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>
<modules>
<remove name="FormsAuthentication" />
<add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
</modules>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-1.3.0.0" newVersion="1.3.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
WCF Service
Web.config
<configuration>
<configSections>
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</configSections>
<system.identityModel>
<identityConfiguration saveBootstrapContext="true">
<issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
<authority name="https://fs.server.com/adfs/services/trust">
<keys>
<add thumbprint="723C3A29732FC61F3BE96487E8560F749D1D8256" />
</keys>
<validIssuers>
<add name="http://fs.server.com/adfs/services/trust" />
</validIssuers>
</authority>
</issuerNameRegistry>
<audienceUris>
<add value="https://localhost/rp_poc" />
</audienceUris>
</identityConfiguration>
</system.identityModel>
<system.serviceModel>
<bindings>
<ws2007FederationHttpBinding>
<binding>
<security mode ="TransportWithMessageCredential">
<message issuedKeyType ="BearerKey" establishSecurityContext="true">
<issuer address ="https://fs.server.com/adfs/services/trust"
binding ="ws2007HttpBinding" />
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="DefaultBehaviour" >
<serviceSecurityAudit auditLogLocation="Application" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure" suppressAuditFailure="true" />
<serviceMetadata httpGetEnabled="true" />
<serviceCredentials useIdentityConfiguration="true">
<serviceCertificate findValue="74 0A FE 19 E9 F0 53 9C 46 D9 F2 D6 56 A7 0C E8" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySerialNumber">
</serviceCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="POC.Security.ServiceClient.User" behaviorConfiguration="DefaultBehaviour" >
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
<endpoint contract="POC.Security.ServiceClient.IUser" binding="ws2007FederationHttpBinding" address=""/>
</service>
</services>
<diagnostics>
<messageLogging maxMessagesToLog="25000" logEntireMessage="true"
logMessagesAtServiceLevel="false"
logMalformedMessages="true" logMessagesAtTransportLevel="true">
<filters>
<clear/>
</filters>
</messageLogging>
</diagnostics>
</system.serviceModel>
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Error, Warning, ActivityTracing" propagateActivity="true" >
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging" switchValue="Error, Warning">
<listeners>
<add name="xml" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\Temp\ServicesLog.svclog" />
</sharedListeners>
</system.diagnostics>
</configuration>
Try adding a serviceAuthorization behavior to your WCF service - with principalPermissionMode = always.
Also - if you want a behavior to be "default" - you typically remove the name attribute. Otherwise you have to explicitly reference it from the service element.
see
http://leastprivilege.com/2012/11/16/wcf-and-identity-in-net-4-5-external-authentication-with-ws-trust/
I'm developing an MVC 4 project to be deployed to Azure.
I have the following route configuration:
routes.MapRoute(
name: "BrowseBusinessByType",
url: "Browse/Business/ByType/{industry}/{region}/{city}/{page}",
defaults: new
{
controller = "Browse",
action = "Business",
region = UrlParameter.Optional,
city = UrlParameter.Optional,
page = UrlParameter.Optional
}
);
routes.MapRoute(
name: "BrowseBusinessByCity",
url: "Browse/Business/ByCity/{region}/{city}/{industry}/{page}",
defaults: new
{
controller = "Browse",
action = "Business",
industry = UrlParameter.Optional,
city = UrlParameter.Optional,
page = UrlParameter.Optional
}
);
There are more routes, but I swear the order is specific to generic, not otherwise.
On localhost, I use:
#Html.RouteLink(#String.Format("{0} ({1})", industryCount.Industry.Name,
industryCount.Count), new {
Controller = "Browse",
Action = "Business",
industry = industryCount.Industry.Slug
})
to get the URL like
http://localhost:49311/Browse/Business/ByType/offices.
However, when delployed to Azure shared web site, the route becomes
http://www.zzzz.dd/Browse/Business?industry=offices
As routes are named, I tried to use
#Html.RouteLink(
#String.Format("{0} ({1})", cityCount.City.Name, cityCount.Count),
"BrowseBusinessByCity",
new
{
region = cityCount.City.Region.Slug,
city = cityCount.City.Slug,
})
Which gives me
http://localhost:49311/Browse/Business/ByCity/eu/helsinki
on localhost and on deploy the html code for link is:
London (8)
What is even more challenging, my routes are completely functioning on URL (in Azure)
http://xxxx.dd/Browse/Business/ByCity/eu/helsinki
Phil Haack's routedebug2 output, Azure:
http://i.stack.imgur.com/Fzbgb.png
routedebug2, localhost:
http://i.stack.imgur.com/4kp3z.png
Thank you in advance for all your help!
UP:
I decided to publish web.configs in order to clear any doubts.
Debug:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework"
type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
</configSections>
<connectionStrings>
<add name="BusinessDBEntities"
connectionString="data source=ANDREW-PC\;initial catalog=BusinessCityEntities;integrated security=True;multipleactiveresultsets=True;application name=EntityFramework"
providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="azureStorageConnectionString"
value="***" />
<add key="azureContainer" value="thumbnails"/>
<add key="webpages:Version" value="2.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="PreserveLoginUrl" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="RouteDebugger:Enabled" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
<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>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true" />
<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>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
</entityFramework>
</configuration>
Release:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="BusinessDBEntities" connectionString="***" providerName="System.Data.SqlClient" />
<add name="DefaultConnection" connectionString="DefaultConnection_ConnectionString" providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="azureStorageConnectionString" value="***" />
<add key="azureContainer" value="thumbnails" />
<add key="webpages:Version" value="2.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="PreserveLoginUrl" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="RouteDebugger:Enabled" value="true" />
</appSettings>
<system.web>
<compilation targetFramework="4.0">
<assemblies>
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
<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>
<customErrors mode="Off" />
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true" />
<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>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
</entityFramework>
</configuration>
The reason this doesn't work is because you have too many UrlParameter.Optional segments. See this for more info.