分类:代码

码农是第一生产力。

Spring Boot + Spring Security + Angular 配置

最简单配置

  • 弹出登录对话框
  • 自定义用户名密码

    @Configurable
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        public void configure(HttpSecurity httpSecurity) {
            try {
                httpSecurity.authorizeRequests().anyRequest().authenticated()
                        .and()
                        .httpBasic();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Autowired
        public void ConfigureGlobal(AuthenticationManagerBuilder auth) {
            try {
                auth.inMemoryAuthentication().withUser("root").password("123456").roles("ADMIN");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

自定义 LoginForm

  • 自定义 form 提交地址
  • 认证结果不跳转
  • 登录对话框中,允许资源访问

    @Configurable
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private CustomAuthFailureHandler customAuthFailureHandler;
    
        @Autowired
        private CustomLoginSuccessHandler customLoginSuccessHandler;
    
        @Autowired
        private CustomLogoutSuccessHandler customLogoutSuccessHandler;
    
        Gson gson = new Gson();
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .antMatchers("/login").permitAll()
                        .anyRequest().authenticated()
                        .and()
                    .formLogin()
                        .loginPage("/login").loginProcessingUrl("/auth")
                        .successHandler(customLoginSuccessHandler)
                        .failureHandler(customAuthFailureHandler)
                        .and()
                    .logout().permitAll().logoutSuccessUrl("/logout")
                        .logoutSuccessHandler(customLogoutSuccessHandler)
            ;
            http.csrf().disable();
        }
    
        @Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().regexMatchers(".*\\.js", ".*\\.css", ".*\\.ico", ".*\\.woff2");
        }
    
        @Autowired
        public void ConfigureGlobal(AuthenticationManagerBuilder auth) {
            try {
                auth.inMemoryAuthentication()
                        .withUser("root").password("123456").roles("ADMIN");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        protected class NoRedirectStrategy implements RedirectStrategy {
            @Override
            public void sendRedirect(HttpServletRequest request,
                                     HttpServletResponse response, String url) throws IOException {
                // no redirect
            }
        }
    
        @Component
        public class CustomLoginSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
    
            public CustomLoginSuccessHandler() {
                super();
                setRedirectStrategy(new NoRedirectStrategy());
            }
    
            @Override
            public void onAuthenticationSuccess(HttpServletRequest request,
                                                HttpServletResponse response,
                                                Authentication authentication)
                    throws ServletException, IOException {
                super.onAuthenticationSuccess(request, response, authentication);
                Writer writer = response.getWriter();
                writer.write(gson.toJson("success"));
            }
        }
    
        @Component
        public class CustomAuthFailureHandler extends SimpleUrlAuthenticationFailureHandler {
    
            public CustomAuthFailureHandler() {
                super();
                setRedirectStrategy(new NoRedirectStrategy());
            }
    
            @Override
            public void onAuthenticationFailure(HttpServletRequest request,
                                                HttpServletResponse response,
                                                AuthenticationException exception)
                    throws IOException, ServletException {
                String error = exception.getMessage();
                //getRedirectStrategy().sendRedirect(request, response, "/login?error=" + error);
                Writer writer = response.getWriter();
                writer.write(gson.toJson(error));
            }
        }
    
        @Component
        public class CustomLogoutSuccessHandler implements LogoutSuccessHandler {
            @Override
            public void onLogoutSuccess(HttpServletRequest request,
                                        HttpServletResponse response,
                                        Authentication authentication)
                    throws IOException, ServletException {
                Writer writer = response.getWriter();
                writer.write(gson.toJson("success"));
            }
        }
    }
    

Angular 提交

  • 登录

    onLogin() {
        const url = '/auth';
        // let data = {username: this.username, password: this.password };
        // let data = "username=" + this.username + "&password=" + this.password;
        let params = new URLSearchParams();
        params.set('username', this.username);
        params.set('password', this.password);
    
        let header = {
          headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded'),
        };
    
        this.http.post(url, params.toString(), header).subscribe(
          data => {
            console.log(data);
            if (data != null && data == 'success') {
              this.router.navigateByUrl("/");
            } else {
              let snackBarRef = this.snackBar.open("Login failed. " + data, "CLOSE", {
                duration: 3000
              });
              snackBarRef.onAction().subscribe();
            }
          },
          err => {
            console.log("error: " + err.errorMsg);
          }
        );
      }
    
  • 登出

    logout() {
      this.http.get('/logout').subscribe( data => {
        this.router.navigateByUrl('/login');
      });
    }
    

vscode 编译调试 java 单文件代码

安装

  • Language Support for Java(TM) by Red Hat
  • Java Debug Extension for Visual Studio Code

设置

  • 需要先打开一个目录,以下配置文件生成于该目录的 .vscode 目录下
  • 编译设置

    C-S-p Tasks: Configure Task Runner

    {
        // See https://go.microsoft.com/fwlink/?LinkId=733558
        // for the documentation about the tasks.json format
        "version": "2.0.0",
        "tasks": [
            {
                "taskName": "java build",
                "type": "shell",
                "command": "javac",
                "args": ["-d","${workspaceRoot}","${file}"],
                "group": {
                    "kind": "build",
                    "isDefault": true
                },
                "problemMatcher": {
                    "owner": "java",
                    "fileLocation": ["absolute"],
                    "pattern": {
                        "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error|fatal error):\\s+(.*)$",
                        "file": 1,
                        "line": 2,
                        "column": 3,
                        "severity": 4,
                        "message": 5
                    }
                }
            }
        ]
    }
    
  • 调试设置

    Debug -> Start Debugging

    {
        // Use IntelliSense to learn about possible attributes.
        // Hover to view descriptions of existing attributes.
        // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
        "version": "0.2.0",
        "configurations": [
            {
                "type": "java",
                "name": "Debug (Launch)",
                "request": "launch",
                "sourcePaths": [
                    "$(workspaceRoot)"
                ],
                "classPaths": [
                    "",            
                    "$(workspaceRoot)"
                ],
                "mainClass": "${fileBasenameNoExtension}",
                "args": ""
            },
            {
                "type": "java",
                "name": "Debug (Attach)",
                "request": "attach",
                "hostName": "localhost",
                "port": 0
            }
        ]
    }
    

快捷键

  • 编译 C-S-b
  • 调试 F5

vscode 编译调试 C++ 单文件代码

安装

  • 安装 vscode
  • 安装插件 c/c++ c/c++ snippets

设置

  • 需要先打开一个目录,以下配置文件生成于该目录的 .vscode 目录下
  • IntelliSense 设置

    C-S-p c/cpp: Edit Configurations..

    {
        "configurations": [
            {
                "name": "Win32",
                "includePath": [
                    "D:/mingw540-x64/x86_64-w64-mingw32/include/c++",
                    "${workspaceRoot}"
                ],
                "defines": [
                    "_DEBUG",
                    "UNICODE"
                ],
                "intelliSenseMode": "msvc-x64",
                "browse": {
                    "path": [
                        "D:/mingw540-x64/x86_64-w64-mingw32/include/c++",
                        "${workspaceRoot}"
                    ],
                    "limitSymbolsToIncludedHeaders": true,
                    "databaseFilename": ""
                }
            }
        ],
        "version": 3
    }
    
  • 编译设置

    C-S-p Tasks: Configure Task Runner

    {
        // See https://go.microsoft.com/fwlink/?LinkId=733558
        // for the documentation about the tasks.json format
        "version": "2.0.0",
        "tasks": [
            {
                "taskName": "g++ build",
                "type": "shell",
                "command": "g++.exe",
                "args": ["-g","${file}","-o","${file}.exe", "-std=c++1y"], 
                "group": {
                    "kind": "build",
                    "isDefault": true
                },
                "problemMatcher": {
                    "owner": "cpp",
                    "fileLocation": ["absolute"],
                    "pattern": {
                        "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error|fatal error):\\s+(.*)$",
                        "file": 1,
                        "line": 2,
                        "column": 3,
                        "severity": 4,
                        "message": 5
                    }
                }
            },
            {
                "taskName": "clang++ build",
                "type": "shell",
                "command": "clang++.exe",
                "args": ["-target", "x86_64-pc-windows-gnu", "-g","${file}","-o","${file}.exe", "-std=c++1y"], 
                "group": {
                    "kind": "build",
                    "isDefault": true
                },
                "problemMatcher": {
                    "owner": "cpp",
                    "fileLocation": ["absolute"],
                    "pattern": {
                        "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error|fatal error):\\s+(.*)$",
                        "file": 1,
                        "line": 2,
                        "column": 3,
                        "severity": 4,
                        "message": 5
                    }
                }
            }
        ]
    }
    
  • 调试设置

    Debug -> Start Debugging

    {
            "version": "0.2.0",
            "configurations": [
                {
                    "name": "(gdb) Launch",
                    "type": "cppdbg",
                    "request": "launch",
                    "program": "${file}.exe",
                    "args": [],
                    "stopAtEntry": false,
                    "cwd": "${workspaceRoot}",
                    "environment": [],
                    "externalConsole": true,
                    "MIMode": "gdb",
                    "miDebuggerPath": "gdb.exe",
                    "setupCommands": [
                        {
                            "description": "Enable pretty-printing for gdb",
                            "text": "-enable-pretty-printing",
                            "ignoreFailures": true
                        }
                    ]
                }
            ]
        }
    

快捷键

  • 编译 C-S-b
  • 调试 F5

ubuntu16.04 修改 pthread 库的 PTHREAD_KEYS_MAX 宏定义

编译说明

  • pthread 是 glibc 的子库,需要编译整个 glibc。
  • 需要安装编译套件 gcc, make 等工具。

编译 glibc

  • 查看 glibc 当前版本

    $ /lib/x86_64-linux-gnu/libc.so.6
    GNU C Library (Ubuntu GLIBC 2.23-0ubuntu9) stable release version 2.23, by Roland McGrath et al.
    Copyright (C) 2016 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.
    There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
    PARTICULAR PURPOSE.
    Compiled by GNU CC version 5.4.0 20160609.
    Available extensions:
            crypt add-on version 2.1 by Michael Glad and others
            GNU Libidn by Simon Josefsson
            Native POSIX Threads Library by Ulrich Drepper et al
            BIND-8.2.3-T5B
    libc ABIs: UNIQUE IFUNC
    For bug reporting instructions, please see:
    <https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
    
  • 下载 glibc-2.23

    apt install axel
    axel -n 10 http://ftp.gnu.org/gnu/glibc/glibc-2.23.tar.bz2
    tar xjf glibc-2.23.tar.bz2
    
  • 修改 PTHREAD_KEYS_MAX 宏大小
    • 不能改太大,改成 10240 创建线程时会崩溃
    • 仅修改相关 PC 体系下的头文件,如下是修改完的

      $ cd /home/share/glibc-2.23
      $ ag "define PTHREAD_KEYS_MAX"
      glibc-2.23/sysdeps/unix/sysv/linux/aarch64/bits/local_lim.h
      65:#define PTHREAD_KEYS_MAX     2048
      
      glibc-2.23/sysdeps/unix/sysv/linux/bits/local_lim.h
      64:#define PTHREAD_KEYS_MAX     2048
      
      glibc-2.23/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h
      64:#define PTHREAD_KEYS_MAX     1024
      
      glibc-2.23/sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h
      64:#define PTHREAD_KEYS_MAX     1024
      
      glibc-2.23/sysdeps/unix/sysv/linux/mips/bits/local_lim.h
      64:#define PTHREAD_KEYS_MAX     1024
      
      glibc-2.23/sysdeps/unix/sysv/linux/ia64/bits/local_lim.h
      64:#define PTHREAD_KEYS_MAX     1024
      
      glibc-2.23/sysdeps/unix/sysv/linux/tile/bits/local_lim.h
      64:#define PTHREAD_KEYS_MAX     1024
      
      glibc-2.23/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h
      64:#define PTHREAD_KEYS_MAX     1024
      
      glibc-2.23/sysdeps/nacl/bits/local_lim.h
      29:#define PTHREAD_KEYS_MAX        2048
      
  • 编译 glibc-2.23

    apt install gawk
    mkdir build
    cd build
    ../configure CC=gcc --disable-sanity-checks
    

安装前的准备

  • 查看 pthread 所在目录

    $ locate pthread.so
    /lib/x86_64-linux-gnu/libpthread.so.0
    /usr/lib/x86_64-linux-gnu/libpthread.so
    /usr/lib/x86_64-linux-gnu/samba/vfs/aio_pthread.so
    
  • 查看运行库

    $ cd /lib/x86_64-linux-gnu/
    $ l *pthread*
    -rwxr-xr-x 1 root root 136K Jun 17 04:57 libpthread-2.23.so
    lrwxrwxrwx 1 root root   18 Jun 17 04:57 libpthread.so.0 -> libpthread-2.23.so
    
  • 查看链接库

    $ cd /usr/lib/x86_64-linux-gnu
    $ l *pthread*
    -rw-r--r-- 1 root root 2.4M Jun 17 04:52 libpthread.a
    -rw-r--r-- 1 root root 7.6K Jun 17 04:52 libpthread_nonshared.a
    -rw-r--r-- 1 root root  252 Jun 17 04:52 libpthread.so
    
  • 查看头文件位置

    $ locate local_lim.h
    /usr/include/x86_64-linux-gnu/bits/local_lim.h
    

替换链接库

  • 备份链接库

    cd /usr/lib/x86_64-linux-gnu
    mv libpthread.so libpthread.so.bak
    mv libpthread.a libpthread.a.bak
    mv libpthread_nonshared.a libpthread_nonshared.a.bak
    
  • 替换链接库 编译完成后记得还原

    cd /usr/lib/x86_64-linux-gnu
    cp /home/share/glibc-2.23/glibc-2.23/build/nptl/libpthread.so .
    cp /home/share/glibc-2.23/glibc-2.23/build/nptl/libpthread.a .
    cp /home/share/glibc-2.23/glibc-2.23/build/nptl/libpthread_nonshared.a .
    

替换运行库

  • 备份运行库
    • 部分 shell 命令依赖 libpthread.so.0,如 cp,mv。

      cd /lib/x86_64-linux-gnu/
      cp libpthread.so.0 libpthread.so.0.bak
      
    • ln 仍然可用,可用于紧急情况下恢复。

      ln -s -f libpthread-2.23.so libpthread.so.0 
      
  • 替换运行库
    • 放到执行目录下

      export LD_LIBRARY_PATH=./
      cd /home/share/glibc-2.23/glibc-2.23/build/nptl
      cp *.so* /var/data/testprogram
      
    • 放到系统目录下 危险,尽量不要使用这种方法

      cd /lib/x86_64-linux-gnu/
      cp /home/share/glibc-2.23/glibc-2.23/build/nptl/libpthread.so libpthread.spider.so
      ln -s -f libpthread.spider.so libpthread.so.0
      
  • 修改头文件 编译完成后记得还原

    vim /usr/include/x86_64-linux-gnu/bits/local_lim.h
    #define PTHREAD_KEYS_MAX 10240
    

flex 布局

浏览器版本支持

  • chrome 21, opera 12.1, firefox 22, safari 6.1, ie 10

指定 flex 布局

  • 块元素 display: flex;
  • 行内元素 display: inline-flex;
  • webkit 内核 display: -webkit-flex display: -webkit-inline-flex
  • 影响设置 flex 而已后, float , clear , vertcal-align 都失效

窗口属性

  • flex-direction row | row-reverse | column | column-reverse
  • flex-wrap nowrap | wrap | wrap-reverse
  • flex-flow <flex-direction> || <flex-wrap>
  • justify-content flex-start | flex-end | center | space-between | space-around
  • align-items flex-start | flex-end | center | baseline | stretch
  • align-content flex-start | flex-end | center | space-between | space-around | stretch

元素属性

  • order <integer>
  • flex-grow <number> /*default 0*/
  • flex-shrink <number> /*default 0*/
  • flex-basis <number | auto /*default auto*/
  • flex none | [ <flex-grow> <flex-shrink>? || <flex-basis> ]
  • align-self auto | flex-start | flex-end | center | baseline | stretch