Web API 2 with authorize attributes

Martin Doré asked on March 17, 2017 17:10

I created a Web API 1 web site. I would like to potentially provide a RESTFUL API for some clients. Ideally I would like to use the same authentication and authorization of the Kentico web site.

My problem is when I try to put Authorize attributes with roles, I always have the same error:

The error message is :

ExceptionMessage: Object type 'cms.class' not found.

ExceptionType: System.InvalidOperationException

StackTrace:

at CMS.DataEngine.ObjectQueryBase\`2.get_Object() at CMS.DataEngine.ObjectQueryBase\`2.get_TypeInfo() at CMS.DataEngine.ObjectQueryBase\`2.GetData() at CMS.DataEngine.DataQueryBase\`1.get_Result() at CMS.DataEngine.DataClassInfoProvider.GetClassStructureInfoFromDB(String className) at CMS.DataEngine.ClassStructureInfo.GetClassInfo(String className) at CMS.DataEngine.AbstractInfoBase\`1.EnsureData(Boolean loadDefault, Boolean applyTypeCondition) at CMS.DataEngine.AbstractInfoBase\`1.get_DataClass() at CMS.DataEngine.AbstractInfoBase\`1.ItemChanged(String columnName) at CMS.DataEngine.AbstractInfoBase\`1.TryGetValue(String columnName, Object& value) at CMS.DataEngine.AbstractInfoBase\`1.GetValue(String columnName) at CMS.DataEngine.DataClassInfoBase\`1.get_ClassShowAsSystemTable() at CMS.DataEngine.DataClassInfo.get_TypeInfo() at CMS.DataEngine.BaseInfo.CheckLicense(ObjectActionEnum action, String domainName) at CMS.DataEngine.AbstractInfoProvider\`3.GetObjectQuery(Boolean checkLicense) at CMS.DataEngine.AbstractInfoProvider\`3.GetDataByColumn[T](String columnName, T value, String columns) at CMS.DataEngine.AbstractInfoProvider\`3.GetInfoByColumn[T](String columnName, T value) at CMS.DataEngine.AbstractInfoProvider\`3.GetInfoByCodeName(String codeName, Boolean useHashtable) at CMS.DataEngine.DataClassInfoProviderBase\`1.GetDataClassInfo(String name) at CMS.DataEngine.QueryInfoProvider.GetFullNameWhereCondition(String fullName) at CMS.DataEngine.AbstractInfoProvider\`3.GetInfoByFullNameInternal(String fullName) at CMS.DataEngine.AbstractInfoProvider\`3.GetInfoByFullName(String fullName, Boolean useHashtable) at CMS.DataEngine.QueryInfoProvider.GetQueryInfoInternal(String queryName) at CMS.DataEngine.QueryInfoProvider.GetQueryInfo(String name, Boolean throwException) at CMS.DataEngine.DataQueryBase\`1.get_FullQueryName() at CMS.DataEngine.DataQueryBase\`1.GetConnectionStringName() at CMS.DataEngine.DataQueryBase\`1.get_ConnectionStringName() at CMS.DataEngine.DataQueryBase\`1.GetDataSourceName() at CMS.DataEngine.WhereConditionBase\`1.get_DataSourceName() at CMS.DataEngine.WhereConditionBase\`1.get_DataSourceName() at CMS.DataEngine.WhereConditionBase\`1.HasCompatibleSource(IDataQuery query) at CMS.DataEngine.WhereConditionBase\`1.WhereIn(String columnName, IDataQuery nestedQuery, Boolean negation) at CMS.SiteProvider.SiteInfoProvider.GetRunningSiteInfoFromDB(String domainName) at CMS.SiteProvider.SiteInfoProvider.GetRunningSiteInfoObject(String domainName) at CMS.SiteProvider.SiteInfoProvider.GetRunningSiteInfoObject(String domainName, String applicationPath) at CMS.SiteProvider.SiteInfoProvider.GetRunningSiteInfo(String domainName, String applicationPath) at CMS.SiteProvider.SiteContext.GetCurrentSiteByDomain() at CMS.SiteProvider.SiteContext.get_CurrentSiteName() at CMS.MembershipProvider.CMSRoleProvider.GetRolesForUser(String username) at System.Web.Security.RolePrincipal.IsInRole(String role) at System.Linq.Enumerable.Any[TSource](IEnumerable\`1 source, Func\`2 predicate) at System.Web.Http.AuthorizeAttribute.IsAuthorized(HttpActionContext actionContext) at System.Web.Http.AuthorizeAttribute.OnAuthorization(HttpActionContext actionContext) at System.Web.Http.Filters.AuthorizationFilterAttribute.OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()

What I've done so far...

1) Read all the following documentation:
Single sign-on

Working with users on MVC sites

...and many others

2) My others tests : SUCCESS = [Authorize(Users="any existing user")] grant access to the action of the controller

SUCCESS = [Authorize(Users="any non existing user")] deny access to the action of the controller

FAILED = [Authorize(Roles= "any role existing or not")]

FAILED = I put this code into an action of my controller (without any authorize attribute):

if (User.Identity.IsAuthenticated)
        {
            CMS.Membership.UserInfo userInfo =  CMS.Membership.UserInfoProvider.GetUserInfo(User.Identity.Name);

            CMS.Membership.AuthenticationHelper.AuthenticateUser(User.Identity.Name, true, false);

            if (User.IsInRole("any role"))  <-- Same error as authorize
            {
                return Ok(_productRepository.GetProductParameters(productId));
            }
        }

I also created a module and I initialize everything in the OnInit:

CMS.DataEngine.ConnectionHelper.ConnectionString = ConnectionHelper.ConnectionString;
CMS.Base.SystemContext.WebApplicationPhysicalPath = AppDomain.CurrentDomain.BaseDirectory;
CMS.DataEngine.CMSApplication.Init();

In the assembly info I also added this line:

[assembly: CMS.AssemblyDiscoverable]

Someone could help me with this?

Thanks in advance!

   Please, sign in to be able to submit a new answer.