- VisualStudio2022
- pprof-Hướng dẫn sử dụng nó trong bản mạng trực tiếp
- Triển khai C# các loại hộp chọn nhiều màu lựa chọn thả xuống, cây lựa chọn nhiều màu lựa chọn thả xuống và các nút tối đa
- [Ghi chú học tập] Cơ sở dữ liệu cấu trúc: cat tree
Trong bài đăng trên blog trước "Hướng dẫn nâng cao SpringBoot (80) Spring Security", chúng tôi đã giới thiệu cách sử dụng xác thực formLogin, xác thực HttpBasic và tên người dùng và mật khẩu tùy chỉnh trong Spring Security. Trong bài viết này, chúng tôi sẽ giới thiệu phương pháp xác minh đăng nhập của giao diện đăng nhập tùy chỉnh. Trong bài đăng blog trước "Hướng dẫn nâng cao SpringBoot (81) Xác thực tùy chỉnh bảo mật mùa xuân", chúng tôi đã giới thiệu cách triển khai xác thực tùy chỉnh Bảo mật mùa xuân.
<sự phụ thuộc> <ID nhóm>org.springframework.socialID nhóm> <ID tạo tác>spring-social-configID tạo tác> <phiên bản>1.1.6.PHÁT HÀNHphiên bản> sự phụ thuộc>
/** * @Tác giả chen bo * @Date 2023/12 * @Des */ @Data công cộng lớp học Mã hình ảnh { /** * hình ảnh hình ảnh */ Riêng tư Hình ảnh BufferedImage; /** * Mã xác minh */ Riêng tư Mã chuỗi; /** * Thời gian hết hạn */ Riêng tư LocalDateTime hết hạn; công cộng ImageCode(Hình ảnh đệm, Mã chuỗi, int hết hạnTrong) { cái này.hình ảnh = hình ảnh; cái này.code = mã số; cái này.thời gian hết hạn = LocalDateTime.now().plusSeconds(expireIn }); /** * Xác định xem mã xác minh đã hết hạn chưa * @trở lại */ công cộng boolean isExpir() { trở lại LocalDateTime.now().isAfter(expireTime); } }
Viết giao diện để trả về mã xác minh đồ họa:
/** * @Tác giả chen bo * @Date 2023/12 * @Des */ @RestController công cộng lớp học Trình điều khiển hình ảnh { công cộng cuối cùng tĩnh Chuỗi SESSION_KEY_IMAGE_CODE = "SESSION_VERIFICATION_CODE"; Riêng tư PhiênChiến lược phiênChiến lược = mới HttpSessionSessionStrategy(); @GetMapping("/mã/hình ảnh") công cộng trống rỗng createCode(yêu cầu HttpServletRequest, phản hồi HttpServletResponse) ném IOException { Mã hình ảnh Mã hình ảnh = createImageCode(); sessionStrategy.setAttribution(mới ServletWebRequest(yêu cầu), SESSION_KEY_IMAGE_CODE, imageCode); ImageIO.write(imageCode.getImage(), "jpeg", phản hồi.getOutputStream()); } Riêng tư Mã hình ảnh createImageCode() { // Chiều rộng hình ảnh mã xác minh int chiều rộng = 100; // Độ dài hình ảnh mã xác minh int chiều cao=36; // Số chữ số mã xác minh int chiều dài = 4; // Mã xác minh có hiệu lực trong 60 giây int hết hạnTrong = 60; = mới BufferedImage(chiều rộng, chiều cao, BufferedImage.TYPE_INT_RGB); = image.getGraphics(); = mới Ngẫu nhiên(); đồ họa.setColor(getRandColor(200, 500)); đồ họa.fillRect(0, 0, chiều rộng, chiều cao);mới Font("Time New Roman", Font.ITALIC, 20)); đồ họa.setColor(getRandColor(160, 200)); vì (int tôi = 0; tôi < 155;) { int x = ngẫu nhiên.nextInt(width); int y = ngẫu nhiên.nextInt(chiều cao); int xl = ngẫu nhiên.nextInt(12); int yl = ngẫu nhiên.nextInt(12); đồ họa.drawLine(x, y, x +xl,y+ yl); } StringBuilder sRand = mới StringBuilder(); vì (int tôi = 0; tôi < chiều dài;) { Chuỗi rand = String.valueOf(random.nextInt(10)); sRand.append(rand);mới Màu(20 + Random.nextInt(110), 20 + Random.nextInt(110), 20 + Random.nextInt(110))); đồ họa.drawString(rand, 13*i+6,16); } đồ họa.dispose(); trở lại mới ImageCode(image, sRand.toString(), ExpiryIn }); Riêng tư Màu getRandColor(int fc, int bc) { Ngẫu nhiên ngẫu nhiên = mới Ngẫu nhiên(); if if (fc > 255)fc = 255; if if (bc > 255) bc = 255; int r = fc + Random.nextInt(bc - fc); int g = fc + Random.nextInt(bc - fc); int b = fc + Random.nextInt(bc - fc); trở lại mới Màu(r, g, b);
Đối tượng org.springframework.social.connect.web.HttpSessionSessionStrategy đóng gói một số phương thức để xử lý Session, bao gồm các phương thức setAttribution, getAttribution và RemoveAttribution. Bạn có thể xem mã nguồn của lớp này để biết chi tiết. Sử dụng sessionStrategy để lưu trữ đối tượng mã xác minh đã tạo trong Phiên và xuất hình ảnh được tạo ra trang đăng nhập thông qua luồng IO.
Trong "Trang đăng nhập biểu mẫu viết lại" trong bài đăng blog trước "Hướng dẫn nâng cao SpringBoot (81) Xác thực tùy chỉnh bảo mật mùa xuân", login.html đã được tạo và đoạn mã sau đã được thêm vào login.html:
<nhịp phong cách="hiển thị: nội tuyến"> <đầu vào kiểu="văn bản" tên="Vui lòng nhập mã xác minh" phần giữ chỗ="Mã xác minh" yêu cầu="bắt buộc"/> <hình ảnh src="/mã/hình ảnh"/> nhịp>
Thuộc tính src của thẻ img tương ứng với phương thức createImageCode của ImageController.
Trong quá trình xác minh mã xác minh, nhiều ngoại lệ loại mã xác minh khác nhau có thể được đưa ra, chẳng hạn như "Lỗi mã xác minh", "Mã xác minh đã hết hạn", v.v., vì vậy chúng tôi xác định một loại ngoại lệ của loại mã xác minh:
/** * @Tác giả chen bo * @Date 2023/12 * @Des */ công cộng lớp học Xác thựcCodeException mở rộng Ngoại lệ xác thực { Riêng tư tĩnh cuối cùng dài nối tiếpVersionUID = 1715361291615299823L; công cộng ValidateCodeException(Giải thích chuỗi) { siêu(giải thích); } }
Lưu ý: Ngoại lệ xác thực được kế thừa ở đây thay vì Ngoại lệ.
Spring Security thực chất là một chuỗi bộ lọc bao gồm nhiều bộ lọc. Bộ lọc xử lý logic đăng nhập của người dùng là UsernamePasswordAuthenticationFilter và quy trình xác minh mã xác minh phải diễn ra trước bộ lọc này, tức là chỉ sau khi xác minh mã xác minh vượt qua Xác minh tên người dùng và mật khẩu. Vì Spring Security không trực tiếp cung cấp giao diện bộ lọc liên quan đến xác minh mã xác minh, nên chúng ta cần tự xác định bộ lọc xác minh mã xác minh: ValidateCodeFilter:
/** * @Tác giả chen bo * @Date 2023/12 * @Des */ @Thành phần công cộng lớp học Xác thựcCodeFilter mở rộng Một lầnPerRequestFilter { @Autowired Riêng tư MyAuthenticationFailureHandler myAuthenticationFailureHandler; Riêng tư PhiênChiến lược phiênChiến lược = mới HttpSessionSessionStrategy(); được bảo vệ trống rỗng doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) ném ServletException, IOException { if if ("/đăng nhập".equalsIgnoreCase(httpServletRequest.getRequestURI()) && "bưu kiện".equalsIgnoreCase(httpServletRequest.getMethod())) { thử { mã xác thực(mới ServletWebRequest(httpServletRequest)); } lấy được (ValidateCodeException e) { myAuthenticationFailureHandler.onAuthenticationFailure(httpServletRequest, httpServletResponse, e); trở lại; } } filterChain.doFilter(httpServletRequest, httpServletResponse } Riêng tư trống rỗng xác thựcCode(ServletWebRequest servletWebRequest) ném ServletRequestBindingException, ValidateCodeException { Mã hình ảnh codeInSession = (ImageCode) sessionStrategy.getAttribution(servletWebRequest, ImageController.SESSION_KEY_IMAGE_CODE); Chuỗi codeInRequest); = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), "imageCode"); if if (StringUtils.isEmpty(codeInRequest)) { ném mới ValidateCodeException("Mã xác minh không được để trống!"); } if if (codeInSession == vô giá trị) { ném mới ValidateCodeException("Mã xác minh không tồn tại!"); } if if (codeInSession.isExpire()) { sessionStrategy.removeAttribution(servletWebRequest, ImageController.SESSION_KEY_IMAGE_CODE); ném mới ValidateCodeException("Mã xác minh đã hết hạn!"); } if if (!codeInRequest.equalsIgnoreCase(codeInSession.getCode())) { ném mới ValidateCodeException("Xác minh sai!"); } sessionStrategy.removeAttribution(servletWebRequest, ImageController.SESSION_KEY_IMAGE_CODE);
ValidateCodeFilter kế thừa org.springframework.web.filter.OncePerRequestFilter, sẽ chỉ được thực thi một lần. được thực thi một lần.
Trong phương thức doFilterInternal, chúng tôi xác định URL xem yêu cầu phải là /đăng nhập hay không. hành động của biểu mẫu đăng nhập hoặc không. Nếu vậy, hãy thực hiện logic xác minh mã xác minh. trực tiếp filterChain.doFil. để mã hóa tiếp tục. của Spring Security AuthenticationFailureHandler sẽ được gọi để xử lý.
ImageCode và yêu cầu tham số imageCode from Session (tương ứng với thuộc tính tên của hộp mã xác minh trên trang đăng nhập), sau đó đưa ra nhiều dự đoán khác nhau và đưa ra các ngoại lệ tương ứng Khi mã xác thực hết hạn hoặc mã xác thực đã vượt qua, chúng tôi có thể xóa thuộc tính ImageCode trong Session.
Bộ lọc mã xác thực đã được xác định, làm cách nào để thêm nó vào trước UsernamePasswordAuthenticationFilter? cần bổ sung một số cấu hình trong cấu hình phương thức của BrowserSecurityConfig. để không bị chặn: "/code/image".
/** * @Tác giả chen bo * @Date 2023/12 * @Des */ @Cấu hình công cộng lớp học Bảo mật cấu hình mở rộng WebSecurityConfigurerAdapter { @Override được bảo vệ trống rỗng cấu hình(HttpSecurity http) ném Exception { http.addFilterBefore(mới Xác thựcCodeFilter(), Tên người dùngPasswordAuthenticationFilter.lớp học) //Thêm bộ lọc xác thực mã xác thực .formĐăng nhập() // biểu tượng đăng nhập mẫu .loginPage("/login.html") // Url nhảy đăng nhập // .loginPage("/xác thực/yêu cầu") .loginProcessingUrl("/đăng nhập") // Xử lý mẫu đăng nhập url // .successHandler(xác thựcSuccessHandler) .failureHandler(mới MyAuthenticationFailureHandler()) .and() .authorizeRequests() // Quyền cấu hình .antMatchers("/login.html", "/css/**", "/authentication/require", "/code/image").permitAll() // Không cần chứng minh .anyRequest() // Tất cả các yêu cầu .đã được xác thực() // Tất cả đều được yêu cầu chứng nhận .and().csrf().disable(); } @Bean công cộng Mật khẩuBộ mã hóa mật khẩuBộ mã hóa() { trở lại mới BCryptPasswordEncoding();
ValidateCodeFilter trước UsernamePasswordAuthenticationFilter thông tin qua phương thức addFilterBefore.
Tài liệu tham khảo/học tập khác:
https://github.com/toutouge/javademosecond/tree/master/security-demo.
Tác giả: Hãy gọi tôi là Anh Toutou Nguồn: http://www.cnblogs.com/toutou/ Về tác giả: Tập trung phát triển dự án trên cơ sở nền tảng nền tảng. Nếu bạn có bất kỳ câu hỏi hoặc mẹo nào, xin vui lòng cho tôi biết! Tuyên bố về bản quyền: Bản quyền của bài viết này! thuộc về tác giả và việc in lại được hoan nghênh, nhưng tuyên bố này phải được giữ lại mà không có đồng ý Xin cam đoan: Mọi người thảo luận, tin nhắn riêng tư sẽ được phản hồi trong thời gian sớm nhất. sửa lỗi cân bằng và cùng tiến trình. đối với bạn, bạn có thể ấn vào [Dề xuất] ở góc dưới bên phải bài viết. lớn nhất để thực hiện sáng tạo và viết không ngừng!
Cuối cùng, bài viết này về Hướng dẫn nâng cao SpringBoot (82) Mã xác minh đồ họa SpringSecurity kết thúc ở đây. Spring Boot (82) Spring Security, vui lòng tìm kiếm các bài viết CFSDN hoặc tiếp tục duyệt qua các bài viết liên hệ quan. sẽ hỗ trợ blog của tôi trong tương lai .
MySQL (nâng cao) 1. MySQL (nâng cao) sử dụng NOT NULL để xác định rằng cột không trống tên varchar(20) không null, đặc biệt buộc phải duy nhất UNIQUE
Đa luồng (nâng cao) 1. Chiến lược khóa thông thường 1.1 Khóa lạc quan Khóa bi quan Khóa tối ưu: Luôn giả sử tình huống tốt nhất Mỗi khi bạn đi lấy dữ liệu, bạn nghĩ rằng người khác sẽ không sửa đổi dữ liệu, nhưng khi bạn gửi bản cập nhật dữ liệu. và sau đó đánh giá xem có ai khác đã sửa dữ liệu trong khoảng thời gian này hay không.
Tôi tin vào một hệ thống được mã hóa chính xác - không thể xảy ra lỗi (như lỗi hoặc ngoại lệ) (lỗi máy chủ DB/memcached khiến truy vấn không thành công). Mã của chúng tôi không nên dựa vào bất kỳ giả định nào để hoạt động bình thường và phải được chứng minh là đúng bất cứ khi nào có thể. Nhưng để chắc chắn rằng tôi
1. Giới thiệu Mã chung cho phép bạn viết các hàm linh hoạt, có thể tái sử dụng, có thể sử dụng cho bất kỳ loại nào theo yêu cầu bạn xác định. Bạn có thể viết mã có thể tái sử dụng, có mục đích rõ ràng và trừu tượng. Generics là mạnh nhất của Swift
1. Tạo cấu hình chất lượng và các dự án liên quan 1. Tạo cấu hình chất lượng mã java mới 2. Thêm quy tắc vào cấu hình và xác nhận rằng có 4 quy tắc Thay đổi cấu hình quét cho dự án 2. Tạo ngưỡng chất lượng liên quan đến dự án 1.
Để biết cấu hình jenkinsfile, sharelibrary và jenkins hoàn chỉnh, hãy xem phần cuối cùng. Tự động khớp các nhánh đẩy gitlab 1. Thêm các tham số trình cắm Webhook chung để lấy thông tin nhánh được gửi lần này.
1. Tạo một ứng dụng mới trong gitlab 2. Cài đặt plugin gitlab trong jenkins 3. Sau khi cài đặt plugin, hãy sử dụng nó trong cấu hình bảo mật toàn cầu và định cấu hình xác thực gitlab 4. Tự động sử dụng thông tin đăng nhập hiện tại của gitlab sau khi đăng xuất và đăng nhập lại
1. Triển khai jenkins master 1. Tạo tệp YAML triển khai apiVersion: apps/v1 kind: Siêu dữ liệu triển khai: tên: je
1. Cài đặt Docker nexus wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum sạch tất cả
1. Tạo một tệp thư viện mới build.groovy package org.devops // Build type def Build(buildType,buildShell){
1. Mua sản phẩm 1. Cài đặt và định cấu hình plug-in cấu hình plug-in (trong dự án jenkins) 2. Chọn sản phẩm tương ứng 3. Sửa đổi tệp jenkins // Thêm mã sau Chuỗi tạo tácU
1.github tạo OAuth 2.jenkins cài đặt và định cấu hình plugin xác thực github jenkins định cấu hình để sử dụng xác thực github 3. Đăng xuất và đăng nhập lại
1. Thêm dự án Maven thử nghiệm 1. Tạo dự án gitlab mới 2. Nhập mã kho ứng dụng simple-java-maven-app (bạn có thể truy cập github hoặc Gittree) 3. Định cấu hình nguồn nội địa mvn
1. Thêm trình cắm AnsiColor 2. Kiểm tra cú pháp trình cắm 1. Mở bất kỳ cấu hình dự án đường ống nào, tìm cú pháp đường ống và nhấp vào kết nối nhảy, chọn trình cắm và xem trợ giúp 3. Sửa đổi thư viện chia sẻ kịch bản để tối ưu hóa
1. Khái niệm đường ống 1 nút/tác nhân (node) Nút là một máy, có thể là nút chính của Jenkins hoặc nút phụ. Chỉ định máy mà công việc hiện tại đang chạy qua nút (đây là cú pháp tập lệnh).
1. Sao lưu và khôi phục plug-in 1. Cài đặt plug-in sao lưu và khởi động lại hệ thống để xem 2. Bấm để vào chu trình cấu hình sao lưu và bấm Cài đặt Chỉ sao lưu các bản dựng được đánh dấu để giữ
1. Triển khai LDAP. Triển khai vùng chứa được sử dụng tại đây. Tham khảo triển khai thủ công: https://www.cnblogs.com/panwenbin-logs/p/16101045.html 1. Cài đặt docker wget -
Do phiên bản nguồn mở của sonarqube không hỗ trợ quản lý đa nhánh nên cùng một dự án sonar sẽ được chỉ định khi quét tất cả các nhánh, điều này không thuận tiện cho chúng tôi xem 1. Tải xuống địa chỉ dự án plug-in nguồn mở: https: //github.com/mc1arke/
1. Kiểm tra thủ công Lưu ý rằng phiên bản này đã chứa plugin quét ngôn ngữ Java. Không cần phải cài đặt riêng mã 1.clone git clone git@192.168.1.128:root/demo-maven-serv.
Tôi có tình huống tiếp theo. Từ biểu mẫu PHP, tôi chỉ nhận được ID công ty. Tôi cần sắp xếp tất cả tên người dùng bằng ID công ty đó. Tôi cần một mảng và xuất tất cả nhật ký có tên người dùng đó sang một bảng. Vấn đề của tôi là khi tôi thử bước tiếp theo: $sql2 = " CHỌN
Tôi là một lập trình viên xuất sắc, rất xuất sắc!