Commit b50bf81e by chenzy

【新增】深铁现场单点登录集成

parent 7b5fb99c
......@@ -52,6 +52,19 @@
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20220924</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
</dependency>
</dependencies>
<build>
......
......@@ -4,15 +4,17 @@ import com.keymobile.authservice.component.SecurityConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.PropertySource;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@ComponentScan(basePackages = {"com.keymobile.sso",
"com.keymobile.config.logging", "com.keymobile.config.naming",
"com.keymobile.config.redisclient", "com.keymobile.authservice.component"}, excludeFilters = {
"com.keymobile.config.redisclient", "com.keymobile.authservice.component", "com.keymobile.config.feignclient"}, excludeFilters = {
@ComponentScan.Filter(type= FilterType.ASSIGNABLE_TYPE, value= SecurityConfig.class)
})
@PropertySource(value = "classpath:/application.yml")
......
......@@ -8,5 +8,12 @@ public class Constants {
public static final String Session_Roles = "roles";
public static final String Session_Lang = "lang";
public static final String JWT_ACCESS_TOKEN = "access_token";
public static final String OAUTH_AUTHORIZE_CODE_PARAM = "code";
public static final String OAUTH_AUTHORIZE_STATE_PARAM = "state";
public static final String OAUTH_AUTHORIZE_GRANT_TYPE = "authorization_code";
public static final String OAUTH_AUTHORIZE_STATE = "keymobile";
public static final String OAUTH_AUTHORIZE_RESPONSE_TYPE = "code";
}
package com.keymobile.sso.api;
import com.keymobile.authservice.component.CustomizedUserDetailService;
import com.keymobile.sso.logging.LogConstants;
import com.keymobile.sso.logging.LogManager;
import com.keymobile.sso.oauth2.Oauth2Properties;
import com.keymobile.sso.service.AuthService;
import com.keymobile.sso.util.Utils;
import dm.jdbc.filter.stat.json.JSONObject;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
......@@ -15,6 +31,16 @@ import java.util.Map;
@RestController
@RequestMapping(value = "/")
public class LoginManagement {
private static final Logger log = LoggerFactory.getLogger(LoginManagement.class);
@Autowired
private Oauth2Properties oauth2Properties;
@Autowired
private AuthService authService;
@Autowired
private CustomizedUserDetailService customizedUserDetailService;
@RequestMapping(value = "/sessionInfo", method = {RequestMethod.POST, RequestMethod.GET})
public @ResponseBody Map<String,Object> verifyLogin(HttpServletRequest request, HttpServletResponse response) {
......@@ -45,4 +71,108 @@ public class LoginManagement {
return session.getAttribute(Constants.Session_Lang).toString();
}
@GetMapping("/ssologin")
public void login(HttpServletResponse response) throws IOException {
String successAuthorizeUri = getAuthorizeFullUri();
log.info("OauthLoginUri is {}", successAuthorizeUri);
response.sendRedirect(successAuthorizeUri);
// return successAuthorizeUri;
}
@RequestMapping("/ssologin1")
public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
String code = request.getParameter(Constants.OAUTH_AUTHORIZE_CODE_PARAM);
String state = request.getParameter(Constants.OAUTH_AUTHORIZE_STATE_PARAM);
log.info("Oauth回调携带参数----- code {} , state {} ", code, state);
Map<String, String> userDetailByTokenInfo = getUserDetailByTokenInfo(code, state, request);
List<Map<String, Object>> matchUser = authService.getUserByName(userDetailByTokenInfo.get("unique_name"));
if (null == matchUser || matchUser.isEmpty()) {
Map<String, Object> toAdd = new HashMap<>();
toAdd.put("dname", userDetailByTokenInfo.get("given_name"));
toAdd.put("name", userDetailByTokenInfo.get("unique_name"));
toAdd.put("password", "37fa265330ad83eaa879efb1e2db6380896cf639");
toAdd.put("oaUserOrgName", userDetailByTokenInfo.get("orgName"));
authService.addUser(toAdd);
log.info("新增单点用户成功:{}", userDetailByTokenInfo.get("given_name"));
//初始权限
List<Map<String, Object>> newUser = authService.getUserByName(userDetailByTokenInfo.get("unique_name"));
// List<Long> userIds = new ArrayList<>();
// userIds.add(Long.parseLong(newUser.get(0).get("id").toString()));
authService.addDataRole(oauth2Properties.getInitRoleId(),Long.parseLong(newUser.get(0).get("id").toString()));
log.info("初始化权限id:{},新增用户{}权限初始化成功。", oauth2Properties.getInitRoleId(), userDetailByTokenInfo.get("given_name"));
}
LogManager.logInfo(LogConstants.AUTH_AUDIT, "用户 " + userDetailByTokenInfo.get("unique_name") + " : " + userDetailByTokenInfo.get("given_name") + " 登录。");
UserDetails userDetails = customizedUserDetailService.loadUserByUsername(userDetailByTokenInfo.get("unique_name"));
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());
String authorizationSuccessRedirectUri = oauth2Properties.getAuthorizationSuccessRedirectUri();
response.sendRedirect(authorizationSuccessRedirectUri);
}
private Map<String, String> getUserDetailByTokenInfo(String code, String state, HttpServletRequest request) {
try {
if (!StringUtils.isEmpty(code) && !StringUtils.isEmpty(state)) {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("code", code);
map.add("client_id", oauth2Properties.getClientId());
map.add("client_secret", oauth2Properties.getClientSecret());
map.add("redirect_uri", oauth2Properties.getPostLoginRedirectUri());
map.add("grant_type", Constants.OAUTH_AUTHORIZE_GRANT_TYPE);
log.info("Oauth 获取token的url is {}, 参数为 {}", oauth2Properties.getAccessTokenUri(), map);
// Map<String, String> resp = restTemplate.postForObject(oauth2Properties.getAccessTokenUri(), map, Map.class);
String getTokenUri = String.format("%s?client_id=%s&grant_type=%s&code=%s&client_secret=%s",
oauth2Properties.getAccessTokenUri(), oauth2Properties.getClientId(), Constants.OAUTH_AUTHORIZE_GRANT_TYPE, code, oauth2Properties.getClientSecret());
String resp = Utils.doHttpsPost(getTokenUri,null);
JSONObject jo = new JSONObject(resp);
log.info("Oauth 获取token的信息 is {}", resp);
HttpSession session = request.getSession();
session.setAttribute(Constants.JWT_ACCESS_TOKEN, jo.get("access_token"));
String getUserInfoUri = String.format("%s?client_id=%s&access_token=%s",
oauth2Properties.getUserInfoUri(), oauth2Properties.getClientId(), jo.get("access_token"));
log.info("Oauth 获取认证用户的url is {}", getUserInfoUri);
String userInfo = Utils.doHttpsGet(getUserInfoUri,null);
log.info("Oauth 获取认证用户的信息 is {}", userInfo);
JSONObject userInfoObject = new JSONObject(userInfo);
Map<String, String> userDetailByTokenInfo = new HashMap<>();
userDetailByTokenInfo.put("given_name",userInfoObject.get("displayName").toString());
userDetailByTokenInfo.put("unique_name",userInfoObject.get("loginName").toString());
String orgNamePath = userInfoObject.get("orgNamePath").toString();
// 找到倒数第二个 / 的位置
int lastSlashIndex = orgNamePath.lastIndexOf('/', orgNamePath.length() - 2);
String orgName = "";
if (lastSlashIndex != -1) {
// 截取最后一段字符串
String lastSegment = orgNamePath.substring(lastSlashIndex + 1, orgNamePath.length() - 1);
log.info("orgNamePath -> {}, lastSegment -> {}", orgNamePath, lastSegment);
orgName = lastSegment;
}
userDetailByTokenInfo.put("orgName",orgName);
return userDetailByTokenInfo;
}
throw new RuntimeException("Oauth获取token的参数code或者state为空!");
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Oauth 获取token 错误!", e);
}
}
private String getAuthorizeFullUri() {
String authorizeUri = oauth2Properties.getUserAuthorizationUri();
String clientId = oauth2Properties.getClientId();
String redirectUri = oauth2Properties.getPostLoginRedirectUri();
String response_type = Constants.OAUTH_AUTHORIZE_RESPONSE_TYPE;
String state = Constants.OAUTH_AUTHORIZE_STATE;
String authorizeFullUri = String.format("%s?client_id=%s&redirect_uri=%s&response_type=%s&state=%s",
authorizeUri, clientId, redirectUri, response_type, state);
return authorizeFullUri;
}
}
......@@ -3,5 +3,5 @@ package com.keymobile.sso.logging;
public interface LogConstants {
String CTX_AUDIT = "sso.AUDIT";
String AUTH_AUDIT = "auth.AUDIT";
}
package com.keymobile.sso.oauth2;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "security.oauth2.client")
@Component
public class Oauth2Properties {
private String clientId;
private String clientSecret;
private String clientTokenUri;
private String userAuthorizationUri;
private String postLoginRedirectUri;
private String authorizationSuccessRedirectUri;
private String postLogoutRedirectUri;
private String accessTokenUri;
private String userInfoUri;
private String authorizationLoginOutUri;
private Long initRoleId;
public void setPostLogoutRedirectUri(String postLogoutRedirectUri) {
this.postLogoutRedirectUri = postLogoutRedirectUri;
}
public String getPostLogoutRedirectUri() {
return postLogoutRedirectUri;
}
public void setAuthorizationLoginOutUri(String authorizationLoginOutUri) {
this.authorizationLoginOutUri = authorizationLoginOutUri;
}
public String getAuthorizationLoginOutUri() {
return authorizationLoginOutUri;
}
public void setAccessTokenUri(String accessTokenUri) {
this.accessTokenUri = accessTokenUri;
}
public String getAccessTokenUri() {
return accessTokenUri;
}
public void setAuthorizationSuccessRedirectUri(String authorizationSuccessRedirectUri) {
this.authorizationSuccessRedirectUri = authorizationSuccessRedirectUri;
}
public String getAuthorizationSuccessRedirectUri() {
return authorizationSuccessRedirectUri;
}
public void setPostLoginRedirectUri(String postLoginRedirectUri) {
this.postLoginRedirectUri = postLoginRedirectUri;
}
public String getPostLoginRedirectUri() {
return postLoginRedirectUri;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getClientTokenUri() {
return clientTokenUri;
}
public void setClientTokenUri(String clientTokenUri) {
this.clientTokenUri = clientTokenUri;
}
public String getUserAuthorizationUri() {
return userAuthorizationUri;
}
public void setUserAuthorizationUri(String userAuthorizationUri) {
this.userAuthorizationUri = userAuthorizationUri;
}
public String getUserInfoUri() {
return userInfoUri;
}
public void setUserInfoUri(String userInfoUri) {
this.userInfoUri = userInfoUri;
}
public Long getInitRoleId() {
return initRoleId;
}
public void setInitRoleId(Long initRoleId) {
this.initRoleId = initRoleId;
}
public String getAuthorizeLogoutUri() {
String authorizeUri = getAuthorizationLoginOutUri();
String clientId = getClientId();
String redirectUri = getPostLogoutRedirectUri();
String logoutUri = String.format("%s?redirctToUrl=%s&redirectToLogin=true&entityId=%s",
authorizeUri, redirectUri, clientId);
return logoutUri;
}
}
package com.keymobile.sso.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 AuthService {
@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 = "/dataRoles/{dataRoleId}/users/sync")
// Map<String, Object> dataRoles(@PathVariable(value = "dataRoleId") Long roleId, @RequestParam(value = "userIds") List<Long> userIds);
@PostMapping(value = "/dataRoles/{dataRoleId}/users/{userId}")
Map<String, Object> addDataRole(@PathVariable(value = "dataRoleId") Long roleId, @RequestParam(value = "userId") Long userId);
}
\ No newline at end of file
package com.keymobile.sso.util;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
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.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.Map.Entry;
public class Utils {
public static String doHttpsPost(String url, Map<String, Object> paramMap) {
CloseableHttpClient httpClient = null;
CloseableHttpResponse httpResponse = null;
String result = "";
// httpClient = HttpClients.createDefault();
try {
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build(),
NoopHostnameVerifier.INSTANCE
);
httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
}catch (Exception e){
e.printStackTrace();
}
HttpPost httpPost = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(10000)// 设置连接主机服务超时时间
.setConnectionRequestTimeout(10000)// 设置连接请求超时时间
.setSocketTimeout(20000)// 设置读取数据连接超时时间
.build();
httpPost.setConfig(requestConfig);
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=gbk");
if (null != paramMap && paramMap.size() > 0) {
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
Set<Entry<String, Object>> entrySet = paramMap.entrySet();
Iterator<Entry<String, Object>> iterator = entrySet.iterator();
while (iterator.hasNext()) {
Entry<String, Object> mapEntry = iterator.next();
nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString()));
}
try {
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "GBK"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
try {
httpResponse = httpClient.execute(httpPost);
HttpEntity entity = httpResponse.getEntity();
result = EntityUtils.toString(entity);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != httpResponse) {
try {
httpResponse.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != httpClient) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
public static String doHttpsGet(String url, Map<String, Object> paramMap) {
CloseableHttpClient httpClient = null;
CloseableHttpResponse httpResponse = null;
String result = "";
// httpClient = HttpClients.createDefault();
try {
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build(),
NoopHostnameVerifier.INSTANCE
);
httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
}catch (Exception e){
e.printStackTrace();
}
HttpGet httpget = new HttpGet(url);
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(10000)// 设置连接主机服务超时时间
.setConnectionRequestTimeout(10000)// 设置连接请求超时时间
.setSocketTimeout(20000)// 设置读取数据连接超时时间
.build();
httpget.setConfig(requestConfig);
httpget.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=gbk");
// if (null != paramMap && paramMap.size() > 0) {
// List<NameValuePair> nvps = new ArrayList<NameValuePair>();
// Set<Entry<String, Object>> entrySet = paramMap.entrySet();
// Iterator<Entry<String, Object>> iterator = entrySet.iterator();
// while (iterator.hasNext()) {
// Entry<String, Object> mapEntry = iterator.next();
// nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString()));
// }
// try {
// httpget.setEntity(new UrlEncodedFormEntity(nvps, "GBK"));
// } catch (UnsupportedEncodingException e) {
// e.printStackTrace();
// }
// }
try {
httpResponse = httpClient.execute(httpget);
HttpEntity entity = httpResponse.getEntity();
result = EntityUtils.toString(entity);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != httpResponse) {
try {
httpResponse.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != httpClient) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
}
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