Free bootstrap template - 추천 무료 부트스트랩 템플릿


관련 자료

https://github.com/ColorlibHQ/AdminLTE

 

ColorlibHQ/AdminLTE

AdminLTE - Free Premium Admin control Panel Theme Based On Bootstrap 3.x - ColorlibHQ/AdminLTE

github.com

https://adminlte.io/

 

Free Bootstrap Admin Template | AdminLTE.IO

Bootstrap is raking over the world and so is React. Therefore, we decided to showcase these outstanding React Bootstrap templates May 20, 2019

adminlte.io

https://github.com/weituotian/AdminLTE-With-Iframe

 

weituotian/AdminLTE-With-Iframe

AdminLTE With Iframe- 基于AdminLTE适合中国国情的网站模版. Contribute to weituotian/AdminLTE-With-Iframe development by creating an account on GitHub.

github.com

https://weituotian.github.io/AdminLTE-With-Iframe/pages/index_iframe.html

 

AdminLTE 2 | with iframe

 

weituotian.github.io

https://themequarry.com/

 

Premium Website Themes & Templates | ThemeQuarry

DETAILS DEMO

themequarry.com



 

 

The MIT License (MIT) 라이센스로 배포가 되고 있는 무료 부트스트랩 템플릿이다. ( 링크

 

[그림] AdminLTE 템플릿 대쉬보드 화면

 

다른 github에서 "weituotian"라는 분이 iframe용으로 탭 네비게이션 관리자 페이지를 만들었다. 탭 네비게이션이 필요한 사람은 이 템플릿을 사용해도 되겠다.

 

[그림] AdminLTE with iframe 대쉬보드 화면

 

CreateProcessAsUser 으로 다른 권한으로 실행하기


관련 자료

https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessasusera

 

CreateProcessAsUserA function (processthreadsapi.h)

Creates a new process and its primary thread. The new process runs in the security context of the user represented by the specified token.

docs.microsoft.com

https://support.microsoft.com/ko-kr/help/165194/createprocessasuser-windowstations-and-desktops

 

https://support.microsoft.com/ko-kr/help/165194/createprocessasuser-windowstations-and-desktops

쿠키가 사용되고 있지 않습니다. 쿠키를 사용하고 페이지를 새로 고치세요.

support.microsoft.com

https://mynotepad.tistory.com/176

 

VIsta 이상 버전에서 Windows Service 에 등록된 프로그램에서 다른 프로그램 띄우기

Windows Vista 이상 버전에서는 세션 관리정책으로 인해서 Windows 의 Service 에 등록된 프로그램이 직접 다른 프로그램을 띄우지 못하게 막았다. 보안상의 이유로 이렇게 한 듯 한데. 이로 인해서 서비스로 등록..

mynotepad.tistory.com

 



 

 

 아래 코드를 통해서 다른 계정의 UI와 권한으로 실행할 수 있다.

 

public class ProcessLauncher
    {
        #region Structures
        [StructLayout(LayoutKind.Sequential)]
        public struct STARTUPINFO
        {
            public Int32 cb;
            public string lpReserved;
            public string lpDesktop;
            public string lpTitle;
            public Int32 dwX;
            public Int32 dwY;
            public Int32 dwXSize;
            public Int32 dwXCountChars;
            public Int32 dwYCountChars;
            public Int32 dwFillAttribute;
            public Int32 dwFlags;
            public Int16 wShowWindow;
            public Int16 cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public Int32 dwProcessID;
            public Int32 dwThreadID;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct SECURITY_ATTRIBUTES
        {
            public Int32 Length;
            public IntPtr lpSecurityDescriptor;
            public bool bInheritHandle;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct ProfileInfo
        {
            public int dwSize;
            public int dwFlags;
            public string lpUserName;
            public string lpProfilePath;
            public string lpDefaultPath;
            public string lpServerName;
            public string lpPolicyPath;
            public IntPtr hProfile;
        }
        #endregion

        #region Enumerations
        public enum SECURITY_IMPERSONATION_LEVEL
        {
            SecurityAnonymous,
            SecurityIdentification,
            SecurityImpersonation,
            SecurityDelegation
        }

        public enum TOKEN_TYPE
        {
            TokenPrimary = 1,
            TokenImpersonation
        }
        #endregion

        #region Constants
        //Use these for DesiredAccess
        private static uint STANDARD_RIGHTS_REQUIRED = 0x000F0000;
        private static uint STANDARD_RIGHTS_READ = 0x00020000;
        private static uint TOKEN_ASSIGN_PRIMARY = 0x0001;
        private static uint TOKEN_DUPLICATE = 0x0002;
        private static uint TOKEN_IMPERSONATE = 0x0004;
        private static uint TOKEN_QUERY = 0x0008;
        private static uint TOKEN_QUERY_SOURCE = 0x0010;
        private static uint TOKEN_ADJUST_PRIVILEGES = 0x0020;
        private static uint TOKEN_ADJUST_GROUPS = 0x0040;
        private static uint TOKEN_ADJUST_DEFAULT = 0x0080;
        private static uint TOKEN_ADJUST_SESSIONID = 0x0100;
        private static uint TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
        private static uint TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID);

        private const int MAXIMUM_ALLOWED = 0x2000000;

        //Process Creation Flags
        private const uint CREATE_UNICODE_ENVIRONMENT = 0x00000400;
        private const uint CREATE_NO_WINDOW = 0x08000000;
        private const uint CREATE_NEW_CONSOLE = 0x00000010;
        private const uint DETACHED_PROCESS = 0x00000008;

        private const UInt32 INFINITE = 0xFFFFFFFF;
        private const UInt32 WAIT_ABANDONED = 0x00000080;
        private const UInt32 WAIT_OBJECT_0 = 0x00000000;
        private const UInt32 WAIT_TIMEOUT = 0x00000102;
        #endregion

        #region Win32 API Imports



        [
           DllImport("kernel32.dll",
              EntryPoint = "CloseHandle", SetLastError = true,
              CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)
        ]
        public static extern bool CloseHandle(IntPtr handle);

        [
           DllImport("advapi32.dll",
              EntryPoint = "CreateProcessAsUser", SetLastError = true,
              CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)
        ]
        public static extern bool
           CreateProcessAsUser(IntPtr hToken, string lpApplicationName, string lpCommandLine,
                               ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes,
                               bool bInheritHandle, uint dwCreationFlags, IntPtr lpEnvrionment,
                               string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo,
                               ref PROCESS_INFORMATION lpProcessInformation);

        [
           DllImport("advapi32.dll",
              EntryPoint = "DuplicateTokenEx")
        ]
        public static extern bool
           DuplicateTokenEx(IntPtr hExistingToken, uint dwDesiredAccess,
                            ref SECURITY_ATTRIBUTES lpThreadAttributes,
                            Int32 ImpersonationLevel, Int32 dwTokenType,
                            ref IntPtr phNewToken);

        [DllImport("advapi32.dll", SetLastError = true)]
        internal static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, ref IntPtr TokenHandle);

        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);

        [DllImport("kernel32.dll")]
        private static extern uint WTSGetActiveConsoleSessionId();

        [DllImport("wtsapi32.dll", SetLastError = true)]
        static extern bool WTSQueryUserToken(UInt32 sessionId, out IntPtr Token);

        [DllImport("kernel32.dll")]
        static extern bool GetExitCodeProcess(IntPtr hProcess, ref int lpExitCode);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);

        [DllImport("userenv.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool CreateEnvironmentBlock(out IntPtr lpEnvironment, IntPtr hToken, bool bInherit);

        [DllImport("userenv.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool DestroyEnvironmentBlock(IntPtr lpEnvironment);

        [DllImport("userenv.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern bool LoadUserProfile(IntPtr hToken, ref ProfileInfo lpProfileInfo);

        [DllImport("Userenv.dll", CallingConvention = CallingConvention.Winapi, SetLastError = true, CharSet = CharSet.Auto)]
        public static extern bool UnloadUserProfile(IntPtr hToken, IntPtr lpProfileInfo);

        #endregion

        public static void Start(ProcessStartInfo processStartInfo)
        {
            var primaryToken = IntPtr.Zero;
            var userToken = IntPtr.Zero;
            var hProcess = IntPtr.Zero;

            var pi = new PROCESS_INFORMATION();
            var sa = new SECURITY_ATTRIBUTES();
            sa.Length = Marshal.SizeOf(sa);

            var profileInfo = new ProfileInfo();
            profileInfo.dwSize = Marshal.SizeOf(profileInfo);
            profileInfo.lpUserName = Environment.UserName;
            profileInfo.dwFlags = 1;


            try
            {
                primaryToken = GetCurrentWinLogonToken();
                userToken = GetCurrentUserToken();
                var si = new STARTUPINFO();
                si.cb = Marshal.SizeOf(si);
                si.lpDesktop = "WinSta0\\Default";
 
                IntPtr lpEnvironment = IntPtr.Zero;
                if (!CreateEnvironmentBlock(out lpEnvironment, GetCurrentUserToken(), false))
                    throw new Win32Exception(Marshal.GetLastWin32Error());

                //if (!LoadUserProfile(userToken, ref profileInfo))
                //    throw new Win32Exception(Marshal.GetLastWin32Error());

                if (!CreateProcessAsUser(
                                            primaryToken,
                                            null,
                                            string.Format("\"{0}\" {1}", processStartInfo.FileName.Replace("\"", "\"\""), processStartInfo.Arguments),
                                            ref sa, ref sa,
                                            false, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, lpEnvironment,
                                            null, ref si, ref pi
                                    ))
                    throw new Win32Exception(Marshal.GetLastWin32Error());

                DestroyEnvironmentBlock(lpEnvironment);

            }
            finally
            {
                if (pi.hProcess != IntPtr.Zero)
                    CloseHandle(pi.hProcess);
                if (pi.hThread != IntPtr.Zero)
                    CloseHandle(pi.hThread);
                if (primaryToken != IntPtr.Zero)
                    CloseHandle(primaryToken);
                //UnloadUserProfile(userToken, profileInfo.hProfile);
            }


        }

        private static IntPtr GetCurrentWinLogonToken()
        {
            int winlogonPid = 0;
            var hToken = IntPtr.Zero;
            var hDupedToken = IntPtr.Zero;
            var hProcess = IntPtr.Zero;

            var sa = new SECURITY_ATTRIBUTES();
            sa.Length = Marshal.SizeOf(sa);
            IntPtr pServer = IntPtr.Zero;

            uint dwSessionId = GetCurrentUserSessionId();

            // obtain the process id of the winlogon process that is running within the currently active session
            Process[] processes = Process.GetProcessesByName("winlogon");
            foreach (Process p in processes)
            {
                if (p.SessionId == dwSessionId)
                {
                    winlogonPid = p.Id;
                }
            }

            // obtain a handle to the winlogon process
            hProcess = OpenProcess(MAXIMUM_ALLOWED, false, winlogonPid);
            if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE, ref hToken))
                throw new Win32Exception(Marshal.GetLastWin32Error());

            if (!DuplicateTokenEx(
                    hToken,
                    TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS,
                    ref sa,
                    (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
                    (int)TOKEN_TYPE.TokenPrimary,
                    ref hDupedToken
                ))
                throw new Win32Exception(Marshal.GetLastWin32Error());

            return hDupedToken;
        }

        private static uint GetCurrentUserSessionId()
        {
            uint dwSessionId = 0;
            using (ITerminalServer localServer = (new TerminalServicesManager()).GetLocalServer())
            {
                foreach (ITerminalServicesSession current in localServer.GetSessions())
                {
                    if (current.ConnectionState == ConnectionState.Active)
                    {
                        dwSessionId = (uint)current.SessionId;
                        break;
                    }
                }
            }

            return dwSessionId;
        }

        private static IntPtr GetCurrentUserToken()
        {
            var hToken = IntPtr.Zero;
            var hDupedToken = IntPtr.Zero;

            var sa = new SECURITY_ATTRIBUTES();
            sa.Length = Marshal.SizeOf(sa);
            IntPtr pServer = IntPtr.Zero;

            uint dwSessionId = GetCurrentUserSessionId();

            if (!WTSQueryUserToken(dwSessionId, out hToken))
                throw new Win32Exception(Marshal.GetLastWin32Error());

            if (!DuplicateTokenEx(
                    hToken,
                    TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS,
                    ref sa,
                    (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
                    (int)TOKEN_TYPE.TokenPrimary,
                    ref hDupedToken
                ))
                throw new Win32Exception(Marshal.GetLastWin32Error());

            return hDupedToken;
        }


    }

[코드] 특정 계정의 토큰 값으로 사용자 계정으로 프로세스 실행하는 코드

BootboxJS — Bootstrap의 모달을 쉽게 컨트롤 하자


관련 자료

http://bootboxjs.com/

 

Bootbox.js — alert, confirm and flexible dialogs for the Bootstrap framework

Bootbox provides three functions, alert, confirm, and prompt, whose aim is to mimic their native JavaScript equivalents. Here’s the simplest possible example: bootbox.alert("Hello world!"); Run example Compare that to the code you’d have to write without B

bootboxjs.com

https://github.com/makeusabrew/bootbox

 

makeusabrew/bootbox

Wrappers for JavaScript alert(), confirm() and other flexible dialogs using Twitter's bootstrap framework - makeusabrew/bootbox

github.com

 



 

 

 

[그림] bootbox logo

 

아래와 같은 코드로 쉽게 Bootstrap의 모달을 사용할 수 있다.

 

[그림] alert 모달 사용 예제 화면

 

 

아래는 웹 페이지에서 jquery와 통합한 소스 ( 홈페이지에 나와 있는 가이드 소스 )

<!-- set up the modal to start hidden and fade in and out -->
<div id="myModal" class="modal fade">
    <div class="modal-dialog">
        <div class="modal-content">
            <!-- dialog body -->
            <div class="modal-body">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                Hello world!
            </div>
            <!-- dialog buttons -->
            <div class="modal-footer"><button type="button" class="btn btn-primary">OK</button></div>
        </div>
    </div>
</div>
        
<!-- sometime later, probably inside your on load event callback -->
<script>
    $("#myModal").on("show", function() {    // wire up the OK button to dismiss the modal when shown
        $("#myModal a.btn").on("click", function(e) {
            console.log("button pressed");   // just as an example...
            $("#myModal").modal('hide');     // dismiss the dialog
        });
    });
        
    $("#myModal").on("hide", function() {    // remove the event listeners when the dialog is dismissed
        $("#myModal a.btn").off("click");
    });
            
    $("#myModal").on("hidden", function() {  // remove the actual elements from the DOM when fully hidden
        $("#myModal").remove();
    });
            
    $("#myModal").modal({                    // wire up the actual modal functionality and show the dialog
        "backdrop"  : "static",
        "keyboard"  : true,
        "show"      : true                     // ensure the modal is shown immediately
    });
</script>

 

bootbox 5.0 부터는 bootstrap 4을 지원한다.

'Javascript' 카테고리의 다른 글

[Javascript] svelte  (0) 2019.12.03
[Javascript] ag-grid  (0) 2019.10.20
Mobx - Simple, scalable state management  (0) 2019.05.11
BootstrapVue  (0) 2019.05.02
브라우저에서 particle을 만들어 보자  (0) 2019.04.19

+ Recent posts