We just upgraded a Commerce site from 7.5 to 9.2, and this also caused a new version of the EPiServer.ServiceAPI-package to be installed.
Our site uses Forms-authentication and we have a lot of REST-services implemented as standard Web API-controllers. These controllers are protected (so as to only allow authenticated users) by globally adding the AuthorizeAttribute like so:
After upgrading though, all the controllers return 401 - unauthorized. Removing the AuthorizeAttribute and debugging reveals that the HttpContext.Current.User is now a ClaimsIdentity (as opposed to FormsIdentity) and IsAuthenticated is false.
Removing the EPiServer.ServiceAPI nuget-package resolves the problem, but that's not a viable work around for us.
Seemingly then, the ServiceAPI-initialization does something in it's initialization, probably suppressing default host authentication, but this then has the side effect of affecting Web API in general.
Anyone have an idea of what is going on here, and more importantly, how to fix it?
For security purposes Service api uses SuppressDefaultHostAuthentication. If you want to use the standard configuration you will need to use headers for authorization and not cookies. You can use the token endpoint setup on the service api or create your own authorization attribute which authorizes through the header. If you dont want to use you need to change the standard configuration you need to disable which opens you up to csrf attacks.
Create a initialization module with dependency to EPiServer.ServiceApi.IntegrationInitialization
var handler = GlobalConfiguration.Configuration.MessageHandlers.FirstOrDefault(x => x.GetType() == typeof(PassiveAuthenticationMessageHandler));
While the MVC templates use a cookie based authentication mechanism, the new SPA templates prefer to use a token based authentication model explicitly passed via the Authorization HTTP header (which is better since it avoids CSRF attacks). This means that the default authentication from the host must be ignored since the authentication will be performed against something else other than a cookie. Web API 2 added a feature to ignore the host level authentication called SuppressDefaultHostAuthentication. This is an extension method on the HttpConfiguration that adds a message handler. The purpose of this message handler is to simply (and explicitly) assign an anonymous principal to the RequestContext’s Principal property. This way if cookie middleware does process an incoming cookie, by the time the call arrives at Web API the caller will be treated as anonymous.
Thanks, Mark. Much appreciated.
I wish the documentation/release info was a bit more candid regarding potentially breaking changes like this - I read the blog about the permissions-change and the AuthorizePermission attribute, but it really wasn't clear to me that this would break our WebAPI-auth.