注:不同企业统一登录认证具体实现可能会有些许不同,但都大同小异,不外乎从公司首页访问你正在开发的系统,这时你需要提供部分参数获取Access-Token(包含用户信息或一些登录信息)
本人所在公司使用的模式如下所示

项目经理会将申请的Client_id和secret提前告知你,你需要将其写入配置文件中以便后续使用

废话不多说直接上代码
/**
* APP权限接口和CAS单点登录接口
* @param code
* @return
* @Auther: 山枕檀痕
*
*/
@ApiOperation("APP权限接口和CAS单点登录接口")
@RequestMapping(value = "/loginByCode", method = RequestMethod.POST)
public Result<JSONObject> loginByCode(@RequestParam("code") String code){
Result<JSONObject> result = new Result<JSONObject>();
// 1. 获取令牌
Map<String, String> tokenResponse = getToken(code);
if (tokenResponse == null) {
// 处理获取令牌失败的情况
return result;
}
// 2. 获取用户信息
String accessToken = tokenResponse.get("access_token");
SysUserInfo userInfo = getUserInfo(accessToken);
String realname = userInfo.getUser_name();
//3. 校验用户是否有效
//update-begin-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bug,if条件永远为false
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysUser::getRealname,realname);
SysUser sysUser = sysUserService.getOne(queryWrapper);
//update-end-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bug,if条件永远为false
result = sysUserService.checkUserIsEffective(sysUser);
if(!result.isSuccess()) {
return result;
}
//4.用户登录信息
userInfo(sysUser, result);
//update-begin--Author:liusq Date:20210126 for:登录成功,删除redis中的验证码
LoginUser loginUser = new LoginUser();
BeanUtils.copyProperties(sysUser, loginUser);
baseCommonService.addLog("用户名: " + realname + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser);
//update-end--Author:wangshuai Date:20200714 for:登录日志没有记录人员
return result;
}
public Map<String, String> getToken(String code) {
// 创建一个RestTemplate实例
RestTemplate restTemplate = new RestTemplate();
// 构建请求头,包括 Content-Type
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
// 构建请求体参数
MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
requestBody.add("client_id", appProperties.getClientId());
requestBody.add("secret", appProperties.getSecret());
requestBody.add("code", code);
requestBody.add("grant_type", "authorization_code");
// 创建HttpEntity对象,将请求体和请求头组合
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(requestBody, headers);
// 发起POST请求,获取响应
ResponseEntity<String> response = restTemplate.postForEntity(appProperties.getAuthServer()+"/connect/token", request, String.class);
System.out.println("response++++++++++++++++++++++++"+response);
if (response.getStatusCode().is2xxSuccessful()) {
// 请求成功,从响应中提取token
String tokenResponse = response.getBody();
return parseTokenResponse(tokenResponse);
} else {
throw new RuntimeException("无法检索令牌: " + response.getStatusCodeValue());
}
}
public Map<String, String> parseTokenResponse(String tokenResponse) {
ObjectMapper objectMapper = new ObjectMapper();
try {
return objectMapper.readValue(tokenResponse, new TypeReference<Map<String, String>>() {});
} catch (Exception e) {
e.printStackTrace(); // 处理解析异常
return null;
}
}
public SysUserInfo getUserInfo(String accessToken){
RestTemplate restTemplate = new RestTemplate();
// 构建请求体参数
MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
requestBody.add("access_token", accessToken);
// 创建HttpEntity对象,将请求体和请求头组合
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(requestBody, headers);
// 构建请求 URL
String url = appProperties.getAuthServer()+"/connect/checktoken";
ResponseEntity<SysUserInfo> response = restTemplate.postForEntity(url, request, SysUserInfo.class);
if (response.getStatusCode().is2xxSuccessful()) {
return response.getBody();
} else {
throw new RuntimeException("无法获取登录信息: " + response.getStatusCodeValue());
}
}
本文详细描述了企业统一登录认证过程,涉及获取Access-Token、用户信息验证及使用RESTTemplate进行OAuth请求的示例代码。作者展示了如何在接收到CAS单点登录的code后,通过与授权服务器交互获取用户信息并确保用户有效性。



373

被折叠的 条评论
为什么被折叠?



