Cannot get MVC working in asp.net web forms project - asp.net-mvc

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}
);
}
}

Related

'System.ArgumentNullException' while using Stimulsoft

I'm trying to use Stimulsoft Reports 2014.3 in my MVC 5.2 app. I get the following exception when I try to use #Html.Stimulsoft().StiMvcViewer.
An exception of type 'System.ArgumentNullException' occurred in mscorlib.dll
Value cannot be null. Parameter name: key
I can use #Html.Stimulsoft().StiMvcViewerFx just fine. I have tried various changes in web.config to get ride of this exception, but they were all useless. I've also tried Debug -> Exceptions, and checking both boxes for Common Language Runtime Exceptions, but there wasn't any other exception.
Adding #Html.Stimulsoft().RenderMvcViewerScripts() wasn't useful neither.
This is the view:
#using Stimulsoft.Report.Mvc
#using System.Web.UI.WebControls
#model Models.GenericReportViewModel
<div>
#Html.Stimulsoft().StiMvcViewer(new StiMvcViewerOptions()
{
ActionGetReportSnapshot = string.Concat("LoadReport?Id=", Model.ReportName),
Width = Unit.Point(500),
Theme = StiTheme.Default,
ActionExportReport = "ExportReport",
Height = Unit.Point(400),
Controller = "Report",
})
</div>
This is the web.config:
<system.web>
<globalization uiCulture="fa-IR" culture="fa-IR"></globalization>
<compilation debug="true" targetFramework="4.5">
<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="Stimulsoft.Base, Version=2014.3.0.0, Culture=neutral, PublicKeyToken=ebe6666cba19647a" />
<add assembly="Stimulsoft.Report, Version=2014.3.0.0, Culture=neutral, PublicKeyToken=ebe6666cba19647a" />
<add assembly="Stimulsoft.Report.Mvc, Version=2014.3.0.0, Culture=neutral, PublicKeyToken=ebe6666cba19647a" />
</assemblies>
</compilation>
<httpRuntime targetFramework="4.5" />
<pages>
<namespaces>
<add namespace="Kendo.Mvc.UI" />
<add namespace="System.Web.Helpers" />
<!--<add namespace="System.Web.Abstractions" />-->
<add namespace="Stimulsoft.Base" />
<add namespace="Stimulsoft.Report" />
<add namespace="Stimulsoft.Report.Mvc" />
</namespaces>
</pages>
</system.web>
I should note that the Flash version works as below and it doesn't have any problem:
#using Stimulsoft.Report.Mvc
#using System.Web.UI.WebControls
#model Models.GenericReportViewModel
<div>
#Html.Stimulsoft().RenderMvcViewerFxScripts()
#Html.Stimulsoft().StiMvcViewerFx(new StiMvcViewerFxOptions()
{
ActionGetReportSnapshot = string.Concat("LoadReport?Id=", Model.ReportName),
Width = Unit.Point(500),
Theme = StiMvcViewerFxOptions.Themes.Blue,
ActionExportReport = "ExportReport",
BackgroundColor = System.Drawing.Color.Silver,
ActionGetLocalization = "GetLocal",
Height = Unit.Point(400),
Controller = "Report",
})
</div>
It's been suggested to add the following bindingRedirect to web.config
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.1" />
</dependentAssembly>
Adding this will suppress the exception and prevents the page from rendering, probably because I'm not using MVC 3! But it should have something to do with it.
I also have this redirect as oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0", but I'll get the exception with this one.
Add this line in appsettings in web.config
<add key="PageInspector:ServerCodeMappingSupport" value="Disabled" />
Maybe your report file created with different version of Stimulsoft.

how can I make Elmah.io integrate with my custom membership provider in asp.net MVC?

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);
}
}
}

MVC 5 Session Issue

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>

Passive web application calling a WCF service

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/

Html.RouteLink stops generating links after deployment to Azure

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.

Resources