OAUTH
This commit is contained in:
parent
a93959f1f2
commit
bfd6ec188b
|
|
@ -113,6 +113,11 @@
|
||||||
<artifactId>spring-security-oauth2</artifactId>
|
<artifactId>spring-security-oauth2</artifactId>
|
||||||
<version>2.5.2.RELEASE</version>
|
<version>2.5.2.RELEASE</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-jwt</artifactId>
|
||||||
|
<version>1.1.1.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.bonus.auth.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
|
||||||
|
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
|
||||||
|
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
|
||||||
|
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
|
||||||
|
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
|
||||||
|
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||||
|
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
|
||||||
|
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableAuthorizationServer
|
||||||
|
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
|
// Configure the token store and JWT converter
|
||||||
|
@Bean
|
||||||
|
public TokenStore tokenStore() {
|
||||||
|
return new JwtTokenStore(accessTokenConverter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public JwtAccessTokenConverter accessTokenConverter() {
|
||||||
|
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
|
||||||
|
converter.setSigningKey("your-256-bit-secret"); // Use a secure key in production
|
||||||
|
return converter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure security constraints on the token endpoint
|
||||||
|
@Override
|
||||||
|
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
|
||||||
|
security.tokenKeyAccess("permitAll()") // Public key for token verification
|
||||||
|
.checkTokenAccess("isAuthenticated()") // Token validation endpoint
|
||||||
|
.allowFormAuthenticationForClients();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure client details service
|
||||||
|
@Override
|
||||||
|
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
|
||||||
|
clients.inMemory()
|
||||||
|
.withClient("client-id") // Your client ID
|
||||||
|
.secret(passwordEncoder.encode("client-secret")) // Your client secret
|
||||||
|
.authorizedGrantTypes("password", "refresh_token")
|
||||||
|
.scopes("read", "write")
|
||||||
|
.accessTokenValiditySeconds(3600) // 1 hour
|
||||||
|
.refreshTokenValiditySeconds(86400); // 24 hours
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure the endpoints
|
||||||
|
@Override
|
||||||
|
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
|
||||||
|
endpoints.authenticationManager(authenticationManager)
|
||||||
|
.tokenStore(tokenStore())
|
||||||
|
.accessTokenConverter(accessTokenConverter());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,149 +1,132 @@
|
||||||
//package com.bonus.auth.controller;
|
package com.bonus.auth.controller;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.utils.UuidUtils;
|
||||||
|
import com.bonus.common.core.constant.SecurityConstants;
|
||||||
|
import com.bonus.common.core.utils.encryption.Sm4Utils;
|
||||||
|
import com.bonus.common.core.web.domain.AjaxResult;
|
||||||
|
import com.bonus.common.security.utils.SecurityUtils;
|
||||||
|
import com.bonus.system.api.RemoteUserService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||||
|
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||||
|
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
|
||||||
|
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/ticket")
|
||||||
|
public class TicketController {
|
||||||
|
@Resource
|
||||||
|
private RemoteUserService remoteUserService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
public RedisTemplate<String, String> redisTemplate;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TokenStore tokenStore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得用户token、userId、当前时间加密的字符串
|
||||||
|
* 跳转第三方菜单时,获取 登录凭证 Ticket
|
||||||
|
* 将Ticket记录在redis中,设置时效 60s,记录用户id、用户的token、和当前时间
|
||||||
|
*/
|
||||||
|
@GetMapping("getUserTicket")
|
||||||
|
public String getUserTicket() {
|
||||||
|
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
if (authentication instanceof OAuth2Authentication) {
|
||||||
|
Object details = authentication.getDetails();
|
||||||
|
if (details instanceof OAuth2AuthenticationDetails) {
|
||||||
|
OAuth2AuthenticationDetails detail = (OAuth2AuthenticationDetails) details;
|
||||||
|
String tokenValue = detail.getTokenValue();
|
||||||
|
String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
|
||||||
|
Long userId = SecurityUtils.getUserId();
|
||||||
|
String ticket = tokenValue + "," + dateStr + "," + userId;
|
||||||
|
String encryptedString = Sm4Utils.encrypt(ticket);
|
||||||
|
if (encryptedString != null) {
|
||||||
|
String uuid = UuidUtils.generateUuid();
|
||||||
|
redisTemplate.opsForValue().set(uuid, encryptedString, 60, TimeUnit.SECONDS);
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new RuntimeException("未知错误");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录凭证 Ticket校验
|
||||||
|
* 第三方系统拿到Ticket后需要校验该Ticket有效性,校验通过返回用户信息
|
||||||
|
* @param ticket:登录凭证
|
||||||
|
* @param appId:第三方系统注册颁发的APPID,唯一标识,用来控制第三方系统的接入
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("validate")
|
||||||
|
public AjaxResult getUserInfo(String ticket, String appId) {
|
||||||
|
if (appId==null || "".equals(appId)) {
|
||||||
|
log.error("第三方系统Ticket校验失败: ticket:{} 结果 :{} ",ticket,"APPID为空");
|
||||||
|
return new AjaxResult(10000, "APPID为空!");
|
||||||
|
}
|
||||||
|
if (ticket==null || "".equals(ticket)) {
|
||||||
|
log.error("第三方系统Ticket校验失败:appId:{} 结果 :{} ",appId,"令牌为空");
|
||||||
|
return new AjaxResult(10001, "令牌为空!");
|
||||||
|
}
|
||||||
|
|
||||||
|
String encryptedString = redisTemplate.opsForValue().get(ticket);
|
||||||
|
if (StringUtils.isBlank(encryptedString)) {
|
||||||
|
log.error("第三方系统Ticket校验失败:appId:{} ticket:{} 结果 :{} ",appId,ticket,"令牌已失效");
|
||||||
|
return new AjaxResult(10003, "令牌已失效!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String realTicket = Sm4Utils.decrypt(encryptedString);
|
||||||
|
if (StringUtils.isBlank(realTicket)) {
|
||||||
|
log.error("第三方系统Ticket校验失败:appId:{} ticket:{} 结果 :{} ",appId,ticket,"令牌解析错误");
|
||||||
|
return new AjaxResult(10004, "令牌解析错误!");
|
||||||
|
}
|
||||||
|
String[] ticketInfoArr = realTicket.split(",");
|
||||||
|
|
||||||
|
String tokenValue = ticketInfoArr[0];
|
||||||
|
OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
|
||||||
|
if (accessToken == null || StringUtils.isEmpty(accessToken.getValue())) {
|
||||||
|
log.error("第三方系统Ticket校验失败:appId:{} ticket:{} 结果 :{} ",appId,ticket,"当前用户已离线,请重新登录");
|
||||||
|
return new AjaxResult(10005, "当前用户已离线,请重新登录!");
|
||||||
|
}
|
||||||
|
String userId = ticketInfoArr[2];
|
||||||
|
AjaxResult result = remoteUserService.getInfo(Long.parseLong(userId), SecurityConstants.INNER);
|
||||||
|
|
||||||
|
|
||||||
|
// Map<String, Object> resMap = new HashMap<>();
|
||||||
|
// resMap.put("userName", sysUser.getUserName());
|
||||||
|
// resMap.put("name", sysUser.getNickName());
|
||||||
|
// resMap.put("deptId", sysUser.getDeptId());
|
||||||
|
// resMap.put("deptName", sysUser.getDept() == null ? null : sysUser.getDept().getDeptName().replaceAll("YJ", ""));
|
||||||
//
|
//
|
||||||
//import com.alibaba.nacos.common.utils.UuidUtils;
|
// SysDept dept = sysUser.getDept();
|
||||||
//import com.bonus.common.core.constant.SecurityConstants;
|
// 特定的业务需求,需要记录当前用户是否为运检站,并且返回 xx站
|
||||||
//import com.bonus.common.core.utils.encryption.Sm4Utils;
|
// if (dept != null) {
|
||||||
//import com.bonus.common.core.web.domain.AjaxResult;
|
// if ("4".equals(dept.getDeptType()) && dept.getDeptName().contains("站")) {
|
||||||
//import com.bonus.common.security.utils.SecurityUtils;
|
// resMap.put("businessDeptName", dept.getDeptName().replaceAll("YJ", ""));
|
||||||
//import com.bonus.system.api.RemoteUserService;
|
// } else {
|
||||||
//import com.bonus.system.api.domain.SysDept;
|
// resMap.put("businessDeptName", "");
|
||||||
//import com.bonus.system.api.domain.SysUser;
|
|
||||||
//import lombok.extern.slf4j.Slf4j;
|
|
||||||
//import org.apache.commons.lang3.StringUtils;
|
|
||||||
//import org.springframework.data.redis.core.RedisTemplate;
|
|
||||||
//import org.springframework.security.core.Authentication;
|
|
||||||
//import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
//import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
|
||||||
//import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
|
||||||
//import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
|
|
||||||
//import org.springframework.security.oauth2.provider.token.TokenStore;
|
|
||||||
//import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
//import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
//import org.springframework.web.bind.annotation.RestController;
|
|
||||||
//import javax.annotation.Resource;
|
|
||||||
//import java.text.SimpleDateFormat;
|
|
||||||
//import java.util.Date;
|
|
||||||
//import java.util.HashMap;
|
|
||||||
//import java.util.Map;
|
|
||||||
//import java.util.concurrent.TimeUnit;
|
|
||||||
//
|
|
||||||
///**
|
|
||||||
// * 第三方系统接入
|
|
||||||
// * @author semdo
|
|
||||||
// */
|
|
||||||
//@Slf4j
|
|
||||||
//@RestController
|
|
||||||
//@RequestMapping("/ticket")
|
|
||||||
//public class TicketController {
|
|
||||||
// @Resource
|
|
||||||
// private RemoteUserService remoteUserService;
|
|
||||||
//
|
|
||||||
// @Resource
|
|
||||||
// public RedisTemplate<String, String> redisTemplate;
|
|
||||||
//
|
|
||||||
// @Resource
|
|
||||||
// private TokenStore tokenStore;
|
|
||||||
//
|
|
||||||
// @Resource
|
|
||||||
// private ISysThirdClientAccreditService thirdClientAccreditService;
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 获得用户token、userId、当前时间加密的字符串
|
|
||||||
// * 跳转第三方菜单时,获取 登录凭证 Ticket
|
|
||||||
// * 将Ticket记录在redis中,设置时效 60s,记录用户id、用户的token、和当前时间
|
|
||||||
// */
|
|
||||||
// @GetMapping("getUserTicket")
|
|
||||||
// public String getUserTicket() {
|
|
||||||
// Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
|
||||||
// if (authentication instanceof OAuth2Authentication) {
|
|
||||||
// Object details = authentication.getDetails();
|
|
||||||
// if (details instanceof OAuth2AuthenticationDetails) {
|
|
||||||
// OAuth2AuthenticationDetails detail = (OAuth2AuthenticationDetails) details;
|
|
||||||
// String tokenValue = detail.getTokenValue();
|
|
||||||
// String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
|
|
||||||
// Long userId = SecurityUtils.getUserId();
|
|
||||||
// String ticket = tokenValue + "," + dateStr + "," + userId;
|
|
||||||
// String encryptedString = Sm4Utils.encrypt(ticket);
|
|
||||||
// if (encryptedString != null) {
|
|
||||||
// String uuid = UuidUtils.generateUuid();
|
|
||||||
// redisTemplate.opsForValue().set(uuid, encryptedString, 60, TimeUnit.SECONDS);
|
|
||||||
// return uuid;
|
|
||||||
// }
|
|
||||||
// }
|
// }
|
||||||
|
// } else {
|
||||||
|
// resMap.put("businessDeptName", "");
|
||||||
// }
|
// }
|
||||||
// throw new RuntimeException("未知错误");
|
|
||||||
// }
|
log.info("第三方系统Ticket校验成功:appId:{} ticket:{} Ticket生成时间:{}",appId,ticket,ticketInfoArr[1]);
|
||||||
//
|
return AjaxResult.success(result);
|
||||||
// /**
|
}
|
||||||
// * 登录凭证 Ticket校验
|
|
||||||
// * 第三方系统拿到Ticket后需要校验该Ticket有效性,校验通过返回用户信息
|
}
|
||||||
// * @param ticket:登录凭证
|
|
||||||
// * @param appId:第三方系统注册颁发的APPID,唯一标识,用来控制第三方系统的接入
|
|
||||||
// * @return
|
|
||||||
// */
|
|
||||||
// @GetMapping("validate")
|
|
||||||
// public AjaxResult getUserInfo(String ticket, String appId) {
|
|
||||||
// if (appId==null || "".equals(appId)) {
|
|
||||||
// log.error("第三方系统Ticket校验失败: ticket:{} 结果 :{} ",ticket,"APPID为空");
|
|
||||||
// return new AjaxResult(10000, "APPID为空!");
|
|
||||||
// }
|
|
||||||
// if (ticket==null || "".equals(ticket)) {
|
|
||||||
// log.error("第三方系统Ticket校验失败:appId:{} 结果 :{} ",appId,"令牌为空");
|
|
||||||
// return new AjaxResult(10001, "令牌为空!");
|
|
||||||
// }
|
|
||||||
// boolean appStatus = thirdClientAccreditService.getAppStatusByAppId(appId);
|
|
||||||
//
|
|
||||||
// if (!appStatus) {
|
|
||||||
// log.error("第三方系统Ticket校验失败:appId:{} ticket:{} 结果 :{} ",appId,ticket,"应用不可用");
|
|
||||||
// return new AjaxResult(10002, "应用不可用!");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// String encryptedString = redisTemplate.opsForValue().get(ticket);
|
|
||||||
// if (StringUtils.isBlank(encryptedString)) {
|
|
||||||
// log.error("第三方系统Ticket校验失败:appId:{} ticket:{} 结果 :{} ",appId,ticket,"令牌已失效");
|
|
||||||
// return new AjaxResult(10003, "令牌已失效!");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// String realTicket = Sm4Utils.decrypt(encryptedString);
|
|
||||||
// if (StringUtils.isBlank(realTicket)) {
|
|
||||||
// log.error("第三方系统Ticket校验失败:appId:{} ticket:{} 结果 :{} ",appId,ticket,"令牌解析错误");
|
|
||||||
// return new AjaxResult(10004, "令牌解析错误!");
|
|
||||||
// }
|
|
||||||
// String[] ticketInfoArr = realTicket.split(",");
|
|
||||||
//
|
|
||||||
// String tokenValue = ticketInfoArr[0];
|
|
||||||
// OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
|
|
||||||
// if (accessToken == null || StringUtils.isEmpty(accessToken.getValue())) {
|
|
||||||
// log.error("第三方系统Ticket校验失败:appId:{} ticket:{} 结果 :{} ",appId,ticket,"当前用户已离线,请重新登录");
|
|
||||||
// return new AjaxResult(10005, "当前用户已离线,请重新登录!");
|
|
||||||
// }
|
|
||||||
// String userId = ticketInfoArr[2];
|
|
||||||
// AjaxResult result = remoteUserService.getInfo(Long.parseLong(userId), SecurityConstants.INNER);
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//// Map<String, Object> resMap = new HashMap<>();
|
|
||||||
//// resMap.put("userName", sysUser.getUserName());
|
|
||||||
//// resMap.put("name", sysUser.getNickName());
|
|
||||||
//// resMap.put("deptId", sysUser.getDeptId());
|
|
||||||
//// resMap.put("deptName", sysUser.getDept() == null ? null : sysUser.getDept().getDeptName().replaceAll("YJ", ""));
|
|
||||||
////
|
|
||||||
//// SysDept dept = sysUser.getDept();
|
|
||||||
// // 特定的业务需求,需要记录当前用户是否为运检站,并且返回 xx站
|
|
||||||
//// if (dept != null) {
|
|
||||||
//// if ("4".equals(dept.getDeptType()) && dept.getDeptName().contains("站")) {
|
|
||||||
//// resMap.put("businessDeptName", dept.getDeptName().replaceAll("YJ", ""));
|
|
||||||
//// } else {
|
|
||||||
//// resMap.put("businessDeptName", "");
|
|
||||||
//// }
|
|
||||||
//// } else {
|
|
||||||
//// resMap.put("businessDeptName", "");
|
|
||||||
//// }
|
|
||||||
//
|
|
||||||
// log.info("第三方系统Ticket校验成功:appId:{} ticket:{} Ticket生成时间:{}",appId,ticket,ticketInfoArr[1]);
|
|
||||||
// return AjaxResult.success(result);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue