Have a legacy application and from there, my MVC application is called.
I planned to use custom httpmodule [AuthenticationModule class inherites IHttpModule]. In Init, I hooked up BeginRequest and do my FormAuthenication stuff...
private void Application_BeginRequest(Object source, EventArgs e) {
// Do my own authetication and issue FormAuthentication Ticket
}
In web.config:
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true">
<add name="AuthenticationModule" type="RealProperty.LegacySecurity.AuthenticationModule, RealProperty.LegacySecurity" preCondition="ManagedHandler"/>
</modules>
But my AuthenticationModule never got fire in debug...
(1) Can anyone explain why it isn't got called?
(2) Is it correct to do my authentication in BeginRequest?
Make sure you have both sections in your Web.config file:
<system.web>
<httpModules>
<add name="MyAuthenticationModule" type="Ns.To.MyAuthenticationModule, MyAssembly" />
</httpModules>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="MyAuthenticationModule" type="Ns.To.MyAuthenticationModule, MyAssembly" />
</modules>
</system.webServer>
Related
I have added a Web API feature to an ASP.NET MVC app and want to use attribute routing. When running the site in Visual Studio 2015, I can enter URLs in the browser address bar and get the methods on my controller to work. Once I move the site to IIS, all I get is 404 responses. I have tried many code changes with no luck.
The BuilderApiController file is in a WebAPI/v1/Controllers folder. Will attributes on the controller be found here?
namespace Hds.Edsi.WebAPI.V1.Controllers
{
[System.Web.Http.RoutePrefix("api/v1/builder")]
public class BuilderApiController : BaseApiController
{
[System.Web.Http.Route("GetExternalOrganizationID/{envisionOrgID}")]
[System.Web.Http.HttpGet]
public HttpResponseMessage GetExternalOrganizationID(string envisionOrgID)
{
WebApiConfig.cs file. Standard stuff. If I am using attribute routing, do I need the config.Routes.MapHttpRoute part? I have tried it with and without.
If I need it, what is the purpose of config.MapHttpAttributeRoutes()? When I look at GlobalConfiguration,Configuration._routes after Register is called, none of the attribute routing defined routes are there. Should they be?
namespace Hds.Edsi.WebAPI
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
/*
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/v1/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
*/
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new StringEnumConverter());
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
Components.Automapper.CreateMaps();
// Requrired for managing AppDomain teardown - IRegisteredObject
MonitorManager.RegisterInstance();
}
IIS Express:
http://localhost:8181/api/v1/builder/GetExternalOrganizationID/123.123.123.123.1234 returns a JSON object as I would expect.
IIS:
http://my server/api/v1/builder/GetExternalOrganizationID/123.123.123.123.1234 returns a 404
I am guessing that I am missing something simple here or don't understand how attribute routing works.
Added
Here is the system.webServer section from web.config:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<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>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*" verb="*" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
</handlers>
</system.webServer>
As per as i know, if it's not working properly on your IIS, then that is an IIS error, not an ASP.NET error so this doesn’t actually come from ASP.NET’s routing engine but from IIS’s handling of expressionless URLs.
You can try with adding runAllManagedModulesForAllRequests to your web.config
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="ScriptCompressionModule" type="Westwind.Web.ScriptCompressionModule,Westwind.Web" />
</modules>
</system.webServer>
In detail you can refer Rick Strahl's Web Log ASP.NET Routing not working on IIS 7.0
Hope this helps!
I have put the parameter in the web.config of the web.api that is being called. I even put it in the webapiconfig.cs to allow all sites hit the web.api. Even put it on the controller. And I still get this message? The calling website is sending json over to my web api. Why would I , could I be getting this error? What information can I give you guys to help me figure out this issue?
In reply to the solutions listed below: Here is the piece of my web.config....I put the wildcard of asterisk in it:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="*"/>
<add name="Access-Control-Allow-Headers" value="*" />
</customHeaders>
</httpProtocol>
Within my webapiconfig.cs file I have the following as well:
{
// enable CORS
config.EnableCors(new EnableCorsAttribute("*", "*", "*", "*"));
}
And here is my controller. I know, overkill, but I am trying to figure out this issue:
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class ExampleController : ApiController
Just check your web.config file and search for system.webServer section:
<system.webServer>
<httpProtocol>
<customHeaders>
<remove name="Access-Control-Allow-Origin" />
<remove name="Access-Control-Allow-Headers" />
<add name="Access-Control-Allow-Headers" value="Origin,X-Requested-With,Content-Type,Accept" />
</customHeaders>
</httpProtocol>
</system.webServer>
Try reading through https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS for the general idea of what's going on, and http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api for how to solve it in ASP.net
Essentially, if your request is coming from one server to another on a different domain, the other server must say it's happy to accept requests from browsers on the first domain.
To fix it, tell ASP.net to return 'Access-Control-Allow-Origin' headers that include the origin your request is coming from, either via web.config (as in the other answer), or by adding to your config and controller classes as below:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.EnableCors();
// ...
}
}
namespace WebService.Controllers
{
[EnableCors(origins: "http://myclientdomain.azurewebsites.net", headers: "*", methods: "*")]
public class TestController : ApiController
{
// ...
}
}
Everytime Elmah logs an error the error is logged twice. 100% identical with exact the same Timestamp.
I have no special configuration in the web.config.
I have created a ElmahHandleErrorAttribute an added two filters:
filters.Add(new ElmahHandleErrorAttribute {
ExceptionType = typeof(System.Data.Common.DbException),
// DbError.cshtml is a view in the Shared folder.
View = "DbError",
Order = 2
});
filters.Add(new ElmahHandleErrorAttribute {
ExceptionType = typeof(Exception),
// DbError.cshtml is a view in the Shared folder.
View = "Error",
Order = 3
});
Some Snippets from web.config:
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
</httpModules>
and
<modules runAllManagedModulesForAllRequests="true">
<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>
In the ElmaHandleErrorAttribute this code:
public override void OnException(ExceptionContext context) {
base.OnException(context);
if (!context.ExceptionHandled
|| TryRaiseErrorSignal(context)
|| IsFiltered(context))
return;
LogException(context);
}
I have searched a lot, but no solution fits to my problem. No double entries in web.config or something like this.
It's no big problem, but it's annoying.
thx in advance
©a-x-i
I had the same problem with my setup, so I made a ExceptionLogger class. Then added a static field to it to keep a list of the exceptions it logged. Then when the onException event hapens it checks for the last exception logged to avoid logging duplicates.
public class ExceptionLogger
{
public static List<Exception> loggedExceptions = new List<Exception>();
public static void LogException(Exception e) {
...
public override void OnException(ExceptionContext context)
{
base.OnException(context);
var e = context.Exception;
if (!e.Equals(ExceptionLogger.loggedExceptions.Last()))
{
ExceptionLogger.LogException(e);
}
}
I need to find who is the current user and check their groups in an active directory setup (windows server 2008) to see if they have permission to access certain pages (admin) on the mvc3 site I am constructing. However, whenever I create a PrincipalContext and query the current user, it returns the apppool the site is running under.
Ive tried:
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
UserPrincipal currentuser = UserPrincipal.Current;
string username = currentuser.DisplayName;
and
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "domain", "CN=dbcn LDAP,OU=the - account,DC=thedc,DC=local", "domain\\user", "password");
UserPrincipal currentuser = UserPrincipal.Current;
string username = currentuser.DisplayName;
Web.config looks like:
<configuration>
<appSettings>
<add key="webpages:Version" value="1.0.0.0" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="autoFormsAuthentication" value="false" />
<add key="enableSimpleMembership" value="false"/>
</appSettings>
<authentication mode="Windows" />
<membership defaultProvider="AspNetActiveDirectoryMembershipProvider">
<providers>
<clear />
<add name="AspNetActiveDirectoryMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="service" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider">
<providers>
<clear />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
<identity impersonate="false" />
<connectionStrings>
<add name="foocontext" connectionString="data source=foo;Initial Catalog=foo;Integrated Security=SSPI;MultipleActiveResultSets=true;" providerName="System.Data.SqlClient" />
<add name="ADService" connectionString="LDAP://foo.local/OU=the - service,DC=foo,DC=local" />
</connectionStrings>
</configuration>
Ive tried instantiating the context with two different accounts (and with no account specified), one of them the ldap account the IT admin uses for queries. What am I missing here? Why does it always return the apppool as the current user? How can I get the current logged in user.
Thanks!
HttpContext.User is what you want...
In ASP.NET, the security context of a user that is authenticated with Windows authentication is represented by the WindowsPrincipal and WindowsIdentity classes. ASP.NET applications that use Windows authentication can access the WindowsPrincipal class through the HttpContext.User property.
To retrieve the security context of the Windows authenticated user that initiated the current request, use the following code:
using System.Security.Principal;
...
// Obtain the authenticated user's Identity
WindowsPrincipal winPrincipal = (WindowsPrincipal)HttpContext.Current.User;
Asp.Net Windows Auth
This is what worked for me after some searching
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, User.Identity.Name);
I have a custom asp.net membership class I am building where I have a helper function that the
GetUser() method uses to convert the values from my database into a System.Web.Security.MembershipUser object.
private MembershipUser _converToMembershipUser(MembershipDBModel member)
{
System.Web.Security.MembershipUser membershipUser = new System.Web.Security.MembershipUser(
this.Name,
member.UserName,
member.UserID.ToString(),
member.Email,
member.PasswordQuestion,
member.Comment,
member.IsApproved,
member.IsLockedOut,
member.CreationDate,
member.LastLoginDate,
member.LastActivityDate,
member.LastPasswordChangedDate,
member.LastLockedOutDate);
return membershipUser;
}
This is the error that I keep getting when the above method is being called. I have not idea how to get around this so any suggestion is very welcome.
System.IO.FileLoadException was caught
Message=The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)
Source=System.Web
StackTrace:
at System.Web.Security.Membership.Initialize()
at System.Web.Security.MembershipAdapter.get_Providers()
at System.Web.Security.MembershipUser..ctor(String providerName, String name, Object providerUserKey, String email, String passwordQuestion, String comment, Boolean isApproved, Boolean isLockedOut, DateTime creationDate, DateTime lastLoginDate, DateTime lastActivityDate, DateTime lastPasswordChangedDate, DateTime lastLockoutDate)
at TMTechMembershipProvider.MembershipProvider._converToMembershipUser(MembershipDBModel member) in d:\Visual Studio 2010\Projects\TMTechMembershipProvider\TMTechMembershipProvider\TMTechMembershipProvider.cs:line 1005
at TMTechMembershipProvider.MembershipProvider.GetUser(String username) in d:\Visual Studio 2010\Projects\TMTechMembershipProvider\TMTechMembershipProvider\TMTechMembershipProvider.cs:line 965
at TMTechMembershipProvider.MembershipProvider.CreateUser(String username, String password, String email, String passwordQuestion, String passwordAnswer, Boolean isApproved, Object providerUserKey, MembershipCreateStatus& status) in d:\Visual Studio 2010\Projects\TMTechMembershipProvider\TMTechMembershipProvider\TMTechMembershipProvider.cs:line 435
InnerException:
System.Web.Security.MembershipAdapter.get_Providers() Initialize() The given assembly name or codebase was invalid.
config file
<?xml version="1.0"?>
<configuration>
<appSettings></appSettings>
<connectionStrings>
<add name="MembershipDBContext" providerName="System.Data.SqlServerCe.4.0" connectionString="data source=MembershipDBContext.sdf"/>
</connectionStrings>
<system.web>
<membership>
<providers>
<!--<remove name="AspNetSqlMembershipProvider"/>
<add name="AspNetSqlMembershipProvider" type="TMTechMembershipProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cbae438f5bab0724" connectionStringName="MembershipDBContext" enablePasswordRetrieval="true" enablePasswordReset="true" requiresQuestionAndAnswer="true" applicationName="MyUnitTests" requiresUniqueEmail="true" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="10" passwordStrengthRegularExpression=""/>-->
<clear/>
<!--<add name="TMTechMembershipProvider.MembershipProvider" type="TMTechMembershipProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cbae438f5bab0724" connectionStringName="MembershipDBContext" enablePasswordRetrieval="true" enablePasswordReset="true" requiresQuestionAndAnswer="true" applicationName="MyUnitTests" requiresUniqueEmail="true" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="10" passwordStrengthRegularExpression=""/>-->
<add name="TMTechMembershipProvider"
type="TMTechMembershipProvider.TempMembershipProvider"
connectionStringName="MembershipDBContext"
enablePasswordRetrieval="true"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
applicationName="MyUnitTests"
requiresUniqueEmail="true"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="6"
minRequiredNonalphanumericCharacters="1"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""/>
</providers>
</membership>
<machineKey validationKey="EAA358B778400490DE16A414AC2144C740874D426214CA81D8265354535ACCA9C0238D5C20021D4335DBE1171F31C02F0AB8ADD5B1EE2A6E07CC768F04B20F30" decryptionKey="AF622C5C9796D67DEB876483F1341E3708CA056B1EB031CEAD6FD7CBD0F13A50" validation="SHA1" decryption="AES"/>
</system.web>
<!--<system.web>
<membership>
<providers>
<remove name="AspNetSqlMembershipProvider"/>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="LocalSqlServer"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
applicationName="/"
requiresUniqueEmail="false"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="1"
minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10"
passwordStrengthRegularExpression="" />
</providers>
</membership>
</system.web>-->
<startup>
<!--<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>-->
</startup>
</configuration>
Error: "The given assembly name or codebase was invalid"
Your type attribute:
type="TMTechMembershipProvider.TempMembershipProvider"
Your type attribute in your commented line:
type="TMTechMembershipProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cbae438f5bab0724"
Your comment:
i tend to agree but this is needle in haystack. This is what I thought the Fusion Log Viewer was for to help identify what is failing to load.
sry, but lol :)
Update 1: re the comment:
Just found it funny, couldn't resist. Meant no harm and was not imply anything with it, we've all been there.
Now on a more serious note, it still seems an issue with specifically that line.
Let's compare it with the type line of the asp.net provider:
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
[Provider class (including the namespace)], [dll], [Version], ...
It seems you are missing either the class or the dll. Hoping that solves it, good luck.
This is not likely to be a code issue, it is a dll reference issue.
You need to carefully review any "type", "assembly", or "publicKeyToken" xml attributes in your web.config. The most likely cause is that you've mis-copied the public key token for an assembly. I would start by checking anywhere you've referenced the System.Web assembly and make sure that the public key token is exactly right and that there are no mispellings in any type names.
In particular, check the type attribute in the add element under the provider and membership element in your web.config. Also, if the custom membership class is implemented in a separate dll, be certain that you are actually referencing the correct version of the System.Web assembly from that dll.