Commit 8f87b98e by xieshaohua

麦当劳sso单点登录和日志配置

parent bd51e84d
......@@ -138,13 +138,24 @@
<dependency>
<groupId>com.keymobile.auth</groupId>
<artifactId>common</artifactId>
<version>3.0.5-release</version>
<version>3.0.9-release</version>
</dependency>
<dependency>
<groupId>com.keymobile.auth</groupId>
<artifactId>security</artifactId>
<version>3.0.5-release</version>
<version>3.0.9-release</version>
</dependency>
<dependency>
<groupId>com.keymobile</groupId>
<artifactId>config</artifactId>
<version>1.1.5-release</version>
</dependency>
<dependency>
<groupId>com.keymobile</groupId>
<artifactId>crypto</artifactId>
<version>1.1.5-release</version>
</dependency>
</dependencies>
......
......@@ -3,9 +3,11 @@ package com.keymobile.login;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class LoginApplication {
public static void main(String[] args) {
......
......@@ -8,5 +8,7 @@ public class Constants {
public static final String Session_Roles = "roles";
public static final String Session_Lang = "lang";
public static final String SSO_API = "sso.API";
}
package com.keymobile.login.api;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.keymobile.auth.common.security.CustomizedUserDetailService;
import com.keymobile.login.logging.LogManager;
import com.keymobile.login.service.AuthService;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
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.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
......@@ -17,6 +40,24 @@ import java.util.Map;
@RequestMapping(value = "/")
public class LoginManagement {
@Value("${Mcd.sso.url}")
private String ssoAuthUrl;
@Value("${Mcd.sso.header}")
private String ssoAuthHeader;
@Value("${Mcd.sso.redirectUrl}")
private String ssoRedirectUrl;
@Autowired
private AuthService authService;
@Autowired
private CustomizedUserDetailService customizedUserDetailService;
private static final Logger log = LoggerFactory.getLogger(LoginManagement.class);
@RequestMapping(value = "/sessionInfo", method = {RequestMethod.POST, RequestMethod.GET})
public @ResponseBody Map<String,Object> verifyLogin(HttpServletRequest request, HttpServletResponse response) {
UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
......@@ -35,6 +76,47 @@ public class LoginManagement {
return rs;
}
@RequestMapping(value = "/ssoLogin", method = {RequestMethod.POST, RequestMethod.GET})
public void ssoLogin(HttpServletRequest request, HttpServletResponse response,
@RequestParam(required = false, value = "ssoToken") String ssoToken) {
if(StringUtils.isNotBlank(ssoToken)) {
try {
Map<String, String> headerMap = new HashMap<>();
headerMap.put("Mcd-Site", ssoAuthHeader);
String result = sendGetSkipSSL(ssoAuthUrl+"?token="+ssoToken, headerMap);
log.info("boss用户数据返回:"+ JSON.toJSONString(result));
JSONObject resultJb = JSON.parseObject(result);
JSONObject resultData = resultJb.getJSONObject("data");
String userName = String.valueOf(resultData.get("employeeNumber"));
String userDName = String.valueOf(resultData.get("chineseName"));
List<Map<String, Object>> matchUser = authService.getUserByName(userName);
if (null == matchUser || matchUser.isEmpty()) {
Map<String, Object> toAdd = new HashMap<>();
toAdd.put("dname", userDName);
toAdd.put("name", userName);
toAdd.put("password", "37fa265330ad83eaa879efb1e2db6380896cf639");
authService.addUser(toAdd);
}
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());
MDC.put("user", userName);
MDC.put("session", session.getId());
LogManager.logInfo(Constants.SSO_API,"登录");
response.sendRedirect(ssoRedirectUrl);
} catch (Exception e) {
log.error("ssoLogin error", e);
}
}else{
log.error("ssoLogin error", "no token");
}
}
@RequestMapping(value = "/lang", method = {RequestMethod.POST, RequestMethod.GET})
public String setLANG(HttpServletRequest request, @RequestParam(value = "LANG", required = true) String LANG) {
HttpSession session = request.getSession();
......@@ -46,4 +128,43 @@ public class LoginManagement {
return session.getAttribute(Constants.Session_Lang).toString();
}
/**
* 发送https请求并跳过ssl证书验证
* 条件:请求体格式为json
*
* @param url
* @return
*/
public String sendGetSkipSSL(String url, Map<String, String> header) throws Exception {
CloseableHttpResponse response = null;
// 处理请求路径
url = UriComponentsBuilder.fromHttpUrl(url) .toUriString();
//创建httpclient对象
CloseableHttpClient client = null;
String respBody;
client = HttpClients.custom().setSSLSocketFactory(new SSLConnectionSocketFactory(SSLContexts.custom()
.loadTrustMaterial(null, new TrustSelfSignedStrategy()).build(), NoopHostnameVerifier.INSTANCE)).build();
//创建post方式请求对象
HttpGet httpGet = new HttpGet(url);
// 请求头设置
httpGet.setHeader("Content-Type", "application/json");
if (header != null) {
for (String s : header.keySet()) {
httpGet.setHeader(s, header.get(s));
}
}
// if (body != null) {
// httpPost.setEntity(new StringEntity(JSON.toJSONString(body), "utf-8"));
// }
response = client.execute(httpGet);
org.apache.http.HttpEntity entity = response.getEntity();
if (entity != null) {
respBody = EntityUtils.toString(entity);
return respBody;
}
return null;
}
}
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.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);
}
......@@ -33,4 +33,10 @@ security:
allowRootLogin: true
logging:
config: classpath:logback-custom.xml
\ No newline at end of file
config: classpath:logback-custom.xml
Mcd:
sso:
url: https://boss.sit.mcd.com.cn/api/inner/boss-api/foundation/sso/authenticate
header: McD-BOSS;PC
redirectUrl: http://10.126.147.58/center-home/menu/index
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<springProperty name="spring.datasource.url" source="spring.datasource.url"/>
<springProperty name="spring.datasource.username" source="spring.datasource.username"/>
<springProperty name="spring.datasource.password" source="spring.datasource.password"/>
<springProperty name="spring.redis.host" source="spring.redis.host"/>
<springProperty name="spring.redis.port" source="spring.redis.port"/>
<springProperty name="spring.redis.password" source="spring.redis.password"/>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %X{user} %X{session} %-5level %logger{5} - %msg%n</pattern>
<encoder charset="UTF-8">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %X{user} %X{session} %-5level %logger{5} - %msg%n</pattern>
</encoder>
</appender>
<appender name="db" class="ch.qos.logback.classic.db.DBAppender">
<connectionSource
class="ch.qos.logback.core.db.DriverManagerConnectionSource">
<driverClass>com.mysql.jdbc.Driver</driverClass>
<url>${spring.datasource.url}</url>
<user>${spring.datasource.username}</user>
<password>${spring.datasource.password}</password>
</connectionSource>
<appender name="fileout" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/data/logs/iapdgstandardmgr/standardmgr.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<maxHistory>30</maxHistory>
<fileNamePattern>/data/logs/iapdgstandardmgr/standardmgr.log.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>5MB</maxFileSize>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %X{user} %X{session} %-5level %logger{5} - %msg%n</pattern>
</encoder>
</appender>
<logger name="auth.AUDIT">
<appender-ref ref="db" />
<appender name="logstash" class="com.cwbase.logback.RedisAppender">
<host>${spring.redis.host}</host>
<port>${spring.redis.port}</port>
<password>${spring.redis.password}</password>
<key>logstash</key>
<additionalField>
<key>user</key>
<value>@{user}</value>
</additionalField>
<additionalField>
<key>session</key>
<value>@{session}</value>
</additionalField>
</appender>
<logger name="sso.API">
<appender-ref ref="logstash"/>
</logger>
<root level="INFO">
<appender-ref ref="stdout" />
<appender-ref ref="stdout"/>
</root>
</configuration>
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