前言
需要实现的功能是用户使用特定的账号登录后,便可以实现上网。经过了解,现在是使用Sangfor(深信服)AC系统对用户上网行为进行管理。通过看文档和与客服沟通,决定搭建一个web的做第三方认证,因为只有这个不需要先获取IP也比较熟悉如何实现。
实际场景:我们经常能接触的场景就是连某个地方的WIFI,需要输入手机号获得验证码便可以上网。
不得不说他们的客服是真的尽责,官网的资料也非常全面,就算回答不上来,也会问相关技术人员再发邮箱反馈。当然服务器搭建好需要配置,配置可以参考官方文档,非常详细明了。简单的说就是在Sangfor系统中配置这个项目的地址,并监听登录成功返回的关键字,如果包含就是登录成功。
pom文件导入依赖
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.2.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- http -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.41</version>
</dependency>
<!-- 热部署模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<!-- 这个需要为 true 热部署才有效 -->
</dependency>
<!-- Swagger 2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons.lang.version}</version>
</dependency>
</dependencies>
application.yml添加配置
spring:
freemarker:
suffix: .ftl
template-loader-path: classpath:/templates/
HomeController
@Controller
public class HomeController {
@RequestMapping(value = {"/index", "", "/"})
@ApiOperation(value = "主页", notes = "")
public String toLogin(HttpServletRequest request) {
Object loginInfo = request.getSession().getAttribute("loginInfo");
LoginForm form = (LoginForm) loginInfo;
if (form != null && form.getUsername() != null && "test".equals(form.getUsername())) {
return "index";
}
return "mobile";
}
@RequestMapping(value = {"/exit"})
@ApiOperation(value = "退出", notes = "")
public String exit(HttpServletRequest request) {
request.getSession().setAttribute("loginInfo", null);
return "mobile";
}
}
LoginController
@Api("登录")
@RestController
@RequestMapping("/")
public class LoginController {
@PostMapping(value = {"login"})
@ApiOperation(value = "登录", notes = "登录")
public String login(@RequestBody @ApiParam(name = "loginForm", value = "登录信息") LoginForm loginForm, HttpServletRequest request) {
if ("test".equals(loginForm.getUsername())) {
loginForm.setCreateDate(new Date().getTime());
request.getSession().setAttribute("loginInfo", loginForm);
return "success";
}
return "fail";
}
}
项目结构截图
遇到问题
1、外网环境部署成功,认证失败。首先要AC系统单点登录原理是配置地址和关键返回字段,进行监听。用系统自带的抓包工具,抓取连接设备IP传输数据,找到登录请求,发现与文档相比有误差。我明监听机制是按着post提交form表单实现的,在修改前端代码后解决此问题。
2、内网部署成功,访问失败。内网环境一定时IP+端口,需要开启端口,不然无法访问。
3、内网部署成功,认证失败。这个地方应该是最坑的地方,不仅需要额外配置,还需要额外的物理连接并进行镜像配置。内网环境中需要将web服务器的数据镜像到核心交换机固定端口,并将端口与AC设备相连。