Commit 197e182c by xieshaohua

前海电力项目sso初始化

parent 431a5802
...@@ -106,7 +106,7 @@ ...@@ -106,7 +106,7 @@
<dependency> <dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version> <version>8.0.28</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
......
...@@ -3,11 +3,13 @@ package com.keymobile.login; ...@@ -3,11 +3,13 @@ package com.keymobile.login;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication @SpringBootApplication
@EnableDiscoveryClient @EnableDiscoveryClient
@ComponentScan(basePackages = {"com.keymobile.login", "com.keymobile.config.logging"}) @ComponentScan(basePackages = {"com.keymobile.login", "com.keymobile.config.logging"})
@EnableFeignClients
public class LoginApplication { public class LoginApplication {
public static void main(String[] args) { public static void main(String[] args) {
......
package com.keymobile.login.api;
import com.keymobile.login.persistence.model.LdapInfo;
import com.keymobile.login.service.ADService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.*;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
@Api(value = "AD域相关", tags = "AD域相关")
@RestController
@RequestMapping(value = "/adApi")
public class ADApi {
private static final Logger logger = LoggerFactory.getLogger(ADApi.class);
private static String DEFAULT_TIME_OUT = "5000";
@Autowired
private ADService adService;
@ApiOperation(value = "保存ldap基本信息")
@PostMapping(value = "/saveLdapInfo")
public LdapInfo saveLdapInfo(@RequestBody LdapInfo ldapInfo) {
return adService.saveLdapInfo(ldapInfo);
}
@ApiOperation(value = "获取ldap基本信息")
@GetMapping(value = "/getLdapInfo")
public LdapInfo getLdapInfo() {
return adService.getLdapInfo();
}
@ApiOperation(value = "删除ldap基本信息")
@DeleteMapping(value = "/deleteLdapInfo")
public void deleteLdapInfo() {
adService.deleteLdapInfo();
}
@ApiOperation(value = "ad域账号登录", notes = "ad域账号登录")
@PostMapping(value = "/login")
public String login(HttpServletRequest request,
@RequestParam(value = "username") String username,
@RequestParam(value = "password") String password) {
return adService.login(request, username, password);
}
@ApiOperation(value = "测试ad账号连接", notes = "测试ad账号连接")
@PostMapping(value = "/connect")
public void connect(@RequestParam(value = "host") String host,
@RequestParam(value = "port") String port,
@RequestParam(value = "username") String username,
@RequestParam(value = "password") String password) {
logger.info("connect start. host:{},port:{},username:{},password:{}", host, port, username, password);
try {
LdapContext ctx = null;
Hashtable<String, String> hashEnv = new Hashtable<>();
//AD的用户名
hashEnv.put(Context.SECURITY_PRINCIPAL, username);
//AD的密码
hashEnv.put(Context.SECURITY_CREDENTIALS, password);
// LDAP工厂类
hashEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
hashEnv.put("com.sun.jndi.ldap.connect.timeout", DEFAULT_TIME_OUT);
// 默认端口389
hashEnv.put(Context.PROVIDER_URL, "ldap://" + host + ":" + port);
try {
// 初始化上下文
ctx = new InitialLdapContext(hashEnv, null);
logger.info("{}身份验证成功!", username);
} catch (AuthenticationException e) {
logger.error("身份验证失败!", e);
} catch (javax.naming.CommunicationException e) {
logger.error("AD域连接失败!", e);
} catch (Exception e) {
logger.error("身份验证未知异常!", e);
} finally {
if (null != ctx) {
try {
ctx.close();
} catch (Exception e) {
logger.error("上下文关闭错误!", e);
}
}
}
} catch (Exception e) {
logger.error("未知异常!", e);
}
}
@ApiOperation(value = "连接查询用户", notes = "连接查询用户")
@PostMapping(value = "/connectAndSearchUser")
public Object connectAndSearchUser(@RequestParam(value = "host") String host,
@RequestParam(value = "port") String port,
@RequestParam(value = "username") String username,
@RequestParam(value = "dn") String dn,
@RequestParam(value = "password") String password,
@RequestParam(value = "searchuser") String searchuser) {
logger.info("connect start. host:{},port:{},username:{},password:{},dn:{}", host, port, username, password, dn);
List<Map<String, String>> users = new ArrayList<>();
try {
String initialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
String providerUrl = "ldap://" + host + ":" + port;
String filterPrefix = "(&(objectCategory=Person)(sAMAccountName=";
String filterSuffix = "))";
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
env.put(Context.PROVIDER_URL, providerUrl);
env.put(Context.SECURITY_PRINCIPAL, username);
env.put(Context.SECURITY_CREDENTIALS, password);
LdapContext context = new InitialLdapContext(env, null);
logger.info("{}身份验证成功!", username);
//baseName 可以通过Softerra LDAP Browser查看
//AD-指定搜索范围为个人,并且用户名为客户端输入的用户名称
String filter = filterPrefix + searchuser + filterSuffix;
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
//AD-返回用户的名称、别名及部门
controls.setReturningAttributes(new String[]{"sAMAccountName", "cn", "department"});
NamingEnumeration<SearchResult> answer = context.search(dn, filter, controls);
while (answer.hasMore()) {
SearchResult result = answer.next();
Map<String, String> user = new HashMap<>();
Attributes attrs = result.getAttributes();
Attribute attr = attrs.get("sAMAccountName");
String name = attr == null || attr.get() == null ? null : attr.get().toString();
user.put("sAMAccountName", name);
attr = attrs.get("cn");
String alias = attr == null || attr.get() == null ? null : attr.get().toString();
user.put("cn", alias);
attr = attrs.get("department");
String dept = attr == null || attr.get() == null ? null : attr.get().toString();
user.put("department", dept);
users.add(user);
}
} catch (Exception e) {
logger.error("查询用户报错!", e);
}
return users;
}
@ApiOperation(value = "连接查询用户", notes = "连接查询用户")
@PostMapping(value = "/searchAllUser")
public void searchAllUser(@RequestParam(value = "host") String host,
@RequestParam(value = "port") String port,
@RequestParam(value = "dn") String dn,
@RequestParam(value = "username") String username,
@RequestParam(value = "password") String password) {
logger.info("searchAllUser start. host:{},port:{},username:{},password:{},dn:{}", host, port, username, password, dn);
try {
Hashtable<String, String> hashEnv = new Hashtable<>();
String LDAP_URL = "ldap://" + host + ":" + port;
hashEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
hashEnv.put(Context.PROVIDER_URL, LDAP_URL);
hashEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
hashEnv.put(Context.SECURITY_PRINCIPAL, username);
hashEnv.put(Context.SECURITY_CREDENTIALS, password);
logger.info("env setting");
LdapContext ctx = null;
try {
// 初始化上下文
ctx = new InitialLdapContext(hashEnv, null);
logger.info("{}身份验证成功!", username);
SearchControls searchControls = new SearchControls();
searchControls.setReturningAttributes(null);
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String userSearchFilter = "(&(objectCategory=person)(objectClass=user))";
NamingEnumeration<SearchResult> answer = ctx.search(dn, userSearchFilter, searchControls);
List<Map<String, Object>> lm = new ArrayList<>();
while (answer.hasMore()) {
SearchResult result = answer.next();
NamingEnumeration<? extends Attribute> attrs = result.getAttributes().getAll();
Map<String, Object> map = new HashMap<>();
while (attrs.hasMore()) {
Attribute attr = attrs.next();
map.put(attr.getID(), attr.get());
lm.add(map);
}
}
logger.info("获取到的用户属性为:" + lm);
} catch (AuthenticationException e) {
logger.error("身份验证失败!", e);
} catch (javax.naming.CommunicationException e) {
logger.error("AD域连接失败!", e);
} catch (Exception e) {
logger.error("身份验证未知异常!", e);
} finally {
if (null != ctx) {
try {
ctx.close();
} catch (Exception e) {
logger.error("上下文关闭错误!", e);
}
}
}
} catch (Exception e) {
logger.error("未知异常!", e);
}
}
}
package com.keymobile.login.conf;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.auth.BasicAuthRequestInterceptor;
import feign.codec.Decoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
@Configuration
public class FeignClientConfig {
@Value("${security.authUser}")
private String authUser;
@Value("${security.authPwd}")
private String authPwd;
@Bean
public BasicAuthRequestInterceptor getBasicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor(authUser, authPwd);
}
@Bean
public Decoder feignDecoder() {
HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(customObjectMapper());
ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);
return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
}
public ObjectMapper customObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
return objectMapper;
}
}
\ No newline at end of file
package com.keymobile.login.conf;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.keymobile.login.api"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("sso RESTful APIs")
.description("Spring Boot Swagger2")
.termsOfServiceUrl("http://www.keymobile.com.cn/")
// .contact("keymobile")
.version("1.0")
.build();
}
}
package com.keymobile.login.exception;
/**
* @author xiesh
* @version 1.0.0
* @date 2024/11/21
* @desc
*/
public class LdapException extends Exception{
private static final long serialVersionUID = 1L;
public LdapException(String errorMsg) {
super(errorMsg);
}
public LdapException(String errorMsg, Throwable cause) {
super(errorMsg, cause);
}
}
package com.keymobile.login.persistence;
import com.keymobile.login.persistence.model.LdapInfo;
import org.springframework.data.repository.CrudRepository;
import javax.transaction.Transactional;
@Transactional
public interface LdapInfoRepository extends CrudRepository<LdapInfo, String> {
}
package com.keymobile.login.persistence.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* @author xiesh
* @version 1.0.0
* @date 2024/4/26
* @desc
*/
@Entity
@Table(name = "sso_ldap_info")
public class LdapInfo {
@Id
private String id;
@Column(name = "HOST", nullable = false)
private String host;
@Column(name = "PORT", nullable = false)
private String port;
@Column(name = "USER_NAME", nullable = false)
private String username;
@Column(name = "PASSWORD", nullable = false)
private String password;
@Column(name = "DN", nullable = false)
private String dn;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDn() {
return dn;
}
public void setDn(String dn) {
this.dn = dn;
}
}
package com.keymobile.login.service;
import com.keymobile.login.persistence.model.LdapInfo;
import org.springframework.web.bind.annotation.RequestBody;
import javax.servlet.http.HttpServletRequest;
/**
* @author xiesh
* @version 1.0.0
* @date 2024/11/20
* @desc ad域服务
*/
public interface ADService {
LdapInfo saveLdapInfo(LdapInfo ldapInfo);
LdapInfo getLdapInfo();
void deleteLdapInfo();
String ldapAuthentication(String username, String password);
String login(HttpServletRequest request, String username, String password) ;
}
package com.keymobile.login.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@FeignClient(value = "authService")
public interface AuthRemoteService {
@RequestMapping(value = "/users/findByName")
List<Map<String, Object>> getUserByName(@RequestParam(value = "match") String match);
@PostMapping(value = "/users")
Map<String, Object> addUser(@RequestBody Map<String, Object> user);
@PostMapping(value = "/users/{userId}")
Map<String, Object> updateUser(@PathVariable(value = "userId") Long userId, @RequestBody Map<String, Object> user);
}
package com.keymobile.login.service.impl;
import com.keymobile.auth.common.security.CustomizedUserDetailService;
import com.keymobile.crypto.aes.AESUtil;
import com.keymobile.login.api.ADApi;
import com.keymobile.login.api.Constants;
import com.keymobile.login.exception.LdapException;
import com.keymobile.login.logging.LogConstants;
import com.keymobile.login.logging.LogManager;
import com.keymobile.login.persistence.LdapInfoRepository;
import com.keymobile.login.persistence.model.LdapInfo;
import com.keymobile.login.service.ADService;
import com.keymobile.login.service.AuthRemoteService;
import com.keymobile.login.util.AES;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.*;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author xiesh
* @version 1.0.0
* @date 2024/11/20
* @desc ad域服务实现
*/
@Service
public class ADServiceImpl implements ADService {
@Autowired
private LdapInfoRepository ldapInfoRepository;
private static final Logger logger = LoggerFactory.getLogger(ADApi.class);
private static String DEFAULT_TIME_OUT = "5000";
@Autowired
private AuthRemoteService authService;
@Autowired
private CustomizedUserDetailService customizedUserDetailService;
public static final String LDAP_ID = "ldap";
public static final String LADP_S_AMACCOUNT_NAME = "sAMAccountName";
public static final String LADP_DISTINGUISHED_NAME = "distinguishedName";
public static final String LADP_CN = "cn";
@Override
public LdapInfo saveLdapInfo(LdapInfo ldapInfo) {
ldapInfo.setId(LDAP_ID);
LdapInfo oldLdap = getLdapInfo();
if (oldLdap == null || !StringUtils.equals(ldapInfo.getPassword(), oldLdap.getPassword())) {
ldapInfo.setPassword(AES.encrypt(ldapInfo.getPassword()));
}
return ldapInfoRepository.save(ldapInfo);
}
@Override
public LdapInfo getLdapInfo() {
return ldapInfoRepository.findById(LDAP_ID).orElse(null);
}
@Override
public void deleteLdapInfo() {
ldapInfoRepository.deleteAll();
}
@Override
public String ldapAuthentication(String username, String password) {
LdapInfo ldapInfo = getLdapInfo();
if (ldapInfo == null) {
return "未配置ldap";
}
String result = "ok";
LdapContext ctx = null;
Hashtable<String, String> HashEnv = new Hashtable<>();
String dn = ldapInfo.getDn();
//拼接ldap可识别的用户名 用户名@域名
String ldapUserName = username + "@" + dn;
String url = "ldap://" + ldapInfo.getHost() + ":" + ldapInfo.getPort();
// LDAP访问安全级别(none,simple,strong)
// HashEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
//AD的用户名
HashEnv.put(Context.SECURITY_PRINCIPAL, ldapUserName);
//AD的密码
HashEnv.put(Context.SECURITY_CREDENTIALS, password);
// LDAP工厂类
HashEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
HashEnv.put("com.sun.jndi.ldap.connect.timeout", DEFAULT_TIME_OUT);
// 默认端口389
HashEnv.put(Context.PROVIDER_URL, url);
logger.debug("ad域账号校验,url:{},username:{},password:{},", url, ldapUserName, password);
try {
// 初始化上下文
ctx = new InitialLdapContext(HashEnv, null);
logger.info("{}身份验证成功!", username);
} catch (Exception e) {
logger.error("身份验证异常!", e);
result = "身份验证异常";
} finally {
if (null != ctx) {
try {
ctx.close();
} catch (Exception e) {
logger.error("上下文关闭错误!", e);
}
}
}
return result;
}
@Override
public String login(HttpServletRequest request, String username, String password) {
String result = null;
try {
result = ldapAuthentication(username, password);
if (StringUtils.equals(result, "ok")) {
Map<String, Object> user = getUserByName(username);
if (null == user || CollectionUtils.isEmpty(user)) {
Map<String, String> ldapUserInfo = searchUserInfoByName(username);
Map<String, Object> toAdd = new HashMap<>();
toAdd.put("name", username);
toAdd.put("dname", ldapUserInfo.get(LADP_CN) == null ? username : ldapUserInfo.get(LADP_CN));
//不能被匹配的加密字符
toAdd.put("password", "37fa265330ad83eaa879efb12312db6380896cf639");
logger.info("新增用户:{}", toAdd);
authService.addUser(toAdd);
}
//设置用户session
UserDetails userDetails = customizedUserDetailService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
HttpSession session = request.getSession(true);
session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());
logger.info("单点登录用户:" + username);
MDC.put("user", username);
MDC.put("session", session.getId());
LogManager.logInfo(LogConstants.CTX_API, "统一账号认证登录");
}
} catch (Exception e) {
logger.error("登录异常!", e);
result = e.getMessage();
}
return result;
}
private Map<String, String> searchUserInfoByName(String searchName) throws Exception {
LdapInfo ldapInfo = getLdapInfo();
if (ldapInfo == null) {
throw new LdapException("未配置ldap信息");
}
Map<String, String> userInfo = new HashMap<>();
Hashtable<String, String> HashEnv = new Hashtable<>();
String ldapUrl = "ldap://" + ldapInfo.getHost() + ":" + ldapInfo.getPort();
String ldapUser = ldapInfo.getUsername() + "@" + ldapInfo.getDn();
String password = AES.decrypt(ldapInfo.getPassword());
HashEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
HashEnv.put(Context.PROVIDER_URL, ldapUrl);
// HashEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
HashEnv.put(Context.SECURITY_PRINCIPAL, ldapUser);
HashEnv.put(Context.SECURITY_CREDENTIALS, password);
logger.info("env setting");
LdapContext ctx = null;
String[] dnArg = StringUtils.split(ldapInfo.getDn(), ".");
List<String> dnString = Arrays.asList(dnArg).stream().map(e -> "DC=" + e).collect(Collectors.toList());
String dnStr = StringUtils.join(dnString, ",");
try {
logger.debug("ad域账号校验,url:{},username:{},password:{},dnStr:{}", ldapUrl, ldapUser, password, dnStr);
// 初始化上下文
ctx = new InitialLdapContext(HashEnv, null);
logger.info("{}身份验证成功!", ldapInfo.getUsername());
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchControls.setReturningAttributes(new String[]{LADP_S_AMACCOUNT_NAME, LADP_CN, LADP_DISTINGUISHED_NAME});
String userSearchFilter = String.format("(&(objectCategory=person)(objectClass=user)(sAMAccountName=%s))", searchName);
NamingEnumeration<SearchResult> answer = ctx.search(dnStr, userSearchFilter, searchControls);
logger.debug("查询,dnStr:{},userSearchFilter:{},searchName:{}", dnStr, userSearchFilter, searchName);
if (answer.hasMore()) {
SearchResult result = answer.next();
Attributes attrs = result.getAttributes();
Attribute attr = attrs.get(LADP_S_AMACCOUNT_NAME);
String name = attr == null || attr.get() == null ? null : attr.get().toString();
userInfo.put(LADP_S_AMACCOUNT_NAME, name);
attr = attrs.get(LADP_CN);
String alias = attr == null || attr.get() == null ? null : attr.get().toString();
userInfo.put(LADP_CN, alias);
attr = attrs.get(LADP_DISTINGUISHED_NAME);
String dept = attr == null || attr.get() == null ? null : attr.get().toString();
userInfo.put(LADP_DISTINGUISHED_NAME, dept);
} else {
logger.info("查询不到用户:{}", searchName);
}
} catch (Exception e) {
throw e;
} finally {
if (null != ctx) {
try {
ctx.close();
} catch (Exception e) {
logger.error("上下文关闭错误!", e);
}
}
}
logger.debug("查询结果,userInfo:{}", userInfo);
return userInfo;
}
private Map<String, Object> getUserByName(String username) {
List<Map<String, Object>> matchUser = authService.getUserByName(username);
if (matchUser != null) {
Map<String, Object> user = matchUser.stream().filter(e -> StringUtils.equals(username, String.valueOf(e.get("name"))))
.findFirst().orElse(null);
return user;
}
return null;
}
}
package com.keymobile.login.util;
import org.apache.commons.lang.StringUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class AES {
//编码方式
public static final String CODE_TYPE = "UTF-8";
//填充类型
public static final String AES_TYPE = "AES/ECB/PKCS5Padding";
//私钥
private static String AES_KEY = "4444111133332222"; //AES固定格式为128/192/256 bits.即:16/24/32bytes。DES固定格式为128bits,即8bytes。
/**
* 加密
*
* @param cleartext
* @return
*/
public static String encrypt(String cleartext) {
//加密方式: AES128(CBC/PKCS5Padding) + Base64, 私钥:1111222233334444
try {
if(StringUtils.isNotBlank(cleartext)){
//IvParameterSpec zeroIv = new IvParameterSpec(VIPARA.getBytes());
//两个参数,第一个为私钥字节数组, 第二个为加密方式 AES或者DES
SecretKeySpec key = new SecretKeySpec(AES_KEY.getBytes(), "AES");
//实例化加密类,参数为加密方式,要写全
Cipher cipher = Cipher.getInstance(AES_TYPE); //PKCS5Padding比PKCS7Padding效率高,PKCS7Padding可支持IOS加解密
//初始化,此方法可以采用三种方式,按加密算法要求来添加。(1)无第三个参数(2)第三个参数为SecureRandom random = new SecureRandom();中random对象,随机数。(AES不可采用这种方法)(3)采用此代码中的IVParameterSpec
//加密时使用:ENCRYPT_MODE; 解密时使用:DECRYPT_MODE;
cipher.init(Cipher.ENCRYPT_MODE, key); //CBC类型的可以在第三个参数传递偏移量zeroIv,ECB没有偏移量
//加密操作,返回加密后的字节数组,然后需要编码。主要编解码方式有Base64, HEX, UUE,7bit等等。此处看服务器需要什么编码方式
byte[] encryptedData = cipher.doFinal(cleartext.getBytes(CODE_TYPE));
return new BASE64Encoder().encode(encryptedData);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 解密
*
* @param encrypted
* @return
*/
public static String decrypt(String encrypted) {
try {
if(StringUtils.isNotBlank(encrypted)){
byte[] byteMi = new BASE64Decoder().decodeBuffer(encrypted);
//IvParameterSpec zeroIv = new IvParameterSpec(VIPARA.getBytes());
SecretKeySpec key = new SecretKeySpec(AES_KEY.getBytes(), "AES");
Cipher cipher = Cipher.getInstance(AES_TYPE);
//与加密时不同MODE:Cipher.DECRYPT_MODE
cipher.init(Cipher.DECRYPT_MODE, key); //CBC类型的可以在第三个参数传递偏移量zeroIv,ECB没有偏移量
byte[] decryptedData = cipher.doFinal(byteMi);
return new String(decryptedData, CODE_TYPE);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void setAesKey(String aesKey){
AES_KEY = aesKey;
}
/**
* 测试
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
String pass = new String("Szse@pwd0528");
setAesKey("4444111133332222");
System.out.println("加密内容:"+encrypt(pass));
String content = new String(encrypt(pass));
System.out.println("解密内容:"+decrypt(content));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment