c# - How to fake or mock user logging in (authentication) with ASP.NET MVC for functional testing -
i'm building custom permissions system asp.net mvc, because authorization system comes mvc isn't flexible enough our needs. includes mvc area that's packaged dll along views, css , javascript. have unit tests already, i'm trying create functional tests through browser. these functional tests run locally computer or on continuous integration server.
the permissions system i'm building doesn't authentication. handles authorization. ideally i'd fake user log-ins each test. create user session arbitrary usernames , passwords instead of keeping separate table of users passwords, , authenticating against that.
i tried setting genericprincipal
object in session in accountcontroller
, , setting httpcontext.current.user
before each request, request seen unauthenticated:
accountcontroller
[authorize] public class accountcontroller : controller { // // post: /account/login [httppost] [allowanonymous] [validateantiforgerytoken] public actionresult login(loginviewmodel model, string returnurl) { if (modelstate.isvalid) { formsauthentication.setauthcookie(model.username, model.rememberme); // add fake user current session global.asax can set // user on current httpcontext mock object. (see // global.asax, application_acquirerequeststate) httpcontext.session["currentuser"] = new genericprincipal(new genericidentity(model.username), new string[0]); if (url.islocalurl(returnurl)) return redirect(returnurl); return redirecttoaction("index", "home"); } modelstate.addmodelerror(string.empty, "username or password incorrect"); return view(model); } }
global.asax
public class mvcapplication : system.web.httpapplication { protected void application_acquirerequeststate(object sender, eventargs e) { if (httpcontext.current.session != null) { // try mock user session, set in // accountcontroller.login... httpcontext.current.user = httpcontext.current.session["currentuser"] iprincipal; } } }
i created custom authorize
attribute used in mvc controllers:
public class permissionlevelattribute : system.web.mvc.authorizeattribute { public override void onauthorization(authorizationcontext filtercontext) { if (!filtercontext.httpcontext.request.isauthenticated || currentprincipal == null) { base.onauthorization(filtercontext); return; } // custom permissions logic... } }
example usage of attribute in controller:
public class blogpostscontroller : controller { [permissionlevel(roles="blogs.posts.edit.update")] public actionresult edit(int id) { // ... } }
when this, filtercontext.httpcontext.request.isauthenticated
property false, , bails out of onauthorization
method.
how fake or mock user login in asp.net mvc creates httpcontext.current.session
object , sets httpcontext.current.user
?
this solution doesn't create "mock" user creates fake user , doesn't check username , password. this, you'll need make 2 major changes:
rewrite
accountcontroller
doesn't check username , password[authorize] public class accountcontroller : controller { // // get: /account/login [allowanonymous] public actionresult login(string returnurl) { viewbag.returnurl = returnurl; return view(); } // // post: /account/login [httppost] [allowanonymous] [validateantiforgerytoken] public actionresult login(loginviewmodel model, string returnurl) { if (modelstate.isvalid) { formsauthentication.setauthcookie(model.username, model.rememberme); if (url.islocalurl(returnurl)) return redirect(returnurl); return redirecttoaction("index", "home"); } modelstate.addmodelerror(string.empty, "username or password incorrect"); return view(model); } // // get: /account/logoff public actionresult logoff() { formsauthentication.signout(); return redirecttoaction("index", "home"); } }
remove or comment out owin related config settings in web.config:
<configuration> <system.webserver> <modules> <!--<remove name="formsauthentication" />--> </modules> </system.webserver> <runtime> <assemblybinding xmlns="urn:schemas-microsoft-com:asm.v1"> <!--<dependentassembly> <assemblyidentity name="microsoft.owin.security" publickeytoken="31bf3856ad364e35" /> <bindingredirect oldversion="0.0.0.0-3.0.1.0" newversion="3.0.1.0" /> </dependentassembly> <dependentassembly> <assemblyidentity name="microsoft.owin.security.oauth" publickeytoken="31bf3856ad364e35" /> <bindingredirect oldversion="0.0.0.0-3.0.1.0" newversion="3.0.1.0" /> </dependentassembly> <dependentassembly> <assemblyidentity name="microsoft.owin.security.cookies" publickeytoken="31bf3856ad364e35" /> <bindingredirect oldversion="0.0.0.0-3.0.1.0" newversion="3.0.1.0" /> </dependentassembly> <dependentassembly> <assemblyidentity name="microsoft.owin" publickeytoken="31bf3856ad364e35" /> <bindingredirect oldversion="0.0.0.0-3.0.1.0" newversion="3.0.1.0" /> </dependentassembly>--> </assemblybinding> </runtime> </configuration>
this allow log in arbitrary user password.
important: wouldn't production version of web application, obviously. building mvc area nuget package , installing package on clean mvc project write automated tests against integrated nuget package , mvc application. that's why able use solution.
Comments
Post a Comment