cas单点登录
This commit is contained in:
parent
d9222f25e1
commit
214bf4bc61
|
@ -293,6 +293,13 @@
|
|||
<version>${ffmpeg.version}-${javacv.version}</version>
|
||||
<classifier>${system.linux-x86_64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.unicon.cas</groupId>
|
||||
<artifactId>cas-client-autoconfig-support</artifactId>
|
||||
<version>2.0.0-GA</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -1,4 +1,100 @@
|
|||
package io.renren.modules.security.oauth2;
|
||||
|
||||
public class CasSSOValidator {
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jasig.cas.client.validation.Assertion;
|
||||
import org.jasig.cas.client.validation.TicketValidationException;
|
||||
import org.jasig.cas.client.validation.json.Cas30JsonServiceTicketValidator;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Component
|
||||
@ConditionalOnProperty(prefix = "sso", name = "mode", havingValue = "cas")
|
||||
public class CasSSOValidator implements SSOValidator {
|
||||
|
||||
@Value("${cas.server-url-prefix}")
|
||||
private String serverUrlPrefix;
|
||||
@Value("${cas.server-login-url}")
|
||||
private String serverLoginUrl;
|
||||
@Value("${cas.client-host-url}")
|
||||
private String clientHostUrl;
|
||||
|
||||
private Cas30JsonServiceTicketValidator ticketValidator;
|
||||
|
||||
@PostConstruct
|
||||
public void init(){
|
||||
ticketValidator = new Cas30JsonServiceTicketValidator(serverUrlPrefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String validatePrincipal(String requestURL) {
|
||||
String ticket = getParema(requestURL, "ticket");
|
||||
try {
|
||||
Assertion validate = ticketValidator.validate(ticket, removeCreditParame(requestURL));
|
||||
if (validate != null) return validate.getPrincipal().getName();
|
||||
} catch (TicketValidationException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCrediteInCallBackUrl(String url) {
|
||||
return url != null && url.indexOf("ticket=") > -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String removeCreditParame(String url) {
|
||||
|
||||
|
||||
try {
|
||||
URL matchUrl = new URL(url);
|
||||
String query = matchUrl.getQuery();
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
if (query == null){
|
||||
return url;
|
||||
}
|
||||
String[] split = query.split("&");
|
||||
for (String s : split) {
|
||||
if (s.startsWith("ticket")) continue;
|
||||
stringBuilder.append(s);
|
||||
stringBuilder.append("&");
|
||||
}
|
||||
|
||||
String newQuery = stringBuilder.toString();
|
||||
if (newQuery.endsWith("&")) newQuery = newQuery.substring(0, newQuery.length()-1);
|
||||
return url.replace(StringUtils.isBlank(newQuery) ? "?"+query:query, newQuery);
|
||||
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
return url;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLoginUrl(String callBackUrl) {
|
||||
return serverLoginUrl + "?service=" + URLEncoder.encode(removeCreditParame(callBackUrl));
|
||||
}
|
||||
|
||||
private static String getParema(String urlStr, String field) {
|
||||
String result = "";
|
||||
Pattern pXM = Pattern.compile(field + "=([^&|^#]*)");
|
||||
Matcher mXM = pXM.matcher(urlStr);
|
||||
while (mXM.find()) {
|
||||
result = mXM.group(1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.apache.http.HttpStatus;
|
|||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
|
||||
import org.jasig.cas.client.authentication.AuthenticationFilter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
|
@ -42,8 +43,7 @@ import java.util.Map;
|
|||
@Scope("prototype")
|
||||
public class Oauth2Filter extends AuthenticatingFilter {
|
||||
|
||||
@Autowired
|
||||
private YaweiSSOProperties yaweiSSOProperties;
|
||||
|
||||
|
||||
@Autowired
|
||||
private SysUserTokenService sysUserTokenService;
|
||||
|
@ -51,8 +51,8 @@ public class Oauth2Filter extends AuthenticatingFilter {
|
|||
@Autowired
|
||||
private SysUserDao sysUserDao;
|
||||
|
||||
@Value("${yawei.enable}")
|
||||
private Boolean yaweiEnable;
|
||||
@Autowired
|
||||
private SSOValidator ssoValidator;
|
||||
|
||||
@Override
|
||||
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
|
||||
|
@ -93,11 +93,9 @@ public class Oauth2Filter extends AuthenticatingFilter {
|
|||
@Override
|
||||
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
|
||||
|
||||
if (yaweiEnable) {
|
||||
return yaweiHandle((HttpServletRequest) request, (HttpServletResponse) response);
|
||||
if (ssoValidator != null) {
|
||||
return ssoHandle((HttpServletRequest) request, (HttpServletResponse) response);
|
||||
}else {
|
||||
String requesturi = ((HttpServletRequest) request).getHeader("REQUESTURI");
|
||||
|
||||
((HttpServletResponse)response).addHeader("REDIRECT", "/#/login");
|
||||
|
||||
}
|
||||
|
@ -167,88 +165,49 @@ public class Oauth2Filter extends AuthenticatingFilter {
|
|||
return token;
|
||||
}
|
||||
|
||||
private boolean yaweiHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
private boolean ssoHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
// 获取当前请求的url
|
||||
String requestUri = request.getHeader("REQUESTURI");
|
||||
if (requestUri == null) {
|
||||
requestUri = request.getRequestURI();
|
||||
}
|
||||
|
||||
String strResponse = request.getParameter(yaweiSSOProperties.getSsoKey());
|
||||
|
||||
if (strResponse == null && requestUri != null && requestUri.indexOf(yaweiSSOProperties.getSsoKey()) > 0) {
|
||||
String ssoMatchKey = yaweiSSOProperties.getSsoKey() + "=";
|
||||
int startIndex = requestUri.indexOf(ssoMatchKey) + ssoMatchKey.length();
|
||||
int indexOf = requestUri.indexOf("&", startIndex);
|
||||
|
||||
strResponse = indexOf > 0 ? requestUri.substring(startIndex, indexOf) : requestUri.substring(startIndex);
|
||||
if (!ssoValidator.hasCrediteInCallBackUrl(requestUri)) {
|
||||
redirectToUrl(ssoValidator.getLoginUrl(requestUri), response);
|
||||
return false;
|
||||
}
|
||||
if (org.apache.commons.lang.StringUtils.isEmpty(strResponse)) {
|
||||
TicketManager tm = new TicketManager();
|
||||
if (!tm.LoadTicket(request)) {
|
||||
redirectToYaweiLogin(request, response);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// 如果服务器端通过认证后,会返回后执行改操作,然后写入cookie
|
||||
SSOResponse ssoResp = new SSOResponse(strResponse);
|
||||
TicketManager tm = ssoResp.CreatePSOTicket();
|
||||
if (tm == null) {
|
||||
redirectToYaweiLogin(request, response);
|
||||
return false;
|
||||
} else {
|
||||
//认证通过
|
||||
LambdaQueryWrapper<SysUserEntity> queryWrapper = new QueryWrapper<SysUserEntity>().lambda()
|
||||
.eq(SysUserEntity::getUsername, tm.getUserID());
|
||||
SysUserEntity sysUserEntity = sysUserDao.selectOne(queryWrapper);
|
||||
if (sysUserEntity != null) {
|
||||
String currentToken = getRequestToken((HttpServletRequest) request);
|
||||
HttpServletResponse httpresponse = (HttpServletResponse) response;
|
||||
if (StringUtils.isBlank(currentToken)) {
|
||||
Result<Map> result = sysUserTokenService.createToken(sysUserEntity.getId());
|
||||
Object token = result.getData().get(Constant.TOKEN_HEADER);
|
||||
currentToken = (String) token;
|
||||
Cookie cookie = new Cookie(Constant.TOKEN_HEADER, currentToken);
|
||||
cookie.setPath("/");
|
||||
httpresponse.addCookie(cookie);
|
||||
httpresponse.addHeader(Constant.TOKEN_HEADER, currentToken);
|
||||
|
||||
String yaweiToken = yaweiSSOProperties.getSsoKey() + "=" + strResponse;
|
||||
if (requestUri.indexOf(yaweiToken) > 0) {
|
||||
requestUri = requestUri.replace(yaweiToken, "");
|
||||
if (requestUri.endsWith("?")) {
|
||||
requestUri = requestUri.substring(0,requestUri.length() -1);
|
||||
}
|
||||
}
|
||||
httpresponse.addHeader("REDIRECT", requestUri);
|
||||
}
|
||||
String principal = ssoValidator.validatePrincipal(requestUri);
|
||||
if (principal != null){
|
||||
//认证通过
|
||||
LambdaQueryWrapper<SysUserEntity> queryWrapper = new QueryWrapper<SysUserEntity>().lambda()
|
||||
.eq(SysUserEntity::getUsername, principal);
|
||||
SysUserEntity sysUserEntity = sysUserDao.selectOne(queryWrapper);
|
||||
if (sysUserEntity != null) {
|
||||
|
||||
request.setAttribute(Constant.TOKEN_HEADER, currentToken);
|
||||
return executeLogin(request, response);
|
||||
}else {
|
||||
send401Error(response, "未找到相关用户");
|
||||
}
|
||||
Result<Map> result = sysUserTokenService.createToken(sysUserEntity.getId());
|
||||
Object token = result.getData().get(Constant.TOKEN_HEADER);
|
||||
String currentToken = (String) token;
|
||||
Cookie cookie = new Cookie(Constant.TOKEN_HEADER, currentToken);
|
||||
cookie.setPath("/");
|
||||
response.addCookie(cookie);
|
||||
response.addHeader(Constant.TOKEN_HEADER, currentToken);
|
||||
//去掉凭证参数
|
||||
String removeCreditParame = ssoValidator.removeCreditParame(requestUri);
|
||||
response.addHeader("REDIRECT", removeCreditParame);
|
||||
request.setAttribute(Constant.TOKEN_HEADER, currentToken);
|
||||
return executeLogin(request, response);
|
||||
}else {
|
||||
send401Error(response, "未找到相关用户");
|
||||
}
|
||||
}
|
||||
|
||||
redirectToUrl(ssoValidator.getLoginUrl(requestUri), response);
|
||||
return false;
|
||||
}
|
||||
|
||||
private void redirectToYaweiLogin(HttpServletRequest request, HttpServletResponse response) throws IOException, IllegalAccessException, NoSuchFieldException {
|
||||
String requestUri = request.getHeader("REQUESTURI");
|
||||
if (requestUri == null) {
|
||||
requestUri = request.getRequestURI();
|
||||
}
|
||||
PSORequest psoRequest = new PSORequest(request);
|
||||
//不建新类了,直接反射解决
|
||||
Field returnUrl = psoRequest.getClass().getDeclaredField("returnUrl");
|
||||
returnUrl.setAccessible(true);
|
||||
returnUrl.set(psoRequest, requestUri);
|
||||
String requeststr = psoRequest.CreateHash();
|
||||
|
||||
String keeperUrl = yaweiSSOProperties.getKeeperUrl();
|
||||
keeperUrl = keeperUrl + "?" + yaweiSSOProperties.getSsoKey() + "="
|
||||
+ URLEncoder.encode(requeststr, "UTF-8");
|
||||
response.addHeader("REDIRECT", keeperUrl);
|
||||
private void redirectToUrl(String url, HttpServletResponse response) throws IOException {
|
||||
response.addHeader("REDIRECT", url);
|
||||
response.setStatus(HttpStatus.SC_UNAUTHORIZED);
|
||||
response.getOutputStream().write(HttpStatus.SC_UNAUTHORIZED);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,14 @@
|
|||
package io.renren.modules.security.oauth2;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public interface SSOValidator {
|
||||
|
||||
String validatePrincipal(String requestURL);
|
||||
|
||||
boolean hasCrediteInCallBackUrl(String url);
|
||||
|
||||
String removeCreditParame(String url);
|
||||
|
||||
String getLoginUrl(String callBackUrl);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,90 @@
|
|||
package io.renren.modules.security.oauth2;
|
||||
|
||||
public class YaweiSSOValidator {
|
||||
import com.yawei.pso.DateHelper;
|
||||
import com.yawei.pso.PSORequest;
|
||||
import com.yawei.pso.SSOResponse;
|
||||
import com.yawei.pso.TicketManager;
|
||||
import com.yawei.pso.security.Encrypter;
|
||||
import io.renren.common.interceptor.YaweiSSOProperties;
|
||||
import org.apache.catalina.connector.Request;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URLEncoder;
|
||||
import java.security.Principal;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
@ConditionalOnProperty(prefix = "sso", name = "mode", havingValue = "yawei")
|
||||
public class YaweiSSOValidator implements SSOValidator {
|
||||
|
||||
@Autowired
|
||||
private YaweiSSOProperties yaweiSSOProperties;
|
||||
|
||||
@Override
|
||||
public String validatePrincipal(String requestURL) {
|
||||
|
||||
String strResponse = getSSOToken(requestURL);
|
||||
SSOResponse ssoResp = new SSOResponse(strResponse);
|
||||
TicketManager tm = ssoResp.CreatePSOTicket();
|
||||
if (tm != null){
|
||||
return tm.getUserID();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCrediteInCallBackUrl(String url) {
|
||||
return StringUtils.isNotBlank(getSSOToken(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String removeCreditParame(String url) {
|
||||
String yaweiToken = yaweiSSOProperties.getSsoKey() + "=" + getSSOToken(url);
|
||||
if (url.indexOf(yaweiToken) > 0) {
|
||||
url = url.replace(yaweiToken, "");
|
||||
if (url.endsWith("?")) {
|
||||
url = url.substring(0,url.length() -1);
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLoginUrl(String callBackUrl) {
|
||||
Encrypter en = new Encrypter("qP70966AcZCQyXR+3P1mfjmqqxdkagom", "FnZ+19kJbQ8=");
|
||||
String requeststr = "PSOSite$" + en.EncryptString(DateHelper.getCurrentStrTime() +
|
||||
"|" + callBackUrl + "||");
|
||||
|
||||
String keeperUrl = yaweiSSOProperties.getKeeperUrl();
|
||||
try {
|
||||
keeperUrl = keeperUrl + "?" + yaweiSSOProperties.getSsoKey() + "="
|
||||
+ URLEncoder.encode(requeststr, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return keeperUrl;
|
||||
}
|
||||
|
||||
private String getSSOToken(String url){
|
||||
String ssoMatchKey = yaweiSSOProperties.getSsoKey() + "=";
|
||||
int startIndex = url.indexOf(ssoMatchKey) + ssoMatchKey.length();
|
||||
|
||||
if (startIndex < ssoMatchKey.length()) return null;
|
||||
|
||||
int indexOf = url.indexOf("&", startIndex);
|
||||
|
||||
return indexOf > 0 ? url.substring(startIndex, indexOf) : url.substring(startIndex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,3 +112,17 @@ zsk:
|
|||
version: 1.0
|
||||
methodId: jirdGetInfoByCatalog
|
||||
catalogIds: c0645e03fb7e4cf3842e9ceedd8ab998,f49561afc7204f008c4bb3cd821eb6ba
|
||||
|
||||
sso:
|
||||
mode: yawei # 取值 yawei,cas
|
||||
|
||||
cas:
|
||||
server-url-prefix: http://10.134.135.81:11188/cas
|
||||
server-login-url: http://10.134.135.81:11188/cas/login
|
||||
client-host-url: http://localhost:9999/#/
|
||||
use-session: false
|
||||
validation-type: cas3
|
||||
# 前端地址,用于退出登录后的重定向
|
||||
front:
|
||||
url: http://10.16.16.159:4444
|
||||
|
||||
|
|
|
@ -1,4 +1,104 @@
|
|||
package io.renren;
|
||||
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
|
||||
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class DataResourceTest {
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@ContentRowHeight(20)
|
||||
@HeadRowHeight(20)
|
||||
@ColumnWidth(25)
|
||||
public static class Entity {
|
||||
|
||||
@ExcelProperty(value = "zyname", index = 0)
|
||||
@JsonProperty("zyname")
|
||||
private String zyname;
|
||||
|
||||
@JsonProperty("sjcczl")
|
||||
@ExcelProperty(value = "sjcczl", index = 1)
|
||||
private Double sjcczl;
|
||||
|
||||
@JsonProperty("zycode")
|
||||
@ExcelProperty(value = "zycode", index = 2)
|
||||
private String zycode;
|
||||
|
||||
@JsonProperty("ygxjghjls")
|
||||
@ExcelProperty(value = "ygxjghjls", index = 3)
|
||||
private Double ygxjghjls;
|
||||
|
||||
@JsonProperty("jghxxjlzs")
|
||||
@ExcelProperty(value = "jghxxjlzs", index = 4)
|
||||
private Double jghxxjlzs;
|
||||
|
||||
@JsonProperty("neibukeshi")
|
||||
@ExcelProperty(value = "neibukeshi", index = 5)
|
||||
private String neibukeshi;
|
||||
|
||||
@JsonProperty("xgxt")
|
||||
@ExcelProperty(value = "xgxt", index = 6)
|
||||
private String xgxt;
|
||||
|
||||
@JsonProperty("ygxdsjccl")
|
||||
@ExcelProperty(value = "ygxdsjccl", index = 7)
|
||||
private Double ygxdsjccl;
|
||||
|
||||
@JsonProperty("zygszl")
|
||||
@ExcelProperty(value = "zygszl", index = 8)
|
||||
private String zygszl;
|
||||
|
||||
@JsonProperty("ykfjghjls")
|
||||
@ExcelProperty(value = "ykfjghjls", index = 9)
|
||||
private Double ykfjghjls;
|
||||
|
||||
@JsonProperty("syqk")
|
||||
@ExcelProperty(value = "syqk", index = 10)
|
||||
private Integer syqk;
|
||||
|
||||
@ExcelProperty(value = "zyformat", index = 11)
|
||||
@JsonProperty("zyformat")
|
||||
private String zyformat;
|
||||
|
||||
@ExcelProperty(value = "guid", index = 12)
|
||||
@JsonProperty("guid")
|
||||
private String guid;
|
||||
|
||||
@ExcelProperty(value = "TGBM", index = 13)
|
||||
@JsonProperty("TGBM")
|
||||
private String tgbm;
|
||||
|
||||
@ExcelProperty(value = "ykfdsjccl", index = 14)
|
||||
@JsonProperty("ykfdsjccl")
|
||||
private Double ykfdsjccl;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test(){
|
||||
String string = FileUtil.readUtf8String("/Users/huangweixiong/Downloads/data.json");
|
||||
List<Entity> entities = JSONArray.parseArray(string, Entity.class);
|
||||
EasyExcel.write("/Users/huangweixiong/Downloads/dataResource.xlsx")
|
||||
.sheet(0)
|
||||
.head(Entity.class)
|
||||
.doWrite(entities);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue