Commit 14b92928 LN

Merge remote-tracking branch 'origin/SO20031-smf-core' into SO20031-smf-core

2 个父辈 4254a8e4 65e8a283
package com.neotel.smfcore.custom.micron20031.login.api;
import cn.hutool.core.codec.Base64Decoder;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.custom.micron20031.login.api.bean.MicronUserInfo;
import com.neotel.smfcore.custom.micron20031.login.config.MicronLoginConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Decoder;
import javax.net.ssl.SSLContext;
import java.net.URLDecoder;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@Slf4j
@Component
public class MicronLoginApi {
@Autowired
private MicronLoginConfig loginConfig;
public static final String GRANT_TYPE = "authorization_code";
public MicronUserInfo getUserInfoByCode(String code) {
//地址
String url = loginConfig.getAdfsBaseAddress() + loginConfig.getTokenUri();
log.info("获取镁光用户信息地址为:" + url);
//设置入参
Map<String, String> paramMap = new HashMap<>();
paramMap.put("client_id", loginConfig.getClientId());
paramMap.put("code", code);
paramMap.put("redirect_uri", loginConfig.getRedirectUrl());
paramMap.put("grant_type", GRANT_TYPE);
log.info("请求参数为:" + JSON.toJSONString(paramMap));
//设置请求头格式
Map<String, String> headerMap = new HashMap<>();
headerMap.put("Content-Type", "application/x-www-form-urlencoded");
//请求token地址
try {
String result = post(url, paramMap, headerMap);
if (StringUtils.isNotBlank(result)) {
JSONObject jsonObject = JSONObject.parseObject(result);
String idToken = jsonObject.getString("id_token");
//以.分割进行截取,取中间部分
String[] split = idToken.split("\\.");
String base64UserInfo = split[1];
//进行解析
String userInfoStr = new String(Base64.getDecoder().decode(base64UserInfo));
log.info("获取到用户信息为:"+userInfoStr);
return JSONObject.parseObject(userInfoStr, MicronUserInfo.class);
}
} catch (Exception e) {
log.error("获取镁光用户信息失败:" + e.getMessage());
e.printStackTrace();
}
return null;
}
private String post(String url, Map<String, String> paramMap, Map<String, String> headerMap) throws Exception {
HttpPost httpPost = new HttpPost(url);
if (headerMap != null && !headerMap.isEmpty()) {
for (Map.Entry<String, String> header : headerMap.entrySet()) {
httpPost.addHeader(header.getKey(), header.getValue());
}
}
// 设置请求参数
try {
String param = "";
if (paramMap != null && paramMap.size() > 0) {
Iterator<String> ite = paramMap.keySet().iterator();
while (ite.hasNext()) {
String key = ite.next();// key
Object valueObj = paramMap.get(key);
String value = "";
if (valueObj != null) {
value = valueObj.toString();
}
param += key + "=" + value + "&";
}
param = param.substring(0, param.length() - 1);
}
param = URLDecoder.decode(param, "UTF-8");
httpPost.setEntity(new StringEntity(param, "UTF-8"));
RequestConfig defaultConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build();
httpPost.setConfig(defaultConfig);
} catch (Exception e) {
log.error("Request params to [" + url + "] json exception:" + e.getMessage());
}
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
try (CloseableHttpClient httpClient = httpClientBuilder.setSSLSocketFactory(getSslConnectionSocketFactory()).build()) {
CloseableHttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
String responseContent = EntityUtils.toString(entity, "UTF-8");
response.close();
httpClient.close();
log.info("postJsonWithAuth url=[" + url + "] return= [" + responseContent + "]");
return responseContent;
} catch (Exception e) {
log.error("Request to [" + url + "] failed:" + e.getMessage());
}
return "";
}
/**
* 支持SSL
*
* @return SSLConnectionSocketFactory
*/
private SSLConnectionSocketFactory getSslConnectionSocketFactory() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
TrustStrategy acceptingTrustStrategy = (x509Certificates, s) -> true;
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
return new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
}
}
package com.neotel.smfcore.custom.micron20031.login.api.bean;
import lombok.Data;
/**
* {
* "aud": "4b3a662e-df9a-4215-8c11-19329d82cecb",
* "iss": "https://adfstest.micron.com/adfs",
* "iat": 1688462863,
* "nbf": 1688462863,
* "exp": 1688466463,
* "auth_time": 1688436083,
* "sub": "DTYjbCO/z9aDs25Xf98RReHVw5W8brFsQm1Kky+X5xs=",
* "upn": "zteoh@micron.com",
* "pwd_exp": "4319191",
* "sid": "S-1-5-21-20920562-2040232336-316619961-46280486",
* "unique_name": "zteoh@micron.com",
* "email": "zteoh@micron.com",
* "PUID": "1200062",
* "winaccountname": "zteoh",
* "given_name": "Zac",
* "family_name": "Teoh",
* "apptype": "Public",
* "appid": "4b3a662e-df9a-4215-8c11-19329d82cecb",
* "authmethod": "http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/windows",
* "ver": "1.0"
* }
*/
@Data
public class MicronUserInfo {
private String aud;
private String iss;
private int iat;
private int nbf;
private int exp;
private int auth_time;
private String sub;
private String upn;
private String pwd_exp;
private String sid;
private String unique_name;
private String email;
private String PUID;
private String winaccountname;
private String given_name;
private String family_name;
private String apptype;
private String appid;
private String authmethod;
private String ver;
}
package com.neotel.smfcore.custom.micron20031.login.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "micron.login")
@Data
public class MicronLoginConfig {
private String adfsBaseAddress;
private String clientId;
private String redirectUrl;
private String adfsMetadataAddress;
private String tokenUri;
private String authorizeUri;
}
package com.neotel.smfcore.custom.micron20031.login.controller;
import com.alibaba.fastjson.JSONObject;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.*;
import com.neotel.smfcore.custom.micron20031.login.api.MicronLoginApi;
import com.neotel.smfcore.custom.micron20031.login.api.bean.MicronUserInfo;
import com.neotel.smfcore.custom.micron20031.login.config.MicronLoginConfig;
import com.neotel.smfcore.security.TokenProvider;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import com.neotel.smfcore.security.bean.LoginProperties;
import com.neotel.smfcore.security.bean.RsaProperties;
import com.neotel.smfcore.security.bean.SecurityProperties;
import com.neotel.smfcore.security.rest.bean.dto.JwtUserDto;
import com.neotel.smfcore.security.rest.bean.dto.OnlineUserDto;
import com.neotel.smfcore.security.service.OnlineUserService;
import com.neotel.smfcore.security.service.manager.IRoleManager;
import com.neotel.smfcore.security.service.manager.IUserManager;
import com.neotel.smfcore.security.service.po.Role;
import com.neotel.smfcore.security.service.po.User;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.server.Http2;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
@Controller
@Slf4j
@RequestMapping("/micron")
@RequiredArgsConstructor
public class MicronLoginController {
@Autowired
private MicronLoginConfig loginConfig;
@Autowired
private MicronLoginApi loginApi;
@Autowired
private IUserManager userManager;
@Autowired
private IRoleManager roleManager;
@Autowired
private OnlineUserService onlineUserService;
@Resource
private LoginProperties loginProperties;
@Autowired
private TokenProvider tokenProvider;
public static final String RESPONSE_TYPE = "code";
public static final String RESPONSE_MODE = "query";
private final AuthenticationManagerBuilder authenticationManagerBuilder;
private final SecurityProperties properties;
private final PasswordEncoder passwordEncoder;
/**
* 登录
*/
@RequestMapping("/login")
@AnonymousAccess
@ResponseBody
public String login() {
String loginRedirectUrl = loginConfig.getAdfsBaseAddress()
+ loginConfig.getAuthorizeUri()
+ "?"
+ "resource=" + loginConfig.getClientId()
+ "&client_id=" + loginConfig.getClientId()
+ "&response_type=" + RESPONSE_TYPE
+ "&haschrome=1"
+ "&redirect_uri=" + loginConfig.getRedirectUrl()
+ "&code_challenge=jbxg31yfKmRhuBVutV-DtfoKsvEsDGKbDF_mEudl2a4"
+ "&code_challenge_method=S256"
+ "&state=15d57431-f939-4e4a-8006-fab1358cafee9507c217-d512-4f28-a8bf-c16928db80ce"
+ "&response_mode=" + RESPONSE_MODE
+ "&client-request-id=69ea5a4a-c0db-48c6-ad0e-feb9cee43301"
+ "&x-client-SKU=PCL.Desktop"
+ "&x-client-Ver=5.2.9.0"
+ "&x-client-CPU=x64"
+ "&x-client-OS=Microsoft+Windows+NT+6.2.9200.0";
log.info("镁光登录重定向地址为:{}", loginRedirectUrl);
return loginRedirectUrl;
}
/**
* 根据code获取用户信息
*/
@ResponseBody
@RequestMapping("/loginAuth")
@AnonymousAccess
public ResponseEntity<Object> loginAuth(HttpServletRequest request) throws Exception {
String code = request.getParameter("code");
log.info("镁光用户登录的授权code为:" + code);
if (StringUtils.isNotBlank(code)) {
MicronUserInfo userInfo = loginApi.getUserInfoByCode(code);
if (userInfo != null) {
//根据唯一名称判断是否存在
User user = userManager.findByUserName(userInfo.getUnique_name());
if (user == null) {
//123456..123
String pwd = passwordEncoder.encode("123456..123");
Role role = roleManager.findOne(new Query(Criteria.where("name").is("admin")));
user = new User(userInfo.getUnique_name(), userInfo.getEmail(), "zh-CN", role.getId(), pwd, true, true, new Date(), new HashSet<>(), "");
user = userManager.save(user);
}
final String password = "123456..123";
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(user.getUsername(), password);
Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
// 生成令牌与第三方系统获取令牌方式
// UserDetails userDetails = userDetailsService.loadUserByUsername(userInfo.getUsername());
// Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
// SecurityContextHolder.getContext().setAuthentication(authentication);
String token = tokenProvider.createToken(authentication);
final JwtUserDto jwtUserDto = (JwtUserDto) authentication.getPrincipal();
// 保存在线信息
String ip = StringUtils.getIp(request);
String browser = StringUtils.getBrowser(request);
String address = StringUtils.getCityInfo(ip);
OnlineUserDto onlineUserDto = null;
try {
long seconds = onlineUserService.properties.getTokenValidityInSeconds() / 1000;
Date exTime= DateUtil.addSeconds(new Date(), new Long(seconds).intValue());
onlineUserDto = new OnlineUserDto(jwtUserDto.getUsername(), browser , ip, address, EncryptUtils.desEncrypt(token), new Date(),exTime);
} catch (Exception e) {
log.error(e.getMessage(),e);
}
OnlineUserService.onlineUserMap.put(onlineUserService.properties.getOnlineKey() + token, onlineUserDto);
// 返回 token 与 用户信息
Map<String, Object> authInfo = new HashMap<String, Object>(2) {{
put("token", properties.getTokenStartWith() + token);
put("user", jwtUserDto);
}};
if (loginProperties.isSingleLogin()) {
//踢掉之前已经登录的token
onlineUserService.checkLoginOnUser(user.getUsername(), token);
}
//重新登陆时清理调试模式状态
SecurityUtils.updateToDebugModel(onlineUserDto.getUserName(),false);
log.info("返回的用户信息为:"+ JSONObject.toJSONString(authInfo));
return ResponseEntity.ok(authInfo);
}
}
throw new ValidateException("smfcore.userInfoError", "用户信息不完整");
}
}
......@@ -18,17 +18,12 @@ package com.neotel.smfcore.security.service.manager;
import com.neotel.smfcore.common.base.IBaseManager;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.security.service.po.Role;
import com.neotel.smfcore.security.service.po.User;
import org.springframework.data.domain.Pageable;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.data.mongodb.core.query.Query;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
public interface IRoleManager extends IBaseManager<Role> {
......@@ -43,4 +38,6 @@ public interface IRoleManager extends IBaseManager<Role> {
void deleteRoles(List<Role> roles) throws ValidateException;
void untiedMenu(String menuId) throws ValidateException;
Role findOne(Query query);
}
......@@ -148,4 +148,10 @@ public class RoleManagerImpl implements IRoleManager {
}
}
@Override
public Role findOne(Query query) {
return roleDao.findOne(query);
}
}
......@@ -19,6 +19,22 @@ micron:
email:
to:
cc:
#登录信息配置
login:
#地址信息
adfs-base-address: https://adfstest.micron.com
#客户端id
client-id: 4b3a662e-df9a-4215-8c11-19329d82cecb
#调用客户端重定向地址
redirect-url: http://localhost
adfs-metadata-address: https://adfstest.micron.com/federationmetadata/2007-06/federationmetadata.xml
#获取token的uri
token-uri: /adfs/oauth2/token
#授权地址
authorize-uri: /adfs/oauth2/authorize
api:
name: 20031
inCheckUrl: https://testapigtwy.micron.com/t/app.mfg/mmsil/v1/DEVL/SINGAPORE/ReturnMaterial
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!