/// <summary>
        /// Renders the error response.
        /// </summary>
        public Task RenderErrorResponse(HttpContext context, Exception error)
        {
            context.Response.ContentType = "text/html";

            try
            {
                var text = (Formatter ?? (Formatter = ErrorFormatter.CreateDefault()))
                           .ErrorHtml(error, DotvvmMiddleware.ConvertHttpContext(context));
                return(context.Response.WriteAsync(text));
            }
            catch (Exception exc)
            {
                context.Response.ContentType = "text/plain";
                try
                {
                    using (var writer = new StreamWriter(context.Response.Body))
                    {
                        writer.WriteLine("Error in Dotvvm Application:");
                        writer.WriteLine(error.ToString());
                        writer.WriteLine();
                        writer.WriteLine("Error occured while displaying the error page. This it s internal error and should not happend, please report it:");
                        writer.WriteLine(exc.ToString());
                    }
                }
                catch { }
                throw new Exception("Error occured inside dotvvm error handler, this is internal error and should not happen; \n Original error:" + error.ToString(), exc);
            }
        }
Example #2
0
        /// <summary>
        /// Builds the view model for the client.
        /// </summary>
        public void BuildViewModel(DotvvmRequestContext context)
        {
            // serialize the ViewModel
            var serializer         = CreateJsonSerializer();
            var viewModelConverter = new ViewModelJsonConverter(context.IsPostBack)
            {
                UsedSerializationMaps = new HashSet <ViewModelSerializationMap>()
            };

            serializer.Converters.Add(viewModelConverter);
            var writer = new JTokenWriter();

            serializer.Serialize(writer, context.ViewModel);

            // persist CSRF token
            writer.Token["$csrfToken"] = context.CsrfToken;

            // persist encrypted values
            if (viewModelConverter.EncryptedValues.Count > 0)
            {
                writer.Token["$encryptedValues"] = viewModelProtector.Protect(viewModelConverter.EncryptedValues.ToString(Formatting.None), context);
            }

            // serialize validation rules
            var validationRules = SerializeValidationRules(viewModelConverter);

            // create result object
            var result = new JObject();

            result["viewModel"]        = writer.Token;
            result["url"]              = context.OwinContext.Request.Uri.PathAndQuery;
            result["virtualDirectory"] = DotvvmMiddleware.GetVirtualDirectory(context.OwinContext);
            if (context.IsPostBack || context.IsSpaRequest)
            {
                result["action"] = "successfulCommand";
                var renderedResources = new HashSet <string>(context.ReceivedViewModelJson?["renderedResources"]?.Values <string>() ?? new string[] { });
                result["resources"] = BuildResourcesJson(context, rn => !renderedResources.Contains(rn));
            }
            else
            {
                result["renderedResources"] = JArray.FromObject(context.ResourceManager.RequiredResources);
            }
            // TODO: do not send on postbacks
            if (validationRules.Count > 0)
            {
                result["validationRules"] = validationRules;
            }

            context.ViewModelJson = result;
        }
Example #3
0
        /// <summary>
        /// Renders the error response.
        /// </summary>
        public Task RenderErrorResponse(IOwinContext context, Exception error)
        {
            context.Response.ContentType = "text/html";

            try
            {
                var text = (Formatter ?? (Formatter = ErrorFormatter.CreateDefault()))
                           .ErrorHtml(error, DotvvmMiddleware.ConvertHttpContext(context));
                return(context.Response.WriteAsync(text));
            }
            catch (Exception exc)
            {
                throw new Exception("Error occured inside dotvvm error handler, this is internal error and should not happen; \n Original error:" + error.ToString(), exc);
            }
        }
Example #4
0
        /// <summary>
        /// Renders the error response.
        /// </summary>
        public Task RenderErrorResponse(HttpContext context, Exception error)
        {
            try
            {
                context.Response.ContentType = "text/html";

                var text = (Formatter ?? (Formatter = CreateDefaultWithDemystifier()))
                           .ErrorHtml(error, DotvvmMiddleware.ConvertHttpContext(context));
                return(context.Response.WriteAsync(text));
            }
            catch (Exception exc)
            {
                return(RenderFallbackMessage(context, error, exc));
            }
        }
Example #5
0
        private string GetCorrectSpaUrlPrefix(IDotvvmRequestContext context)
        {
            var routePath = "";

            if (!string.IsNullOrEmpty(PrefixRouteName))
            {
                routePath = context.Configuration.RouteTable[PrefixRouteName].Url.Trim('/');
            }
            else
            {
                return(null);
            }

            var result = DotvvmMiddleware.GetVirtualDirectory(context.OwinContext);

            if (!string.IsNullOrEmpty(routePath))
            {
                result += "/" + routePath;
            }
            return(result);
        }
Example #6
0
        private static void ConfigureAADAuthentication(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                Authority                 = $"https://login.microsoftonline.com/{ConfigurationManager.AppSettings["ida:TenantId"]}/",
                ClientId                  = ConfigurationManager.AppSettings["ida:ClientId"],
                AuthenticationMode        = AuthenticationMode.Passive,
                TokenValidationParameters = new TokenValidationParameters()
                {
                    ValidateIssuer = (ConfigurationManager.AppSettings["ida:TenantId"] != "common")
                },
                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    RedirectToIdentityProvider = context =>
                    {
                        // determines the base URL of the application (useful when the app can run on multiple domains)
                        var appBaseUrl = GetApplicationBaseUrl(context.Request);

                        if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.AuthenticationRequest)
                        {
                            context.ProtocolMessage.RedirectUri = appBaseUrl;
                            // we need to handle the redirect to the login page ourselves because redirects cannot use HTTP 302 in DotVVM
                            var redirectUri = context.ProtocolMessage.CreateAuthenticationRequestUrl();
                            DotvvmRequestContext.SetRedirectResponse(DotvvmMiddleware.ConvertHttpContext(context.OwinContext), redirectUri, (int)HttpStatusCode.Redirect, true);
                            context.HandleResponse();
                        }
                        else if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
                        {
                            context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
                            // we need to handle the redirect to the logout page ourselves because redirects cannot use HTTP 302 in DotVVM
                            var redirectUri = context.ProtocolMessage.CreateLogoutRequestUrl();
                            DotvvmRequestContext.SetRedirectResponse(DotvvmMiddleware.ConvertHttpContext(context.OwinContext), redirectUri, (int)HttpStatusCode.Redirect, true);
                            context.HandleResponse();
                        }

                        return(Task.FromResult(0));
                    },
                    SecurityTokenValidated = context =>
                    {
                        var isMultiTenant = ConfigurationManager.AppSettings["ida:TenantId"] == "common";
                        if (isMultiTenant)
                        {
                            // validate allowed tenants
                            var tenants     = ConfigurationManager.AppSettings["ida:Tenants"].Split(',');
                            var tokenTenant = context.AuthenticationTicket.Identity.FindFirstValue(AzureAdClaimTypes.TenantId);
                            if (!tenants.Contains(tokenTenant))
                            {
                                throw new SecurityTokenValidationException($"Tenant {tokenTenant} is not allowed to sign in to the application!");
                            }
                        }

                        // create user if it doesn't exists
                        var upn  = context.AuthenticationTicket.Identity.FindFirstValue(AzureAdClaimTypes.Upn);
                        var user = LoginHelper.GetClaimsIdentityForAzure(upn);
                        if (user == null)
                        {
                            var newUser = new UserInfoData
                            {
                                Email     = context.AuthenticationTicket.Identity.FindFirstValue(AzureAdClaimTypes.Upn),
                                FirstName = context.AuthenticationTicket.Identity.FindFirstValue(AzureAdClaimTypes.GivenName),
                                LastName  = context.AuthenticationTicket.Identity.FindFirstValue(AzureAdClaimTypes.Surname),
                                Name      = context.AuthenticationTicket.Identity.FindFirstValue(AzureAdClaimTypes.DisplayName),
                                UserRole  = UserRole.User,
                                Password  = new Guid().ToString()
                            };
                            UserService.CreateOrUpdateUserInfo(newUser);

                            // create identity for the new user
                            user = LoginHelper.GetClaimsIdentityForAzure(upn);
                        }

                        context.AuthenticationTicket = new AuthenticationTicket(user, context.AuthenticationTicket.Properties);

                        return(Task.FromResult(0));
                    }
                }
            });
        }