欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > Apollo配置中心登陆页面添加验证码

Apollo配置中心登陆页面添加验证码

2025/4/5 0:57:43 来源:https://blog.csdn.net/jjk_02027/article/details/146985406  浏览:    关键词:Apollo配置中心登陆页面添加验证码

效果图

软件环境

apollo配置中心,官方下载地址: https://github.com/apolloconfig/apollo

apollo配置中心,官方文档:Apollo

验证码工具:hutool-all 5.8.36  官方网址:https://github.com/chinabugotech/hutool

需求说明

1、登陆页面添加验证码支持

2、验证码正确才能登陆成功

3、验证码为空或不正确需在登陆页面提示出来

4、不能影响现有功能和性能

5、验证码获取与校验需要在0.5s内完成

登陆页面添加验证码

二开login.html

<!--  在密码表单的div后面添加如下代码    -->
<div class="form-group"><input type="text" name="captcha" tabindex="3"class="form-control" placeholder="Enter Captcha"><img src="/createCaptcha" alt="Captcha" />
</div>

maven配置

pom.xml

说明:

       不做表单密码加密传输的不需要升级bcprov,表单密码加密传输见作者另一篇文章

Apollo配置中心登陆页面表单密码加密提交-CSDN博客

<!-- 工具包,包含验证码、加解密(无底层实现) -->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.36</version>
</dependency><!-- 加解密(底层实现),低版本的可能需要升级 -->
<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk18on</artifactId><version>1.80</version>
</dependency>

小知识:

       一般bcprov包并非直接引用,升级自带加解密包时可从对应依赖中先排除 ,然后添加新版本pom依赖。

二开Filter

二开或添加新的Filter皆可

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest httpRequest = (HttpServletRequest) request;HttpServletResponse httpResponse = (HttpServletResponse) response;....... // 其他代码// 验证码支持if(isLoginRequest2(httpRequest, httpResponse)){String captchaCode1 = obtainCaptchaCode1(httpRequest );String captcha = obtainCaptchaCode( httpRequest );if(StringUtil.isEmpty(captcha)){httpResponse.sendRedirect("signin#/error");return;}if(!captcha.equalsIgnoreCase(captchaCode1)){httpResponse.sendRedirect("signin#/error");return;}}....... // 其他代码chain.doFilter(request, response);
}/*** 判断是否登陆请求* * @param request* @param response* @return*/
private boolean isLoginRequest2(HttpServletRequest request, HttpServletResponse response) {String url = request.getRequestURI();if(url.endsWith("signin") && "POST".equalsIgnoreCase(request.getMethod())){return true;}else{return false;}
}/*** 从session中取captchaCode1属性(登陆页面初始化时记录)* @param request* @return*/
protected String obtainCaptchaCode1(HttpServletRequest request) {return (String)request.getSession().getAttribute("captchaCode1" );
}/*** 从表单参数中取captcha* @param request* @return*/
protected String obtainCaptchaCode(HttpServletRequest request) {return request.getParameter("captcha" );
}

验证码生成Controller

可在已有的登陆Controller类中添加createCaptcha(创建验证码)方法

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;/*** @author brickerman 2025-04-03*/
@Controller
public class SignInController {......//其他方法/*** 用于登陆页面初始化时创建验证码,并记录在 session 中* @param request* @param response* @throws IOException*/@RequestMapping(value = "/createCaptcha", method = RequestMethod.GET)public void createCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {// 设置响应的内容类型为PNGresponse.setContentType(MediaType.IMAGE_PNG_VALUE);// 创建一个线型验证码对象,宽130,高50,4个字符长度LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(130, 50, 4, 5);// 获取验证码文本String captchaCode = lineCaptcha.getCode();System.out.println("验证码内容: " + captchaCode);request.getSession().setAttribute("captchaCode1", captchaCode);javax.servlet.ServletOutputStream out = response.getOutputStream();// 获取验证码图片BufferedImageBufferedImage image = lineCaptcha.getImage();// 将图片输出到文件(例如:captcha.png)ImageIO.write(image, "PNG", out);image.flush();response.flushBuffer(); // 确保数据被发送到客户端}
}

 验证码请求不鉴权

找到权限配置类,如:AuthConfiguration(不同的版本可能不一样)

// 举例
@Configuration
public class AuthConfiguration {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable();http.headers().frameOptions().sameOrigin();http.authorizeRequests().antMatchers("/openapi/**", "/vendor/**","/styles/**", "/scripts/**","/views/**", "/img/**","/prometheus","/createCaptcha")  // 取消验证码请求鉴权.permitAll().antMatchers("/**").hasAnyRole(USER_ROLE);http.formLogin().loginPage("/signin").permitAll().failureUrl("/signin?#/error").and().addFilter(authenticationFilter());http.logout().invalidateHttpSession(true).clearAuthentication(true).logoutSuccessUrl("/signin?#/logout");http.exceptionHandling().authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/signin"));}
}

优化登陆失败提示

这里把“用户名或密码错误”改为:“用户名或密码或验证码错误

// LoginController.js
login_module.controller('LoginController',['$scope', '$window', '$location', 'toastr', 'AppUtil',LoginController]);function LoginController($scope, $window, $location, toastr, AppUtil) {if ($location.$$url) {var params = AppUtil.parseParams($location.$$url);if (params.error) {$scope.info = "用户名或密码或验证码错误";}if (params.logout) {$scope.info = "登出成功";}}
}

 失败效果:

附件一:Apollo鉴权机制

Apollo鉴权机制‌主要包括两种实现方式:使用Apollo提供的Spring Security简单认证和接入公司的统一登录认证系统。

Apollo提供的Spring Security简单认证

Apollo从0.9.0版本开始提供了利用Spring Security实现的Http Basic简单认证。这种方式适用于那些没有统一登录认证系统的公司,实现起来相对简单。通过这种方式,Apollo配置中心默认使用Apollo账号进行鉴权,账号默认为“apollo”‌。

接入公司的统一登录认证系统

如果公司已经有统一的登录认证系统,如SSO、LDAP等,可以通过接入这些系统来实现鉴权。具体实现需要实现UserService和UserInfoHolder等接口,将Apollo配置中心与公司的认证系统集成。这种方式可以充分利用公司现有的认证资源,提高系统的安全性和管理效率‌。

配置和修改鉴权方式

如果需要修改或取消鉴权,可以通过修改配置文件来实现。例如,可以通过修改spring.profiles.active参数来启用或禁用鉴权。默认情况下,如果配置文件中没有指定鉴权方式,Apollo会使用默认的Apollo账号进行鉴权。如果需要取消鉴权,可以将配置文件中的auth配置删除即可‌。

附件二:Apollo集成公司SSO统一认证实现方案

一、实现原理

Apollo通过Portal模块的‌SPI扩展机制‌支持SSO集成,其核心逻辑是通过自定义Filter拦截请求,将认证流程交由企业SSO系统完成‌58。完成认证后,用户凭证信息会通过Cookie或分布式Session保存,最终通过UserInfoHolder接口获取当前登录用户信息‌。


二、具体实现步骤

  1. 配置SSO客户端依赖

    引入公司SSO系统提供的客户端JAR包,例如CAS Client或OAuth2 Client‌58。
  2. 实现认证Filter链

    配置SSO Filter拦截/signin等关键路径,实现以下逻辑:
    • 验证票据有效性后,将用户信息写入本地Session或Redis‌
    • 未登录时重定向至SSO登录页面,并在回调时携带认证票据‌
    • 检查请求是否携带有效凭证(如Token或SessionID)‌
  3. 实现用户信息接口

    自定义UserService接口实现类,从SSO系统获取用户基础信息(如用户ID、部门等)‌6
    • 实现UserInfoHolder接口,通过ThreadLocal存储当前用户上下文‌
  4. 配置Apollo Profile

    修改application.properties,激活SSO Profile(如spring.profiles.active=auth)‌
    • 禁用内置Spring Security认证(移除auth Profile相关配置)‌
  5. 权限映射同步

    • 将SSO系统的角色/权限体系与Apollo权限模型(项目管理员、环境发布权限等)进行映射‌
    • 通过/user-manage.html同步SSO用户到Apollo本地数据库‌

三、关键配置示例

# application-sso.properties
sso.enabled=true
sso.login-url=https://sso.company.com/login
sso.callback-url=https://apollo.company.com/callback
sso.token-header=X-Auth-Token

四、注意事项

  1. 跨域问题

    需在SSO服务端配置Apollo Portal域名白名单,避免CORS拦截‌
  2. 会话管理

    推荐使用Redis存储分布式Session,避免节点间状态不一致‌
  3. 高可用设计

    SSO认证服务需部署集群,避免单点故障导致Apollo不可用‌
  4. 权限控制

    Apollo默认采用应用负责人机制,需通过UserService实现SSO用户与负责人自动关联‌
  5. 安全加固

    在SSO侧启用MFA(多因素认证),提升Apollo管理界面访问安全性‌

五、验证流程

  1. 访问https://apollo.company.com触发SSO重定向
  2. 在SSO登录页完成认证后跳转回Apollo
  3. 检查浏览器控制台无401 Unauthorized错误
  4. 验证UserInfoHolder.getUser()能正确返回SSO用户信息‌

通过以上步骤,可实现Apollo与企业SSO系统的无缝集成,同时满足统一身份管理和权限控制需求‌

附件三:登陆表单密码加密

Apollo配置中心登陆页面表单密码加密提交-CSDN博客

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词