作者 朱兆平

add: 增加对机场统一认证接口

@@ -151,7 +151,8 @@ logging: @@ -151,7 +151,8 @@ logging:
151 #Java Web Token 时效时间,单位秒 151 #Java Web Token 时效时间,单位秒
152 jwt: 152 jwt:
153 max-alive: 30000 153 max-alive: 30000
154 - 154 +sso:
  155 + url: http://10.5.14.103:27080/sso/p3/serviceValidate
155 info: 156 info:
156 version: 2.0 157 version: 2.0
157 description: "统一用户认证中心服务,具备用户认证,接口鉴权|数据鉴权功能." 158 description: "统一用户认证中心服务,具备用户认证,接口鉴权|数据鉴权功能."
@@ -144,7 +144,8 @@ logging: @@ -144,7 +144,8 @@ logging:
144 #Java Web Token 时效时间,单位秒 144 #Java Web Token 时效时间,单位秒
145 jwt: 145 jwt:
146 max-alive: 30000 146 max-alive: 30000
147 - 147 +sso:
  148 + url: http://10.5.14.103:27080/sso/p3/serviceValidate
148 info: 149 info:
149 version: 2.0 150 version: 2.0
150 description: "具有公司及部门管理级别的用户管理中心" 151 description: "具有公司及部门管理级别的用户管理中心"
@@ -7,9 +7,15 @@ package com.tianbo.warehouse; @@ -7,9 +7,15 @@ package com.tianbo.warehouse;
7 import org.mybatis.spring.annotation.MapperScan; 7 import org.mybatis.spring.annotation.MapperScan;
8 import org.springframework.boot.SpringApplication; 8 import org.springframework.boot.SpringApplication;
9 import org.springframework.boot.autoconfigure.SpringBootApplication; 9 import org.springframework.boot.autoconfigure.SpringBootApplication;
  10 +import org.springframework.boot.web.client.RestTemplateBuilder;
  11 +import org.springframework.cloud.client.loadbalancer.LoadBalanced;
10 import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 12 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
  13 +import org.springframework.context.annotation.Bean;
11 import org.springframework.scheduling.annotation.EnableScheduling; 14 import org.springframework.scheduling.annotation.EnableScheduling;
12 import org.springframework.transaction.annotation.EnableTransactionManagement; 15 import org.springframework.transaction.annotation.EnableTransactionManagement;
  16 +import org.springframework.web.client.RestTemplate;
  17 +
  18 +import java.time.Duration;
13 19
14 @SpringBootApplication 20 @SpringBootApplication
15 @EnableScheduling 21 @EnableScheduling
@@ -22,5 +28,10 @@ public class WarehouseApplication { @@ -22,5 +28,10 @@ public class WarehouseApplication {
22 SpringApplication.run(WarehouseApplication.class, args); 28 SpringApplication.run(WarehouseApplication.class, args);
23 } 29 }
24 30
  31 + @Bean
  32 + RestTemplate restTemplate(RestTemplateBuilder builder){
  33 + return builder.setConnectTimeout(Duration.ofSeconds(15)).setReadTimeout(Duration.ofSeconds(15))
  34 + .build();
  35 + }
25 } 36 }
26 37
@@ -2,21 +2,33 @@ package com.tianbo.warehouse.controller; @@ -2,21 +2,33 @@ package com.tianbo.warehouse.controller;
2 2
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 4
  5 +import com.alibaba.fastjson.JSONException;
  6 +import com.alibaba.fastjson.JSONObject;
5 import com.google.code.kaptcha.impl.DefaultKaptcha; 7 import com.google.code.kaptcha.impl.DefaultKaptcha;
6 8
7 import com.thoughtworks.xstream.core.util.Base64Encoder; 9 import com.thoughtworks.xstream.core.util.Base64Encoder;
8 import com.tianbo.warehouse.controller.response.ResultJson; 10 import com.tianbo.warehouse.controller.response.ResultJson;
9 import com.tianbo.warehouse.model.ROLE; 11 import com.tianbo.warehouse.model.ROLE;
10 import com.tianbo.warehouse.model.Token; 12 import com.tianbo.warehouse.model.Token;
  13 +import com.tianbo.warehouse.model.USERS;
  14 +import com.tianbo.warehouse.security.filter.JwtTokenUtil;
  15 +import com.tianbo.warehouse.service.PermissionService;
11 import com.tianbo.warehouse.service.RoleService; 16 import com.tianbo.warehouse.service.RoleService;
12 17
  18 +import com.tianbo.warehouse.service.UserService;
13 import com.tianbo.warehouse.util.RedisUtils; 19 import com.tianbo.warehouse.util.RedisUtils;
14 20
  21 +import io.swagger.annotations.ApiOperation;
15 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
  23 +import org.apache.commons.lang.StringUtils;
16 import org.springframework.beans.factory.annotation.Autowired; 24 import org.springframework.beans.factory.annotation.Autowired;
  25 +import org.springframework.beans.factory.annotation.Value;
  26 +import org.springframework.http.ResponseEntity;
17 import org.springframework.web.bind.annotation.PostMapping; 27 import org.springframework.web.bind.annotation.PostMapping;
18 import org.springframework.web.bind.annotation.RequestMapping; 28 import org.springframework.web.bind.annotation.RequestMapping;
  29 +import org.springframework.web.bind.annotation.RequestParam;
19 import org.springframework.web.bind.annotation.RestController; 30 import org.springframework.web.bind.annotation.RestController;
  31 +import org.springframework.web.client.RestTemplate;
20 32
21 import javax.imageio.ImageIO; 33 import javax.imageio.ImageIO;
22 34
@@ -34,11 +46,35 @@ public class AnonymousController { @@ -34,11 +46,35 @@ public class AnonymousController {
34 RoleService roleService; 46 RoleService roleService;
35 47
36 @Autowired 48 @Autowired
  49 + private PermissionService permissionService;
  50 +
  51 + @Autowired
37 RedisUtils redisUtils; 52 RedisUtils redisUtils;
38 53
39 @Autowired 54 @Autowired
40 private DefaultKaptcha captchaProducer; 55 private DefaultKaptcha captchaProducer;
41 56
  57 + @Autowired
  58 + RestTemplate restTemplate;
  59 +
  60 + @Value("${sso.url}")
  61 + private String SSOUrl;
  62 +
  63 + @Value("${jwt.max-alive}")
  64 + protected Integer jwtMaxAlive;
  65 +
  66 + @Autowired
  67 + UserService userService;
  68 +
  69 + /**
  70 + * SSO验证服务票据响应属性名
  71 + */
  72 + private static final String SERVICE_RESPONESE = "serviceResponse";
  73 + private static final String AUTHENTICATION_SUCCESS = "authenticationSuccess";
  74 + private static final String LOGIN_NAME = "LOGIN_NAME";
  75 + private static final String ATTRIBUTES = "attributes";
  76 + private static final String USER_ID = "USER_ID";
  77 +
42 /** 78 /**
43 * 配置匿名者可以访问的路由,并更新到redis,匿名者默认可以访问的role_name =ROLE_anonymous 79 * 配置匿名者可以访问的路由,并更新到redis,匿名者默认可以访问的role_name =ROLE_anonymous
44 * 此方法会将所有符合权限组名=ROLE_anonymous的权限更新到redis中,供gateway调用判断权限 80 * 此方法会将所有符合权限组名=ROLE_anonymous的权限更新到redis中,供gateway调用判断权限
@@ -85,4 +121,126 @@ public class AnonymousController { @@ -85,4 +121,126 @@ public class AnonymousController {
85 return new ResultJson("200","verify get ok",map,verifyToken); 121 return new ResultJson("200","verify get ok",map,verifyToken);
86 122
87 } 123 }
  124 +
  125 + @ApiOperation(value = "查询用户列表及信息", notes = "查询用户列表及单个用户信息")
  126 + @RequestMapping("ssoTicket")
  127 + public ResultJson ssoLogin(@RequestParam("ticket") String ticket,
  128 + @RequestParam("myWebLoginUrl") String myWebLoginUrl
  129 + ){
  130 + try {
  131 + log.info("[SSO-AUTH-TICKET]-开始单点登录票据认证-[{}]",ticket);
  132 + // 构建接口地址
  133 + String url = SSOUrl+"?format=json&service="
  134 + + myWebLoginUrl
  135 + + "&ticket=" + ticket;
  136 +
  137 + // 使用RestTemplate调用接口
  138 + RestTemplate restTemplate = new RestTemplate();
  139 + /**
  140 + * 单点登录认证返回实体类
  141 + * {
  142 + * "serviceResponse" : {
  143 + * "authenticationSuccess" : {
  144 + * "user" : "zhangyf",
  145 + * "attributes" : {
  146 + * "isFromNewLogin" : [ false ],
  147 + * "authenticationDate" : [ 1.614564403617E9 ],
  148 + * "successfulAuthenticationHandlers" : [ "pwd" ],
  149 + * "USER_ID" : "8a0162a628aa4049a7840d75378f1a91",
  150 + * "USER_NAME" : "张炎锋",
  151 + * "extend" : [ ],
  152 + * "credentialType" : "UsernamePasswordCredential",
  153 + * "samlAuthenticationStatementAuthMethod" : "urn:oasis:names:tc:SAML:1.0:am:password",
  154 + * "ipTerritory" : "",
  155 + * "authenticationMethod" : "pwd",
  156 + * "equipType" : "pc",
  157 + * "clientIp" : "172.19.0.17",
  158 + * "isDefaultPwd" : "false",
  159 + * "longTermAuthenticationRequestTokenUsed" : [ false ],
  160 + * "LOGIN_NAME" : "zhangyf",
  161 + * "MOBILE" : "18739902467"
  162 + * }
  163 + * }
  164 + * }
  165 + * },
  166 + */
  167 + ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
  168 + String responseBody = responseEntity.getBody();
  169 +
  170 + try {
  171 + JSONObject jsonObject = JSONObject.parseObject(responseBody);
  172 + USERS user = parseSSOObject(jsonObject);
  173 + if (StringUtils.isNotEmpty(user.getUsername())){
  174 + USERS loginUser = userService.loadByUsername(user.getUsername());
  175 + if (loginUser!=null && loginUser.getUserId()>-1){
  176 + log.info("[SSO-AUTH-TICKET]-从认证中心获取到用户[{}]信息,开始设置系统登录认证token",user.getUsername());
  177 + user.setUserId(loginUser.getUserId());
  178 + user.setUsername(loginUser.getUsername());
  179 + user.setUserface(loginUser.getUserface());
  180 + user.setUserId(loginUser.getUserId());
  181 + user.setRealname(loginUser.getRealname());
  182 + user.setCompanyId(loginUser.getCompanyId());
  183 + user.setCompanyName(loginUser.getCompanyName());
  184 + user.setCompanyInfo(loginUser.getCompanyInfo());
  185 + user.setUserStatus(loginUser.getUserStatus());
  186 + user.setState(loginUser.getState());
  187 + }else {
  188 + user.setPassword("sso");
  189 + user.setUserStatus(2);
  190 + user.setState(true);
  191 + userService.insertSelective(user);
  192 + }
  193 + //设置用户的TOKEN的有效时间,时间配置在配置文件中设置
  194 + int expirationSeconds = 3600*24*7;
  195 + String jwtToken = JwtTokenUtil.generateToken(user.getUsername(), jwtMaxAlive);
  196 + user.setToken(jwtToken);
  197 + //这里将登录成功的[user]对象数据写入redis缓存,KEY为token value为user的JSON对象
  198 + String json = JSON.toJSONString(loginUser);
  199 + redisUtils.set(jwtToken, json,expirationSeconds);
  200 + redisUtils.set(Token.USER_TOKEN_KEY + user.getUsername(),jwtToken,expirationSeconds);
  201 + Map<String,Object> menuMap = permissionService.getUserMenus(user.getUserId());
  202 + return new ResultJson("200","单点登录认证成功",user);
  203 + }
  204 + } catch (JSONException e) {
  205 + e.printStackTrace();
  206 + log.error("[SSO-AUTH-TICKET-ERR]-单点登录票据解析异常",e);
  207 + return new ResultJson("400","单点登录票据解析异常",e.getMessage());
  208 + }
  209 + }catch (Exception e){
  210 + e.printStackTrace();
  211 + log.error("[SSO-AUTH-TICKET-ERR]-单点登录票据认证异常",e);
  212 + }
  213 + return new ResultJson("401","单点登录票据认证失败");
  214 + }
  215 +
  216 + /**
  217 + * 解析单点认证返回的信息
  218 + * @param ssoResp 返回实体类
  219 + * @return 用户类
  220 + */
  221 + private USERS parseSSOObject(JSONObject ssoResp){
  222 + USERS user = new USERS();
  223 + // 根节点
  224 + if (ssoResp.containsKey(SERVICE_RESPONESE)){
  225 + JSONObject root = ssoResp.getJSONObject(SERVICE_RESPONESE);
  226 +
  227 + //成功节点
  228 + if (root.containsKey(AUTHENTICATION_SUCCESS)){
  229 + JSONObject auth = root.getJSONObject(AUTHENTICATION_SUCCESS);
  230 + //用户名获取
  231 + String userName = auth.getString("user");
  232 +
  233 + //用户其他属性
  234 + JSONObject attributes = auth.getJSONObject(ATTRIBUTES);
  235 + String loginName = attributes.getString(LOGIN_NAME);
  236 + String userId = attributes.getString(USER_ID);
  237 + String realName = attributes.getString("USER_NAME");
  238 + log.info("[SSO-AUTH-TICKET-INFO]-用户:{}/{}",loginName,realName);
  239 +
  240 + user.setUsername(loginName);
  241 +// user.setUserId(userId);
  242 + }
  243 + }
  244 + return user;
  245 + }
88 } 246 }
@@ -57,7 +57,7 @@ public class SM3EncryptUtil { @@ -57,7 +57,7 @@ public class SM3EncryptUtil {
57 public static void main(String[] args) { 57 public static void main(String[] args) {
58 Security.addProvider(new BouncyCastleProvider()); 58 Security.addProvider(new BouncyCastleProvider());
59 try { 59 try {
60 - String pwdDigest = passwordSm3("vmvnv1v2"); 60 + String pwdDigest = passwordSm3("jc12345");
61 System.out.println(pwdDigest); 61 System.out.println(pwdDigest);
62 } catch (Exception e) { 62 } catch (Exception e) {
63 e.printStackTrace(); 63 e.printStackTrace();
1 package com.tianbo.warehouse; 1 package com.tianbo.warehouse;
2 2
3 -import com.tianbo.warehouse.security.config.SM3PasswordEncoder; 3 +
4 import com.tianbo.warehouse.security.login.SM4EncryptUtil; 4 import com.tianbo.warehouse.security.login.SM4EncryptUtil;
  5 +import lombok.extern.slf4j.Slf4j;
5 import org.junit.Test; 6 import org.junit.Test;
  7 +import org.junit.runner.RunWith;
  8 +import org.springframework.beans.factory.annotation.Autowired;
6 import org.springframework.boot.test.context.SpringBootTest; 9 import org.springframework.boot.test.context.SpringBootTest;
  10 +import org.springframework.test.context.junit4.SpringRunner;
7 11
  12 +@RunWith(SpringRunner.class)
  13 +@SpringBootTest(classes = WarehouseApplication.class,webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
  14 +@Slf4j
8 public class SM3EncodeTest { 15 public class SM3EncodeTest {
9 16
  17 +
10 @Test 18 @Test
11 public void encode(){ 19 public void encode(){
12 String password = "vmvnv1v2VV"; 20 String password = "vmvnv1v2VV";
13 - SM3PasswordEncoder encoder =new SM3PasswordEncoder();  
14 - String encode = encoder.encode(password);  
15 - System.out.println("SM3encode = " + encode); 21 +
  22 +
16 23
17 String SM4encode = new SM4EncryptUtil().pwd(password); 24 String SM4encode = new SM4EncryptUtil().pwd(password);
18 System.out.println("SM4encode = " + SM4encode); 25 System.out.println("SM4encode = " + SM4encode);