diff --git a/Libs/CMS_CORE_Library.dll b/Libs/CMS_CORE_Library.dll index e839b301..433f0e4d 100644 Binary files a/Libs/CMS_CORE_Library.dll and b/Libs/CMS_CORE_Library.dll differ diff --git a/Step/App_Start/Startup.cs b/Step/App_Start/Startup.cs index 159ce205..88789b8c 100644 --- a/Step/App_Start/Startup.cs +++ b/Step/App_Start/Startup.cs @@ -108,7 +108,8 @@ namespace Step.App_Start map.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions() { - Provider = new SignalROAuthBearerProvider() + Provider = new SignalROAuthBearerProvider(), + AuthenticationType = AUTHENTICATION_TYPE }); var hubConfiguration = new HubConfiguration { diff --git a/Step/Attributes/SignalRAuthorizeAttribute.cs b/Step/Attributes/SignalRAuthorizeAttribute.cs index 6a79898c..185ac482 100644 --- a/Step/Attributes/SignalRAuthorizeAttribute.cs +++ b/Step/Attributes/SignalRAuthorizeAttribute.cs @@ -1,14 +1,18 @@ using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Hubs; +using Microsoft.AspNet.SignalR.Owin; +using Step.App_Start; using Step.Config; using Step.Database.Controllers; using Step.Model.DatabaseModels; using System; +using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Security.Principal; using static Step.Config.ServerConfig; using static Step.Model.Constants; +using static Step.Listeners.SignalRStaticObjects; namespace Step.Attributes { @@ -32,75 +36,86 @@ namespace Step.Attributes return base.AuthorizeHubConnection(hubDescriptor, request); } - protected override bool UserAuthorized(IPrincipal user) - { - if (!base.UserAuthorized(user)) - return false; - - // Get Claims from context - ClaimsIdentity identity = user.Identity as ClaimsIdentity; - // Get user id stored in the bearer token - var userId = identity.Claims.FirstOrDefault(c => c.Type == USER_ID_KEY); - - // Get machine unique id stored in the bearer token - var machineId = identity.Claims.FirstOrDefault(c => c.Type == MACHINE_ID_KEY); - - //User data not found -> not authorized - if (userId == null || machineId == null) - return false; - - // User data not found -> not authorized - if (userId == null || machineId == null) - return false; - - // check authorization - if (!CheckAuthorization(Convert.ToInt32(machineId.Value), Convert.ToInt32(userId.Value), FunctionAccess)) - return false; - - return true; - } - public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod) { - return base.AuthorizeHubMethodInvocation(hubIncomingInvokerContext, appliesToMethod); - } - - private bool CheckAuthorization(int machineId, int userId, string functionName) - { - // Check if the machine is the same where the user logged in - if (machineId != MachineConfig.MachineId) - return false; - - MachineUserModel machineUser = new MachineUserModel(); - using (MachinesUsersController machineUsersController = new MachinesUsersController()) + var connectionId = hubIncomingInvokerContext.Hub.Context.ConnectionId; + var request = hubIncomingInvokerContext.Hub.Context.Request; + var token = request.QueryString.Get("Authorization"); + if (!string.IsNullOrEmpty(token)) { - // Find machineUser data and joined to user data, role data, machine data - machineUser = machineUsersController.FindByUserId(machineId, userId); - } - - using (FunctionsAccessController acController = new FunctionsAccessController()) - { - // Read from db function levels - FunctionAccessModel functionAccess = acController.FindEnabledFunctionByName(functionName); - if (functionAccess != null && ServerConfigController.CheckAreaStatus(functionAccess.Area)) - { - if (Action == ACTIONS.READ) - { // Check read permissions - if (functionAccess.ReadLevelMin > machineUser.Role.Level) - return false; // Not authorized - } - else - { // Check write permissions - if (functionAccess.WriteLevelMin > machineUser.Role.Level) - return false; // Not authorized - } - } - else + // check authorization + if (!CheckAuthorization(FunctionAccess, token, out int machineId, out int userId)) return false; - // Authorized + var claims = new ClaimsIdentity(AUTHENTICATION_TYPE); + claims.AddClaim(new Claim(USER_ID_KEY, userId.ToString())); + claims.AddClaim(new Claim(MACHINE_ID_KEY, machineId.ToString())); + + Dictionary _DCI = new Dictionary(); + _DCI.Add("server.User", claims as IPrincipal); + hubIncomingInvokerContext.Hub.Context = new HubCallerContext(new ServerRequest(_DCI), connectionId); return true; } + return false; + } + + private bool CheckAuthorization(string functionName, string token, out int machineId, out int userId) + { + machineId = userId = 0; + using (SessionsController sessionsController = new SessionsController()) + { + // Find user session on this machine + SessionModel session = sessionsController.FindSessionByToken(token); + if (session == null) + return false; + + // Check if the machine is the same where the user logged in + if (session.MachineUser.MachineId != MachineConfig.MachineId) + return false; + + machineId = session.MachineUser.MachineId; + userId = session.MachineUser.UserId; + + MachineUserModel machineUser = new MachineUserModel(); + using (MachinesUsersController machineUsersController = new MachinesUsersController()) + { + // Find machineUser data and joined to user data, role data, machine data + machineUser = machineUsersController.FindByIdWithData(session.MachineUserId); + } + + using (FunctionsAccessController acController = new FunctionsAccessController()) + { + // Read from db function levels + FunctionAccessModel functionAccess = acController.FindEnabledFunctionByName(functionName); + if (functionAccess != null && ServerConfigController.CheckAreaStatus(functionAccess.Area)) + { + if (Action == ACTIONS.READ) + { // Check read permissions + if (functionAccess.ReadLevelMin > machineUser.Role.Level) + return false; // Not authorized + } + else + { // Check write permissions + if (functionAccess.WriteLevelMin > machineUser.Role.Level) + return false; // Not authorized + } + + // Check if PLC bit exists + if (functionAccess.PlcId != 0) + { + // Check if functionality is enabled by PLC + var functionalityIsEnabled = LastRuntimeFunctionality.Where(x => x.Name == functionName).FirstOrDefault(); + if (functionalityIsEnabled == null || functionalityIsEnabled.Enabled == false) + return false; + } + } + else + return false; + + // Authorized + return true; + } + } } } } \ No newline at end of file diff --git a/Step/Attributes/WebApiAuthorizeAttribute.cs b/Step/Attributes/WebApiAuthorizeAttribute.cs index 83e511cd..6410d5f9 100644 --- a/Step/Attributes/WebApiAuthorizeAttribute.cs +++ b/Step/Attributes/WebApiAuthorizeAttribute.cs @@ -19,7 +19,7 @@ namespace Step { public string FunctionAccess; public ACTIONS Action; - protected override bool IsAuthorized(HttpActionContext actionContext) + protected override bool IsAuthorized(HttpActionContext actionContext) { // Get token from headers if (actionContext.Request.Headers.Authorization == null) diff --git a/Step/Provider/SignalROAuthBearerProvider.cs b/Step/Provider/SignalROAuthBearerProvider.cs index e0a28557..3806cbea 100644 --- a/Step/Provider/SignalROAuthBearerProvider.cs +++ b/Step/Provider/SignalROAuthBearerProvider.cs @@ -5,7 +5,7 @@ namespace Step.Provider { public class SignalROAuthBearerProvider : OAuthBearerAuthenticationProvider { - public override Task RequestToken(OAuthRequestTokenContext context) + public override Task RequestToken(OAuthRequestTokenContext context) { var token = context.Request.Query.Get("Authorization");