Commit 03c8043f authored by gary's avatar gary

1、滴滴权限整合

parent 681b1d24
package pwc.taxtech.atms.common; package pwc.taxtech.atms.common;
import pwc.taxtech.atms.security.DDUserInfo;
import java.util.Optional; import java.util.Optional;
public interface AuthUserHelper { public interface AuthUserHelper {
...@@ -12,4 +14,6 @@ public interface AuthUserHelper { ...@@ -12,4 +14,6 @@ public interface AuthUserHelper {
String getClientIp(); String getClientIp();
DDUserInfo getDDUserInfo();
} }
\ No newline at end of file
...@@ -14,8 +14,10 @@ import org.springframework.stereotype.Component; ...@@ -14,8 +14,10 @@ import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import pwc.taxtech.atms.dao.UserMapper; import pwc.taxtech.atms.dao.UserMapper;
import pwc.taxtech.atms.exception.ApplicationException; import pwc.taxtech.atms.exception.ApplicationException;
import pwc.taxtech.atms.security.DDUserInfo;
import pwc.taxtech.atms.security.JwtUser; import pwc.taxtech.atms.security.JwtUser;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Optional; import java.util.Optional;
...@@ -25,7 +27,7 @@ public class AuthUserHelperImpl implements AuditorAware<String>, AuthUserHelper ...@@ -25,7 +27,7 @@ public class AuthUserHelperImpl implements AuditorAware<String>, AuthUserHelper
@Autowired(required = false) @Autowired(required = false)
private HttpServletRequest request; private HttpServletRequest request;
@Autowired @Resource
private UserMapper userMapper; private UserMapper userMapper;
/* /*
...@@ -111,4 +113,21 @@ public class AuthUserHelperImpl implements AuditorAware<String>, AuthUserHelper ...@@ -111,4 +113,21 @@ public class AuthUserHelperImpl implements AuditorAware<String>, AuthUserHelper
public String getClientIp() { public String getClientIp() {
return Lang.getIP(request); return Lang.getIP(request);
} }
@Override
public DDUserInfo getDDUserInfo(){
SecurityContext context = SecurityContextHolder.getContext();
if (context == null) {
throw new ApplicationException("security context is null");
}
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
throw new ApplicationException("authentication failed");
}
JwtUser jwtUser = (JwtUser) authentication.getPrincipal();
if (jwtUser == null) {
return null;
}
return (DDUserInfo)jwtUser.getClientUserInfo();
}
} }
...@@ -13,6 +13,7 @@ public class AtmsTokenDto { ...@@ -13,6 +13,7 @@ public class AtmsTokenDto {
private String user_name; private String user_name;
private String vat_api_host; private String vat_api_host;
private String version; private String version;
private String ticket;
public String getAccess_token() { public String getAccess_token() {
return access_token; return access_token;
...@@ -110,6 +111,14 @@ public class AtmsTokenDto { ...@@ -110,6 +111,14 @@ public class AtmsTokenDto {
this.version = version; this.version = version;
} }
public String getTicket() {
return ticket;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
@Override @Override
public String toString() { public String toString() {
return "CookieModel [access_token=" + access_token + ", token_type=" + token_type + ", expires_in=" + expires_in return "CookieModel [access_token=" + access_token + ", token_type=" + token_type + ", expires_in=" + expires_in
......
...@@ -6,6 +6,10 @@ public class LoginInputDto { ...@@ -6,6 +6,10 @@ public class LoginInputDto {
private String password; private String password;
private String ticket;
private Integer type;
public String getEmail() { public String getEmail() {
return email; return email;
} }
...@@ -22,5 +26,19 @@ public class LoginInputDto { ...@@ -22,5 +26,19 @@ public class LoginInputDto {
this.password = password; this.password = password;
} }
public String getTicket() {
return ticket;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
} }
package pwc.taxtech.atms.security;
import com.alibaba.fastjson.annotation.JSONField;
/**
* @Auther: Gary J Li
* @Date: 05/03/2019 18:25
* @Description:
*/
public class DDUserInfo {
private int uid;
private String phone;
@JSONField(name = "username_zh")
private String username_zh;
private String email;
private String username;
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getUsername_zh() {
return username_zh;
}
public void setUsername_zh(String username_zh) {
this.username_zh = username_zh;
}
}
package pwc.taxtech.atms.security;
import com.alibaba.fastjson.annotation.JSONField;
/**
* @Auther: Gary J Li
* @Date: 05/03/2019 18:25
* @Description:
*/
public class DDUserInfoRes {
private int errno;
@JSONField(name = "data")
private DDUserInfo ddUserInfo;
private String errmsg;
public int getErrno() {
return errno;
}
public void setErrno(int errno) {
this.errno = errno;
}
public DDUserInfo getDdUserInfo() {
return ddUserInfo;
}
public void setDdUserInfo(DDUserInfo ddUserInfo) {
this.ddUserInfo = ddUserInfo;
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
}
package pwc.taxtech.atms.security; package pwc.taxtech.atms.security;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.impl.DefaultClaims; import io.jsonwebtoken.impl.DefaultClaims;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
...@@ -8,14 +10,18 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio ...@@ -8,14 +10,18 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import pwc.taxtech.atms.common.util.HttpUtil;
import pwc.taxtech.atms.dto.AtmsTokenDto;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.net.URLDecoder;
import java.util.Map;
public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFilter { public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
...@@ -23,13 +29,20 @@ public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFil ...@@ -23,13 +29,20 @@ public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFil
private Integer jwtExpireSecond; private Integer jwtExpireSecond;
@Value("${jwt.refreshSecond}") @Value("${jwt.refreshSecond}")
private Integer jwtRefreshSecond; private Integer jwtRefreshSecond;
@Value("${get_user_info_url}")
private String getUserInfoUrl;
@Value("${app_id}")
private String appId;
@Autowired @Autowired
private JwtUtil jwtUtil; private JwtUtil jwtUtil;
@Value("${check_ticket}")
private Boolean checkTicket;
public JwtAuthenticationFilter() { public JwtAuthenticationFilter() {
super("/**"); super("/**");
} }
@Override
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) { protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
String header = request.getHeader("Authorization"); String header = request.getHeader("Authorization");
return (header != null && (header.startsWith("bearer ") || header.startsWith("Bearer "))); return (header != null && (header.startsWith("bearer ") || header.startsWith("Bearer ")));
...@@ -53,7 +66,32 @@ public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFil ...@@ -53,7 +66,32 @@ public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFil
setDetails(request, authRequest); setDetails(request, authRequest);
return getAuthenticationManager().authenticate(authRequest); Authentication authResult = getAuthenticationManager().authenticate(authRequest);
if (checkTicket) {
Cookie[] cookies = request.getCookies();
String ticket = "";
try {
for (Cookie cookie : cookies) {
if ("ddTicket".equals(cookie.getName())) {
ticket = cookie.getValue();
break;
}
}
JSONObject object;
String ddResp = HttpUtil.post(getUserInfoUrl + "check_ticket", "ticket=" + ticket + "&app_id=" + appId, "application/x-www-form-urlencoded", "UTF-8", 10000, 10000);
object = JSONObject.parseObject(ddResp);
Map<String, Object> res = object.getInnerMap();
int code = (int) res.get("errno");
if (code != 0) {
logger.warn(String.format("DD Ticket Check Failed:[%s]", object.toJSONString()));
return null;
}
logger.debug("ddTicket校验CODE:"+code);
} catch (Exception e) {
logger.error(String.format("调用DD获取用户信息失败:[%s]", e.getMessage()), e);
}
}
return authResult;
} }
protected void setDetails(HttpServletRequest request, protected void setDetails(HttpServletRequest request,
...@@ -75,7 +113,7 @@ public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFil ...@@ -75,7 +113,7 @@ public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFil
DefaultClaims claims = jwtUser.getDefaultClaims(); DefaultClaims claims = jwtUser.getDefaultClaims();
if (claims.getExpiration().getTime() - System.currentTimeMillis() <= jwtRefreshSecond * 1000) { if (claims.getExpiration().getTime() - System.currentTimeMillis() <= jwtRefreshSecond * 1000) {
String newToken = jwtUtil.generateToken(jwtUser.getUsername(), jwtUser.getDatabaseUsername(), String newToken = jwtUtil.generateToken(jwtUser.getUsername(), jwtUser.getDatabaseUsername(),
jwtUser.getUserid()); jwtUser.getUserid(),jwtUser.getTicket());
response.setHeader("Access-Control-Expose-Headers", "refreshToken"); response.setHeader("Access-Control-Expose-Headers", "refreshToken");
response.setHeader("refreshToken", newToken); response.setHeader("refreshToken", newToken);
logger.debug("refreshToken: " + newToken); logger.debug("refreshToken: " + newToken);
......
...@@ -8,20 +8,30 @@ import org.springframework.security.core.userdetails.UserDetails; ...@@ -8,20 +8,30 @@ import org.springframework.security.core.userdetails.UserDetails;
public class JwtUser implements UserDetails { public class JwtUser implements UserDetails {
private static final long serialVersionUId = 1L; private static final long serialVersionUId = 1L;
private final String userid; private final String userid;
/** 登录名, 大小写不限,可以是全大写或全小写 */ /** 登录名, 大小写不限,可以是全大写或全小写 */
private final String username; private final String username;
/** 数据库用户名, 比如Admin */ /** 数据库用户名, 比如Admin */
private final String databaseUsername; private final String databaseUsername;
private final String ticket;
private Object clientUserInfo;
private final Collection<? extends GrantedAuthority> authorities; private final Collection<? extends GrantedAuthority> authorities;
private DefaultClaims defaultClaims; private DefaultClaims defaultClaims;
public JwtUser(String userid, String username, String databaseUsername, public JwtUser(String userid, String username, String databaseUsername,String ticket,Object clientUserInfo,
DefaultClaims defaultClaims, Collection<? extends GrantedAuthority> authorities) { DefaultClaims defaultClaims, Collection<? extends GrantedAuthority> authorities) {
this.userid = userid; this.userid = userid;
this.username = username; this.username = username;
this.databaseUsername = databaseUsername; this.databaseUsername = databaseUsername;
this.ticket = ticket;
this.clientUserInfo = clientUserInfo;
this.authorities = authorities; this.authorities = authorities;
this.defaultClaims = defaultClaims; this.defaultClaims = defaultClaims;
} }
...@@ -61,6 +71,18 @@ public class JwtUser implements UserDetails { ...@@ -61,6 +71,18 @@ public class JwtUser implements UserDetails {
return true; return true;
} }
public String getTicket() {
return ticket;
}
public static long getSerialVersionUId() {
return serialVersionUId;
}
public Object getClientUserInfo() {
return clientUserInfo;
}
public String getUserid() { public String getUserid() {
return userid; return userid;
} }
......
...@@ -3,7 +3,9 @@ package pwc.taxtech.atms.security; ...@@ -3,7 +3,9 @@ package pwc.taxtech.atms.security;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.*; import io.jsonwebtoken.*;
import org.nutz.lang.Times; import org.nutz.lang.Times;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -20,6 +22,7 @@ import io.jsonwebtoken.impl.DefaultJws; ...@@ -20,6 +22,7 @@ import io.jsonwebtoken.impl.DefaultJws;
import io.jsonwebtoken.lang.Assert; import io.jsonwebtoken.lang.Assert;
import pwc.taxtech.atms.common.AtmsApiSettings; import pwc.taxtech.atms.common.AtmsApiSettings;
import pwc.taxtech.atms.common.CommonUtils; import pwc.taxtech.atms.common.CommonUtils;
import pwc.taxtech.atms.common.util.HttpUtil;
@Component @Component
public class JwtUtil implements InitializingBean { public class JwtUtil implements InitializingBean {
...@@ -31,6 +34,14 @@ public class JwtUtil implements InitializingBean { ...@@ -31,6 +34,14 @@ public class JwtUtil implements InitializingBean {
private JwtAuthenticationService jwtAuthenticationService; private JwtAuthenticationService jwtAuthenticationService;
@Value("${jwt.expireSecond}") @Value("${jwt.expireSecond}")
private Integer jwtExpireSecond; private Integer jwtExpireSecond;
@Value("${get_user_info_url}")
private String getUserInfoUrl;
@Value("${app_id}")
private String appId;
@Value("${app_key}")
private String appKey;
@Value("${check_ticket}")
private Boolean checkTicket;
@Override @Override
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
...@@ -50,9 +61,6 @@ public class JwtUtil implements InitializingBean { ...@@ -50,9 +61,6 @@ public class JwtUtil implements InitializingBean {
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
public JwtUser parseToken(String token) { public JwtUser parseToken(String token) {
if (StringUtils.hasText(jwtPowerToken) && jwtPowerToken.equals(token)) {
return new JwtUser("test_userid", "admin", "Admin", null, getAuthorities());
}
JwtParser parser = Jwts.parser().setSigningKey(jwtBase64Secret); JwtParser parser = Jwts.parser().setSigningKey(jwtBase64Secret);
Jwt jwt = parser.parseClaimsJws(token); Jwt jwt = parser.parseClaimsJws(token);
DefaultJws<DefaultClaims> defaultJws = (DefaultJws<DefaultClaims>) jwt; DefaultJws<DefaultClaims> defaultJws = (DefaultJws<DefaultClaims>) jwt;
...@@ -60,8 +68,25 @@ public class JwtUtil implements InitializingBean { ...@@ -60,8 +68,25 @@ public class JwtUtil implements InitializingBean {
String databaseUsername = String.valueOf(defaultClaims.get("databaseUsername")); String databaseUsername = String.valueOf(defaultClaims.get("databaseUsername"));
String username = String.valueOf(defaultClaims.get("username")); String username = String.valueOf(defaultClaims.get("username"));
String userid = String.valueOf(defaultClaims.get("userid")); String userid = String.valueOf(defaultClaims.get("userid"));
String ticket = "";
JSONObject object;
Object userInfo = null;
if(checkTicket){
ticket = String.valueOf(defaultClaims.get("ticket"));
try {
String response = HttpUtil.post(getUserInfoUrl+"get_user_by_ticket", "ticket=" + ticket + "&app_id=" + appId, "application/x-www-form-urlencoded", "UTF-8", 10000, 10000);
object = JSONObject.parseObject(response);
Map<String, Object> res = object.getInnerMap();
userInfo = res.get("data");
} catch (Exception e) {
logger.error(String.format("调用DD获取用户信息失败:[%s]", e.getMessage()), e);
}
}
if (StringUtils.hasText(jwtPowerToken) && jwtPowerToken.equals(token)) {
return new JwtUser("test_userid", "admin", "Admin", ticket, userInfo, null, getAuthorities());
}
// 原版 UserDetails return new JwtUser(userid, username, databaseUsername, defaultClaims, getAuthorities()); // 原版 UserDetails return new JwtUser(userid, username, databaseUsername, defaultClaims, getAuthorities());
return new JwtUser(userid, username, databaseUsername, defaultClaims, getAuthorities(userid)); return new JwtUser(userid, username, databaseUsername, ticket, userInfo, defaultClaims, getAuthorities(userid));
} }
private List<SimpleGrantedAuthority> getAuthorities() { private List<SimpleGrantedAuthority> getAuthorities() {
...@@ -91,7 +116,7 @@ public class JwtUtil implements InitializingBean { ...@@ -91,7 +116,7 @@ public class JwtUtil implements InitializingBean {
* 用户Id * 用户Id
* @return * @return
*/ */
public String generateToken(String username, String databaseUsername, String userid) { public String generateToken(String username, String databaseUsername, String userid,String ticket) {
// sub: 该JWT所面向的用户 // sub: 该JWT所面向的用户
// iss: 该JWT的签发者 // iss: 该JWT的签发者
// iat(issued at): 在什么时候签发的token // iat(issued at): 在什么时候签发的token
...@@ -115,6 +140,7 @@ public class JwtUtil implements InitializingBean { ...@@ -115,6 +140,7 @@ public class JwtUtil implements InitializingBean {
jwtBuilder.claim("username", username); jwtBuilder.claim("username", username);
jwtBuilder.claim("databaseUsername", databaseUsername); jwtBuilder.claim("databaseUsername", databaseUsername);
jwtBuilder.claim("userid", userid); jwtBuilder.claim("userid", userid);
jwtBuilder.claim("ticket", ticket);
// 设置body.username为数据库用户名 // 设置body.username为数据库用户名
jwtBuilder.signWith(SignatureAlgorithm.HS512, jwtBase64Secret); jwtBuilder.signWith(SignatureAlgorithm.HS512, jwtBase64Secret);
return jwtBuilder.compact(); return jwtBuilder.compact();
......
...@@ -121,13 +121,16 @@ public class MenuServiceImpl { ...@@ -121,13 +121,16 @@ public class MenuServiceImpl {
permissionExample.createCriteria().andIdIn(permissionIds); permissionExample.createCriteria().andIdIn(permissionIds);
List<String> menuIds = permissionMapper.selectByExample(permissionExample) List<String> menuIds = permissionMapper.selectByExample(permissionExample)
.stream().map(Permission::getMenuId).collect(Collectors.toList()); .stream().map(Permission::getMenuId).collect(Collectors.toList());
// 数据问题,,暂时用这种蠢办法 // admin权限暂时不做控制
menuIds.add("91223c21-c15a-4882-89cc-42f3807ec9e3"); menuIds.add("91223c21-c15a-4882-89cc-42f3807ec9e3");
menuIds.add("9bf855fb-6b44-49cd-b95b-41a6a9a8c098"); menuIds.add("9bf855fb-6b44-49cd-b95b-41a6a9a8c098");
menuIds.add("F9A18F3A-7E39-4661-BA00-F149710577C3");
menuIds.add("F9A18F3A-7E39-4661-BA00-F149710577C4");
menuIds.add("F9A18F3A-7E39-4661-BA00-F149710577C7");
// 这里的权限之后需要在数据库中加上对应的权限数据
menuIds.add("6b404066-2200-4d11-9436-d0870dfd3188"); menuIds.add("6b404066-2200-4d11-9436-d0870dfd3188");
menuIds.add("6b404066-2200-4d11-9436-d0870dfd3189"); menuIds.add("6b404066-2200-4d11-9436-d0870dfd3189");
menuIds.add("5bdbc9a7-197b-43cc-b0e6-3f50e41b13eb"); menuIds.add("5bdbc9a7-197b-43cc-b0e6-3f50e41b13eb");
menuIds.add("5bdbc9a7-197b-43cc-b0e6-3f50e41b13ec"); menuIds.add("5bdbc9a7-197b-43cc-b0e6-3f50e41b13ec");
menuIds.add("5bdbc9a7-197b-43cc-b0e6-3f50e41b13eg"); menuIds.add("5bdbc9a7-197b-43cc-b0e6-3f50e41b13eg");
......
package pwc.taxtech.atms.service.impl; package pwc.taxtech.atms.service.impl;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.BooleanUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -19,6 +20,7 @@ import pwc.taxtech.atms.common.OperationModule; ...@@ -19,6 +20,7 @@ import pwc.taxtech.atms.common.OperationModule;
import pwc.taxtech.atms.common.UserLoginType; import pwc.taxtech.atms.common.UserLoginType;
import pwc.taxtech.atms.common.UserStatus; import pwc.taxtech.atms.common.UserStatus;
import pwc.taxtech.atms.common.message.UserMessage; import pwc.taxtech.atms.common.message.UserMessage;
import pwc.taxtech.atms.common.util.HttpUtil;
import pwc.taxtech.atms.constant.DimensionConstant; import pwc.taxtech.atms.constant.DimensionConstant;
import pwc.taxtech.atms.constant.PermissionCode; import pwc.taxtech.atms.constant.PermissionCode;
import pwc.taxtech.atms.constant.PermissionUrl; import pwc.taxtech.atms.constant.PermissionUrl;
...@@ -52,15 +54,9 @@ import pwc.taxtech.atms.dto.user.WebUserDto; ...@@ -52,15 +54,9 @@ import pwc.taxtech.atms.dto.user.WebUserDto;
import pwc.taxtech.atms.entity.*; import pwc.taxtech.atms.entity.*;
import pwc.taxtech.atms.entity.UserRoleExample.Criteria; import pwc.taxtech.atms.entity.UserRoleExample.Criteria;
import pwc.taxtech.atms.exception.ApplicationException; import pwc.taxtech.atms.exception.ApplicationException;
import pwc.taxtech.atms.security.AtmsPasswordEncoder; import pwc.taxtech.atms.security.*;
import pwc.taxtech.atms.security.JwtAuthenticationService;
import pwc.taxtech.atms.security.JwtUtil; import java.util.*;
import pwc.taxtech.atms.security.LdapAuthenticationProvider;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
...@@ -110,6 +106,18 @@ public class UserServiceImpl extends AbstractService { ...@@ -110,6 +106,18 @@ public class UserServiceImpl extends AbstractService {
@Value("${api.url}") @Value("${api.url}")
private String apiUrl; private String apiUrl;
@Value("${get_user_info_url}")
private String getUserInfoUrl;
@Value("${app_id}")
private String appId;
@Value("${app_key}")
private String appKey;
@Value("${check_ticket}")
private Boolean checkTicket;
public UserPermissionDto getUserPermission(String userName) { public UserPermissionDto getUserPermission(String userName) {
User user = userMapper.selectByUserNameIgnoreCase(userName); User user = userMapper.selectByUserNameIgnoreCase(userName);
if (user == null) { if (user == null) {
...@@ -368,6 +376,9 @@ public class UserServiceImpl extends AbstractService { ...@@ -368,6 +376,9 @@ public class UserServiceImpl extends AbstractService {
public OperationResultDto<LoginOutputDto> login(LoginInputDto input) { public OperationResultDto<LoginOutputDto> login(LoginInputDto input) {
// return dummyLogin(input); // return dummyLogin(input);
if(input.getType() == 1){
return loginByDDTicket(input);
}
return doLogin(input); return doLogin(input);
} }
...@@ -375,8 +386,10 @@ public class UserServiceImpl extends AbstractService { ...@@ -375,8 +386,10 @@ public class UserServiceImpl extends AbstractService {
logger.debug("doLogin start"); logger.debug("doLogin start");
Assert.notNull(input, "Null input"); Assert.notNull(input, "Null input");
final String inputLoginName = input.getEmail(); final String inputLoginName = input.getEmail();
final String ticket = input.getTicket();
Assert.hasText(inputLoginName, "empty email"); Assert.hasText(inputLoginName, "empty email");
Assert.hasText(input.getPassword(), "empty password"); Assert.hasText(input.getPassword(), "empty password");
logger.debug("ready to call userMapper.selectByserNameIgnoreCase"); logger.debug("ready to call userMapper.selectByserNameIgnoreCase");
// 查找用户时需要忽略大小写 // 查找用户时需要忽略大小写
User tempUser = userMapper.selectByUserNameIgnoreCase(inputLoginName); User tempUser = userMapper.selectByUserNameIgnoreCase(inputLoginName);
...@@ -437,7 +450,7 @@ public class UserServiceImpl extends AbstractService { ...@@ -437,7 +450,7 @@ public class UserServiceImpl extends AbstractService {
logger.debug("创建AtmsTokenDto"); logger.debug("创建AtmsTokenDto");
AtmsTokenDto token = new AtmsTokenDto(); AtmsTokenDto token = new AtmsTokenDto();
newloginResult.getData().setToken(token); newloginResult.getData().setToken(token);
String accessToken = jwtUtil.generateToken(inputLoginName, tempUser.getUserName(), tempUser.getId()); String accessToken = jwtUtil.generateToken(inputLoginName, tempUser.getUserName(), tempUser.getId(),ticket);
token.setAccess_token(accessToken); token.setAccess_token(accessToken);
token.setToken_type("bearer"); token.setToken_type("bearer");
token.setExpires_in(86400000L); token.setExpires_in(86400000L);
...@@ -474,6 +487,80 @@ public class UserServiceImpl extends AbstractService { ...@@ -474,6 +487,80 @@ public class UserServiceImpl extends AbstractService {
return newloginResult; return newloginResult;
} }
private OperationResultDto<LoginOutputDto> loginByDDTicket(LoginInputDto input){
OperationResultDto<LoginOutputDto> result = new OperationResultDto<>();
final String ticket = input.getTicket();
Assert.hasText(ticket, "empty ticket");
DDUserInfoRes ddUserInfoRes = new DDUserInfoRes();
try {
String response = HttpUtil.post(getUserInfoUrl+"get_user_by_ticket", "ticket=" + ticket + "&app_id=" + appId, "application/x-www-form-urlencoded", "UTF-8", 10000, 10000);
logger.debug(String.format("DD-get_user_by_ticket返回:[%s]", response));
ddUserInfoRes = JSONObject.parseObject(response,DDUserInfoRes.class);
} catch (Exception e) {
logger.error(String.format("调用DD获取用户信息失败:[%s]", e.getMessage()), e);
}
if(ddUserInfoRes==null){
result.setResult(false);
LoginOutputDto data = new LoginOutputDto();
data.setCheckState(CheckState.UserNameNotExist.value());
result.setData(data);
return result;
}
String userId="";
DDUserInfo userInfo = ddUserInfoRes.getDdUserInfo();
String userName = userInfo.getUsername_zh()==null?input.getEmail():userInfo.getUsername();
User user = userMapper.selectByUserName(userName);
userId = user.getId();
// 根据用户的登录类型选择不同的登录验证方式
result.setResult(true);
LoginOutputDto data = new LoginOutputDto();
data.setCheckState(CheckState.Success.value());
result.setData(data);
final LoginOutputDto resOutputDto = result.getData();
resOutputDto.setUserId(userId);
result.getData().setMessage("Login success.");
AtmsTokenDto token = new AtmsTokenDto();
result.getData().setToken(token);
String accessToken = jwtUtil.generateToken(userName, userName, userId, ticket);
token.setAccess_token(accessToken);
token.setToken_type("bearer");
token.setExpires_in(86400000L);
token.setApi_host("NA");
token.setVat_api_host(apiUrl);
token.setTp_url(apiUrl);
token.setVersion("1.0" + ".0.0");
token.setUser_name(userName);
token.setLocal_name(userName);
token.setNeed_change_password(false);
token.setIs_external_user(true);
token.setUser_id(userId);
token.setTicket(ticket);
WebUserDto userDto = new WebUserDto();
result.getData().setUser(userDto);
userDto.setUniqueId(CommonUtils.getUUID());
userDto.setLoginName(userName);
userDto.setPassword(input.getPassword());
userDto.setHasValidPeriod(false);
// 登陆成功后清除缓存中的用户后台权限
jwtAuthenticationService.removeApiAuthList(userId);
if (logger.isDebugEnabled()) {
logger.debug("print return json:{}", JSON.toJSONString(result, true));
}
return result;
}
private void needChangePassword(User tempUser, OperationResultDto<LoginOutputDto> newloginResult) { private void needChangePassword(User tempUser, OperationResultDto<LoginOutputDto> newloginResult) {
// 这不可能发生,InActive的用户会被activeCheck方法拒绝登录 // 这不可能发生,InActive的用户会被activeCheck方法拒绝登录
throw new ApplicationException("Not happens"); throw new ApplicationException("Not happens");
...@@ -945,4 +1032,5 @@ public class UserServiceImpl extends AbstractService { ...@@ -945,4 +1032,5 @@ public class UserServiceImpl extends AbstractService {
return operationResultDto; return operationResultDto;
} }
} }
...@@ -46,3 +46,10 @@ log.debug=${log.debug} ...@@ -46,3 +46,10 @@ log.debug=${log.debug}
env_type=${env_type} env_type=${env_type}
file_upload_post_url=${file_upload_post_url} file_upload_post_url=${file_upload_post_url}
file_upload_query_url=${file_upload_query_url} file_upload_query_url=${file_upload_query_url}
#didi-config
check_ticket=${check_ticket}
get_user_info_url=${get_user_info_url}
app_id=${app_id}
app_key=${app_key}
cookie.maxAgeSeconds=${cookie.maxAgeSeconds}
...@@ -42,3 +42,12 @@ log.debug=true ...@@ -42,3 +42,12 @@ log.debug=true
env_type=dev env_type=dev
file_upload_post_url=http://47.94.233.173:11005/resource/erp_tax_system file_upload_post_url=http://47.94.233.173:11005/resource/erp_tax_system
file_upload_query_url=http://47.94.233.173:11006/resource/erp_tax_system file_upload_query_url=http://47.94.233.173:11006/resource/erp_tax_system
#didi-config
#ϵַget_user_info_url=http://mis.diditaxi.com.cn/auth/sso/api/
check_ticket=false
get_user_info_url=http://mis-test.diditaxi.com.cn/auth/sso/api/
app_id=2500
app_key=983258e7fd04d7fa0534735f7b1c33f3
cookie.maxAgeSeconds=86400
...@@ -47,3 +47,10 @@ log.debug=false ...@@ -47,3 +47,10 @@ log.debug=false
env_type=pub env_type=pub
file_upload_post_url=http://100.69.238.155:8000/resource/erp_tax_system file_upload_post_url=http://100.69.238.155:8000/resource/erp_tax_system
file_upload_query_url=http://100.69.238.155:8001/resource/erp_tax_system file_upload_query_url=http://100.69.238.155:8001/resource/erp_tax_system
#ϵַget_user_info_url=http://mis.diditaxi.com.cn/auth/sso/api/
check_ticket=false
get_user_info_url=http://mis.diditaxi.com.cn/auth/sso/api/
app_id=2500
app_key=983258e7fd04d7fa0534735f7b1c33f3
cookie.maxAgeSeconds=86400
\ No newline at end of file
...@@ -24,7 +24,7 @@ public class JwtUtilTest { ...@@ -24,7 +24,7 @@ public class JwtUtilTest {
@Test @Test
public void generateTokenThenValidate() { public void generateTokenThenValidate() {
String token = jwtUtil.generateToken("admin", "Admin", "UUID_OF_ADMIN_USER"); String token = jwtUtil.generateToken("admin", "Admin", "UUID_OF_ADMIN_USER", "TEST_TICKET");
logger.debug("print token:{}", token); logger.debug("print token:{}", token);
JwtUser jwtUser = jwtUtil.parseToken(token); JwtUser jwtUser = jwtUtil.parseToken(token);
logger.debug("print jwtUser:{}", JSON.toJSONString(jwtUser, true)); logger.debug("print jwtUser:{}", JSON.toJSONString(jwtUser, true));
......
...@@ -34,7 +34,6 @@ import java.util.stream.Collectors; ...@@ -34,7 +34,6 @@ import java.util.stream.Collectors;
* @Date: 26/02/2019 11:56 * @Date: 26/02/2019 11:56
* @Description: * @Description:
*/ */
//public class DataInitTest extends CommonIT {
public class DataInitTest extends CommonIT { public class DataInitTest extends CommonIT {
private static final Logger logger = LoggerFactory.getLogger(DataInitTest.class); private static final Logger logger = LoggerFactory.getLogger(DataInitTest.class);
......
package pwc.taxtech.atms.common;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
* 依赖的jar包有:commons-lang-2.6.jar、httpclient-4.3.2.jar、httpcore-4.3.1.jar、commons-io-2.4.jar
* @author zhaoyb
*
*/
public class HttpUtil {
public static final int connTimeout=10000;
public static final int readTimeout=10000;
public static final String charset="UTF-8";
private static HttpClient client = null;
static {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(128);
cm.setDefaultMaxPerRoute(128);
client = HttpClients.custom().setConnectionManager(cm).build();
}
public static String postParameters(String url, String parameterStr) throws ConnectTimeoutException, SocketTimeoutException, Exception{
return post(url,parameterStr,"application/x-www-form-urlencoded",charset,connTimeout,readTimeout);
}
public static String postParameters(String url, String parameterStr,String charset, Integer connTimeout, Integer readTimeout) throws ConnectTimeoutException, SocketTimeoutException, Exception{
return post(url,parameterStr,"application/x-www-form-urlencoded",charset,connTimeout,readTimeout);
}
public static String postParameters(String url, Map<String, String> params) throws ConnectTimeoutException,
SocketTimeoutException, Exception {
return postForm(url, params, null, connTimeout, readTimeout);
}
public static String postParameters(String url, Map<String, String> params, Integer connTimeout,Integer readTimeout) throws ConnectTimeoutException,
SocketTimeoutException, Exception {
return postForm(url, params, null, connTimeout, readTimeout);
}
public static String get(String url) throws Exception {
return get(url, charset, null, null);
}
public static String get(String url, String charset) throws Exception {
return get(url, charset, connTimeout, readTimeout);
}
/**
* 发送一个 Post 请求, 使用指定的字符集编码.
*
* @param url
* @param body RequestBody
* @param mimeType 例如 application/xml "application/x-www-form-urlencoded" a=1&b=2&c=3
* @param charset 编码
* @param connTimeout 建立链接超时时间,毫秒.
* @param readTimeout 响应超时时间,毫秒.
* @return ResponseBody, 使用指定的字符集编码.
* @throws ConnectTimeoutException 建立链接超时异常
* @throws SocketTimeoutException 响应超时
* @throws Exception
*/
public static String post(String url, String body, String mimeType,String charset, Integer connTimeout, Integer readTimeout)
throws ConnectTimeoutException, SocketTimeoutException, Exception {
HttpClient client = null;
HttpPost post = new HttpPost(url);
String result = "";
try {
if (StringUtils.isNotBlank(body)) {
HttpEntity entity = new StringEntity(body, ContentType.create(mimeType, charset));
post.setEntity(entity);
}
// 设置参数
Builder customReqConf = RequestConfig.custom();
if (connTimeout != null) {
customReqConf.setConnectTimeout(connTimeout);
}
if (readTimeout != null) {
customReqConf.setSocketTimeout(readTimeout);
}
post.setConfig(customReqConf.build());
HttpResponse res;
if (url.startsWith("https")) {
// 执行 Https 请求.
client = createSSLInsecureClient();
res = client.execute(post);
} else {
// 执行 Http 请求.
client = HttpUtil.client;
res = client.execute(post);
}
result = IOUtils.toString(res.getEntity().getContent(), charset);
} finally {
post.releaseConnection();
if (url.startsWith("https") && client != null&& client instanceof CloseableHttpClient) {
((CloseableHttpClient) client).close();
}
}
return result;
}
/**
* 提交form表单
*
* @param url
* @param params
* @param connTimeout
* @param readTimeout
* @return
* @throws ConnectTimeoutException
* @throws SocketTimeoutException
* @throws Exception
*/
public static String postForm(String url, Map<String, String> params, Map<String, String> headers, Integer connTimeout,Integer readTimeout) throws ConnectTimeoutException,
SocketTimeoutException, Exception {
HttpClient client = null;
HttpPost post = new HttpPost(url);
try {
if (params != null && !params.isEmpty()) {
List<NameValuePair> formParams = new ArrayList<NameValuePair>();
Set<Entry<String, String>> entrySet = params.entrySet();
for (Entry<String, String> entry : entrySet) {
formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, Consts.UTF_8);
post.setEntity(entity);
}
if (headers != null && !headers.isEmpty()) {
for (Entry<String, String> entry : headers.entrySet()) {
post.addHeader(entry.getKey(), entry.getValue());
}
}
// 设置参数
Builder customReqConf = RequestConfig.custom();
if (connTimeout != null) {
customReqConf.setConnectTimeout(connTimeout);
}
if (readTimeout != null) {
customReqConf.setSocketTimeout(readTimeout);
}
post.setConfig(customReqConf.build());
HttpResponse res = null;
if (url.startsWith("https")) {
// 执行 Https 请求.
client = createSSLInsecureClient();
res = client.execute(post);
} else {
// 执行 Http 请求.
client = HttpUtil.client;
res = client.execute(post);
}
return IOUtils.toString(res.getEntity().getContent(), "UTF-8");
} finally {
post.releaseConnection();
if (url.startsWith("https") && client != null
&& client instanceof CloseableHttpClient) {
((CloseableHttpClient) client).close();
}
}
}
/**
* 发送一个 GET 请求
*
* @param url
* @param charset
* @param connTimeout 建立链接超时时间,毫秒.
* @param readTimeout 响应超时时间,毫秒.
* @return
* @throws ConnectTimeoutException 建立链接超时
* @throws SocketTimeoutException 响应超时
* @throws Exception
*/
public static String get(String url, String charset, Integer connTimeout,Integer readTimeout)
throws ConnectTimeoutException,SocketTimeoutException, Exception {
HttpClient client = null;
HttpGet get = new HttpGet(url);
String result = "";
try {
// 设置参数
Builder customReqConf = RequestConfig.custom();
if (connTimeout != null) {
customReqConf.setConnectTimeout(connTimeout);
}
if (readTimeout != null) {
customReqConf.setSocketTimeout(readTimeout);
}
get.setConfig(customReqConf.build());
HttpResponse res = null;
if (url.startsWith("https")) {
// 执行 Https 请求.
client = createSSLInsecureClient();
res = client.execute(get);
} else {
// 执行 Http 请求.
client = HttpUtil.client;
res = client.execute(get);
}
result = IOUtils.toString(res.getEntity().getContent(), charset);
} finally {
get.releaseConnection();
if (url.startsWith("https") && client != null && client instanceof CloseableHttpClient) {
((CloseableHttpClient) client).close();
}
}
return result;
}
/**
* 从 response 里获取 charset
*
* @param ressponse
* @return
*/
@SuppressWarnings("unused")
private static String getCharsetFromResponse(HttpResponse ressponse) {
// Content-Type:text/html; charset=GBK
if (ressponse.getEntity() != null && ressponse.getEntity().getContentType() != null && ressponse.getEntity().getContentType().getValue() != null) {
String contentType = ressponse.getEntity().getContentType().getValue();
if (contentType.contains("charset=")) {
return contentType.substring(contentType.indexOf("charset=") + 8);
}
}
return null;
}
/**
* 创建 SSL连接
* @return
* @throws GeneralSecurityException
*/
private static CloseableHttpClient createSSLInsecureClient() throws GeneralSecurityException {
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] chain,String authType) throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
@Override
public void verify(String host, SSLSocket ssl)
throws IOException {
}
@Override
public void verify(String host, X509Certificate cert)
throws SSLException {
}
@Override
public void verify(String host, String[] cns,
String[] subjectAlts) throws SSLException {
}
});
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
} catch (GeneralSecurityException e) {
throw e;
}
}
public static void main(String[] args) {
try {
String str= post("https://localhost:443/ssl/test.shtml","name=12&page=34","application/x-www-form-urlencoded", "UTF-8", 10000, 10000);
//String str= get("https://localhost:443/ssl/test.shtml?name=12&page=34","GBK");
/*Map<String,String> map = new HashMap<String,String>();
map.put("name", "111");
map.put("page", "222");
String str= postForm("https://localhost:443/ssl/test.shtml",map,null, 10000, 10000);*/
System.out.println(str);
} catch (ConnectTimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SocketTimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
\ No newline at end of file
...@@ -13,6 +13,7 @@ public class AtmsTokenDto { ...@@ -13,6 +13,7 @@ public class AtmsTokenDto {
private String user_name; private String user_name;
private String vat_api_host; private String vat_api_host;
private String version; private String version;
private String ticket;
public String getAccess_token() { public String getAccess_token() {
return access_token; return access_token;
...@@ -110,6 +111,14 @@ public class AtmsTokenDto { ...@@ -110,6 +111,14 @@ public class AtmsTokenDto {
this.version = version; this.version = version;
} }
public String getTicket() {
return ticket;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
@Override @Override
public String toString() { public String toString() {
return "CookieModel [access_token=" + access_token + ", token_type=" + token_type + ", expires_in=" + expires_in return "CookieModel [access_token=" + access_token + ", token_type=" + token_type + ", expires_in=" + expires_in
......
...@@ -6,6 +6,10 @@ public class LoginInputDto { ...@@ -6,6 +6,10 @@ public class LoginInputDto {
private String password; private String password;
private String ticket;
private Integer type;
public String getEmail() { public String getEmail() {
return email; return email;
} }
...@@ -22,5 +26,19 @@ public class LoginInputDto { ...@@ -22,5 +26,19 @@ public class LoginInputDto {
this.password = password; this.password = password;
} }
public String getTicket() {
return ticket;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
} }
...@@ -2,12 +2,10 @@ package pwc.taxtech.atms.web.controller; ...@@ -2,12 +2,10 @@ package pwc.taxtech.atms.web.controller;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import javax.servlet.http.Cookie; import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -40,7 +38,7 @@ import pwc.taxtech.atms.dto.OperationResultDto; ...@@ -40,7 +38,7 @@ import pwc.taxtech.atms.dto.OperationResultDto;
import pwc.taxtech.atms.dto.OrganizationStructureDto; import pwc.taxtech.atms.dto.OrganizationStructureDto;
import pwc.taxtech.atms.web.AtmsWebSettings; import pwc.taxtech.atms.web.AtmsWebSettings;
/** @see PwC.Tax.Tech.Atms.Web\Controllers\AccountController.cs */
@Controller @Controller
@RequestMapping("/Account") @RequestMapping("/Account")
public class AccountController { public class AccountController {
...@@ -53,6 +51,11 @@ public class AccountController { ...@@ -53,6 +51,11 @@ public class AccountController {
@Autowired @Autowired
private RestTemplate restTemplate; private RestTemplate restTemplate;
// api callback.request
// resultDto (cookie:ticket,code)
// redirct -> #/overview/vat
@RequestMapping(value = "/LogOn", method = RequestMethod.POST) @RequestMapping(value = "/LogOn", method = RequestMethod.POST)
public @ResponseBody LoginOutputDto login(@RequestBody LoginInputDto input, HttpServletResponse response) public @ResponseBody LoginOutputDto login(@RequestBody LoginInputDto input, HttpServletResponse response)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
...@@ -75,7 +78,7 @@ public class AccountController { ...@@ -75,7 +78,7 @@ public class AccountController {
try { try {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
logger.debug("准备调用atms-api的login接口"); logger.debug("准备调用atms-api的login接口");
operationResultDto = callApiUserLogin(input.getEmail(), input.getPassword()); operationResultDto = callApiUserLogin(input);
logger.debug("atms-api的login接口返回,用时[{}ms]", System.currentTimeMillis() - start); logger.debug("atms-api的login接口返回,用时[{}ms]", System.currentTimeMillis() - start);
} catch (RestClientException e) { } catch (RestClientException e) {
logger.error("调用atms-api的login接口出错:" + e, e); logger.error("调用atms-api的login接口出错:" + e, e);
...@@ -157,17 +160,14 @@ public class AccountController { ...@@ -157,17 +160,14 @@ public class AccountController {
return resultLoginOutputDto; return resultLoginOutputDto;
} }
private OperationResultDto<LoginOutputDto> callApiUserLogin(String email, String password) { private OperationResultDto<LoginOutputDto> callApiUserLogin(LoginInputDto input) {
String url = atmsWebSettings.getApiUrl() + "/api/v1/user/login"; String url = atmsWebSettings.getApiUrl() + "/api/v1/user/login";
logger.debug("Print url:{}", url); logger.debug("Print url:{}", url);
ParameterizedTypeReference<OperationResultDto<LoginOutputDto>> parameterizedTypeReference = new ParameterizedTypeReference<OperationResultDto<LoginOutputDto>>() { ParameterizedTypeReference<OperationResultDto<LoginOutputDto>> parameterizedTypeReference = new ParameterizedTypeReference<OperationResultDto<LoginOutputDto>>() {
}; };
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8); headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
LoginInputDto loginInputDto = new LoginInputDto(); HttpEntity<LoginInputDto> requestEntity = new HttpEntity<>(input, headers);
loginInputDto.setEmail(email);
loginInputDto.setPassword(password);
HttpEntity<LoginInputDto> requestEntity = new HttpEntity<>(loginInputDto, headers);
ResponseEntity<OperationResultDto<LoginOutputDto>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, ResponseEntity<OperationResultDto<LoginOutputDto>> responseEntity = restTemplate.exchange(url, HttpMethod.POST,
requestEntity, parameterizedTypeReference); requestEntity, parameterizedTypeReference);
...@@ -180,11 +180,11 @@ public class AccountController { ...@@ -180,11 +180,11 @@ public class AccountController {
// operationResultDto.getResult(), // operationResultDto.getResult(),
// "operationResultDto.getResult() is false"); // "operationResultDto.getResult() is false");
return operationResultDto; return operationResultDto;
} }
@RequestMapping(value = { "/LogOut", "/Logout" }, produces = "text/html;charset=UTF-8") @RequestMapping(value = {"/LogOut", "/Logout"}, produces = "text/html;charset=UTF-8")
public ModelAndView logout(HttpServletRequest request, HttpServletResponse response) { public void logout(HttpServletRequest request, HttpServletResponse response) {
try {
HttpSession session = request.getSession(false); HttpSession session = request.getSession(false);
if (session != null) { if (session != null) {
// 删除会话 // 删除会话
...@@ -193,9 +193,25 @@ public class AccountController { ...@@ -193,9 +193,25 @@ public class AccountController {
Cookie cookie = new Cookie("AtmsApiToken", ""); Cookie cookie = new Cookie("AtmsApiToken", "");
cookie.setPath("/"); cookie.setPath("/");
cookie.setMaxAge(0); cookie.setMaxAge(0);
Cookie ddCodeCookie = new Cookie("ddCode", "");
ddCodeCookie.setPath("/");
ddCodeCookie.setMaxAge(0);
Cookie ddTicketCookie = new Cookie("ddTicket", "");
ddTicketCookie.setPath("/");
ddTicketCookie.setMaxAge(0);
Cookie ddJumptoCookie = new Cookie("ddJumpto", "");
ddJumptoCookie.setPath("/");
ddJumptoCookie.setMaxAge(0);
// 删除Cookie // 删除Cookie
response.addCookie(cookie); response.addCookie(cookie);
return new ModelAndView("logon"); response.addCookie(ddCodeCookie);
response.addCookie(ddTicketCookie);
response.addCookie(ddJumptoCookie);
// todo 这里写死为DD的登出地址了
response.sendRedirect(" http://mis.diditaxi.com.cn/auth/ldap/logout?app_id=2500");
} catch (Exception e) {
logger.error("登出失败", e);
}
} }
......
package pwc.taxtech.atms.web.controller; package pwc.taxtech.atms.web.controller;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;
import pwc.taxtech.atms.common.HttpUtil;
import pwc.taxtech.atms.dto.AtmsTokenDto; import pwc.taxtech.atms.dto.AtmsTokenDto;
import pwc.taxtech.atms.dto.LoginOutputDto;
import pwc.taxtech.atms.web.AtmsWebSettings;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.Cookie; import javax.servlet.http.Cookie;
...@@ -16,16 +27,35 @@ import javax.servlet.http.HttpServletRequest; ...@@ -16,16 +27,35 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.Map;
@Controller @Controller
@RequestMapping("/") @RequestMapping("/")
public class IndexController { public class IndexController {
private static Logger logger = LoggerFactory.getLogger(IndexController.class);
@Value("${api.url}") @Value("${api.url}")
private String apiUrl; private String apiUrl;
@Value("${get_user_info_url}")
private String getUserInfoUrl;
@Value("${app_id}")
private String appId;
@Value("${app_key}")
private String appKey;
@Autowired @Autowired
JwtUtil jwtUtil; JwtUtil jwtUtil;
@Autowired
private AtmsWebSettings atmsWebSettings;
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = {"/", "/index", "/index.html"}, method = RequestMethod.GET) @RequestMapping(value = {"/", "/index", "/index.html"}, method = RequestMethod.GET)
public String login(@CookieValue(value = "AtmsApiToken", required = false) String atmsApiToken, public String login(@CookieValue(value = "AtmsApiToken", required = false) String atmsApiToken,
@CookieValue(value = "LtpaToken", required = false) String ltpaToken, @CookieValue(value = "LtpaToken", required = false) String ltpaToken,
...@@ -63,6 +93,28 @@ public class IndexController { ...@@ -63,6 +93,28 @@ public class IndexController {
return "redirect:Account/LogOn"; return "redirect:Account/LogOn";
} }
@RequestMapping(value = {"/sso/callback"}, method = RequestMethod.GET)
public String ddSSOCallback(@RequestParam(value = "jumpto") String jumpto,
@RequestParam(value = "code") String code,
HttpServletResponse response) throws IOException, ServletException {
try{
String ticketStr = getTicket(code);
Cookie codeCookie = new Cookie("ddCode",URLEncoder.encode(code, "UTF-8"));
codeCookie.setPath("/");
Cookie ddTicket = new Cookie("ddTicket",URLEncoder.encode(ticketStr, "UTF-8"));
ddTicket.setPath("/");
Cookie jumptoCookie = new Cookie("ddJumpto",URLEncoder.encode(jumpto, "UTF-8"));
jumptoCookie.setPath("/");
response.addCookie(codeCookie);
response.addCookie(jumptoCookie);
response.addCookie(ddTicket);
}catch (Exception e){
logger.error("ddSSOCallback error",e);
}
return "redirect:/Account/LogOn";
}
@RequestMapping(value = {"/admin", "/admin.html"}, method = RequestMethod.GET) @RequestMapping(value = {"/admin", "/admin.html"}, method = RequestMethod.GET)
public String admin(@CookieValue(value = "AtmsApiToken", required = false) String atmsApiToken) { public String admin(@CookieValue(value = "AtmsApiToken", required = false) String atmsApiToken) {
if (StringUtils.hasText(atmsApiToken)) { if (StringUtils.hasText(atmsApiToken)) {
...@@ -71,4 +123,24 @@ public class IndexController { ...@@ -71,4 +123,24 @@ public class IndexController {
return "redirect:Account/LogOn"; return "redirect:Account/LogOn";
} }
public String getTicket(String code) {
try{
JSONObject object;
String ddResp = HttpUtil.post(getUserInfoUrl + "check_code", "code=" + code + "&app_key=" + appKey+ "&app_id=" + appId, "application/x-www-form-urlencoded", "UTF-8", 10000, 10000);
object = JSONObject.parseObject(ddResp);
Map<String, Object> res = object.getInnerMap();
int errno = (int) res.get("errno");
if (errno != 0) {
logger.warn(String.format("DD Ticket get Failed:[%s]", object.toJSONString()));
return null;
}else{
Map<String, String> data = (Map)res.get("data");
return data.get("ticket");
}
}catch (Exception e){
logger.error(String.format("通过code:[%s]获取Ticket失败",code));
}
return null;
}
} }
api.url=${api.url} api.url=${api.url}
cookie.maxAgeSeconds=${cookie.maxAgeSeconds}
jwt.base64Secret=${jwt.base64Secret} jwt.base64Secret=${jwt.base64Secret}
jwt.powerToken=${jwt.powerToken} jwt.powerToken=${jwt.powerToken}
...@@ -9,3 +7,10 @@ jwt.refreshSecond=${jwt.refreshSecond} ...@@ -9,3 +7,10 @@ jwt.refreshSecond=${jwt.refreshSecond}
#log #log
log.level=${log.level} log.level=${log.level}
#didi-config
check_ticket=${check_ticket}
get_user_info_url=${get_user_info_url}
app_id=${app_id}
app_key=${app_key}
cookie.maxAgeSeconds=${cookie.maxAgeSeconds}
api.url=http://dts.erp.didichuxing.com:8180/ api.url=http://dts.erp.didichuxing.com:8180/
cookie.maxAgeSeconds=86400
jwt.base64Secret=TXppQjFlZFBSbnJzMHc0Tg== jwt.base64Secret=TXppQjFlZFBSbnJzMHc0Tg==
jwt.powerToken=xxxx jwt.powerToken=xxxx
jwt.expireSecond=180000 jwt.expireSecond=180000
jwt.refreshSecond=600 jwt.refreshSecond=600
log.level=DEBUG log.level=DEBUG
#didi-config
check_ticket=false
get_user_info_url=http://mis-test.diditaxi.com.cn/auth/sso/api/
app_id=2500
app_key=983258e7fd04d7fa0534735f7b1c33f3
cookie.maxAgeSeconds=86400
\ No newline at end of file
api.url=http://172.20.201.164:8180/ api.url=http://172.20.201.164:8180/
cookie.maxAgeSeconds=86400
jwt.base64Secret=TXppQjFlZFBSbnJzMHc0Tg== jwt.base64Secret=TXppQjFlZFBSbnJzMHc0Tg==
jwt.powerToken=xxxx jwt.powerToken=xxxx
jwt.expireSecond=180000 jwt.expireSecond=180000
jwt.refreshSecond=600 jwt.refreshSecond=600
log.level=INFO log.level=INFO
#didi-config
check_ticket=false
get_user_info_url=http://mis-test.diditaxi.com.cn/auth/sso/api/
app_id=2500
app_key=983258e7fd04d7fa0534735f7b1c33f3
cookie.maxAgeSeconds=86400
\ No newline at end of file
...@@ -570,6 +570,6 @@ grunt.registerTask('dev', '开发环境', function () { ...@@ -570,6 +570,6 @@ grunt.registerTask('dev', '开发环境', function () {
'concat:commonJs', 'concat:frameworkJs','concat:frameworkLess', 'concat:commonJs', 'concat:frameworkJs','concat:frameworkLess',
'concat:taxDocumentManageLess', 'concat:taxDocumentManageJs','concat:appJs', 'concat:taxDocumentManageLess', 'concat:taxDocumentManageJs','concat:appJs',
'concat:vatJs', 'concat:vatCss','concat:vatLess', 'concat:vatJs', 'concat:vatCss','concat:vatLess',
'concat:dataImpJs', 'concat:dataImpCss','concat:dataImpLess', 'concat:dataImpJs', 'concat:dataImpCss','concat:dataImpLess','concat:scriptsLogin',
'less', 'copy', 'clean']) 'less', 'copy', 'clean'])
}); });
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
// store login info. // store login info.
var loginModel = {}; var loginModel = {};
var checkResult = {}; var checkResult = {};
var cookie = document.cookie;
var ticket = "";
var failFullLoginCount = 0, failMemberLoginCount = 0; var failFullLoginCount = 0, failMemberLoginCount = 0;
if (!window.console) window.console = {}; if (!window.console) window.console = {};
...@@ -43,10 +47,12 @@ ...@@ -43,10 +47,12 @@
$('loginFullEmail').focus(); $('loginFullEmail').focus();
}; };
var resetLoginModel = function (email, password) { var resetLoginModel = function (email, password,ticket,type) {
loginModel = { loginModel = {
email: email, email: email,
password: password password: password,
ticket:ticket,
type:type
}; };
} }
...@@ -412,6 +418,27 @@ ...@@ -412,6 +418,27 @@
} }
}); });
}; };
if(""!==cookie&&getCookie("ddTicket")){
ticket = getCookie("ddTicket");
loginForm.resetLoginModel("DD", "DD".val(),ticket,1);
login($(this), function () {
// todo DD logOut
setTimeout(function () {
resetErrorStatus();
}, 20);
});
}
function getCookie(name) {
var list = cookie.split("; ");
for(var i = 0; i < list.length; i++) {
var arr = list[i].split("=");
if(arr[0] == name)
return decodeURIComponent(arr[1]);
}
return "";
}
// initialize // initialize
// bind events // bind events
...@@ -424,9 +451,8 @@ ...@@ -424,9 +451,8 @@
// validatorFull.focusInvalid(); // validatorFull.focusInvalid();
return; return;
} }
// set the login data to post // set the login data to post
loginForm.resetLoginModel($('#loginFullEmail').val(), $('#loginFullPwd').val()); loginForm.resetLoginModel($('#loginFullEmail').val(), $('#loginFullPwd').val(),ticket,0);
login($(this), function () { login($(this), function () {
if (!$('#loginFull').valid()) { if (!$('#loginFull').valid()) {
//fix bug 1888 //fix bug 1888
...@@ -481,7 +507,7 @@ ...@@ -481,7 +507,7 @@
return; return;
} }
loginForm.resetLoginModel($('#findFullEmail').val(), null); loginForm.resetLoginModel($('#findFullEmail').val(), null,ticket,0);
// send password over email user entered // send password over email user entered
sendPassword($('#findFullEmail').val(), $(this), function () { sendPassword($('#findFullEmail').val(), $(this), function () {
// case of send email success // case of send email success
......
<!--@using Scripts = System.Web.Optimization.Scripts
@using Styles = System.Web.Optimization.Styles
@{
Layout = null;
}-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" http-equiv="X-UA-Compatible" content="chrome=1; IE=11; IE=10; IE=9; IE=EDGE">
<title>Apex+</title>
<link href="favicon.ico" rel="shortcut icon" type="image/x-icon" />
<!-- @Styles.Render("~/Account/login") -->
<link href="/bundles/accountLogin.css" rel="stylesheet" type="text/css" />
</head>
<body class="login-body">
<!-- @Html.AntiForgeryToken() -->
<div class="login">
<div class="tilte">
<span class="text" id="logo_text">Apex+</span>
</div>
<div id="mainForm" class="form-wrapper">
<form id="loginFull" class="frame form-main-content">
<div class="background-frame">
<img src="/app-resources/images/load-indicator.gif" id="createIndicator" class="loadingImg" style="display:none" alt="loading">
</div>
<!--<div class="loginframe">
<div class="loginfull">
<div class="form-group">
<input id="loginFullEmail" name="loginFullEmail" type="text" placeholder="用户名" class="form-control-customer" />
</div>
<div class="form-group">
<input id="loginFullPwd" name="loginFullPwd" type="password" placeholder="密码" class="form-control-customer" />
</div>
<!--<div class="form-group">-->
<!--<a href="javascript:void(0)" id="btnShowForgotPwd" rel="forgot_password" class="form-forget-password">忘记密码?</a>-->
<!--</div>-->
</div>
<div class="button-wrapper">
<button id="btnFullLogin" class="btn-customer btn-customer-lg login-button" type="button" tabindex="0">登录</button>
</div>
</div> -->
</form>
<form id="forget_password_form" class="frame form-main-content">
<div class="background-frame">
</div>
<div class="loginframe">
<div class="loginfull">
<div class="form-group">
<input id="findFullEmail" name="findFullEmail" type="text" spellcheck="false" placeholder="新密码将会发送至您的注册邮箱" class="form-control-customer" />
</div>
<div class="form-group">
<input type="text" class="form-control-customer" style="visibility:hidden" />
</div>
<div class="form-group">
<a href="javascript:void(0)" rel="forgot_password" class="form-forget-password btnLoginFrame">返回登录?</a>
</div>
</div>
<div class="button-wrapper">
<button id="btnSendPwd" class="btn-customer btn-customer-lg login-button" type="button" tabindex="0">发送</button>
</div>
</div>
</form>
<form id="forget_password_form_sucess" class="frame form-main-content">
<div class="background-frame">
</div>
<div class="loginframe">
<div class="loginfull">
<div class="form-group">
<label class="successMsg"> 邮件发送成功!</label>
</div>
<div class="form-group">
<input type="text" class="form-control-customer" style="visibility:hidden" />
</div>
<div class="form-group">
<a href="javascript:void(0)" rel="forgot_password" class="form-forget-password btnLoginFrame">返回登陆?</a>
</div>
</div>
</div>
</form>
</div>
</div>
<div id="wait" class="notice-center" style="display:none">
<div> 系统正在加载中,请稍等... </div>
<div class='uil-flickr-css' style='transform:scale(0.26);margin:-112px;margin-left: 125px;'> <div></div><div></div></div>
</div>
<!-- @Scripts.Render("~/bundles/modernizr")
@Scripts.Render("~/bundles/jquery", "~/Scripts/login") -->
<script type="text/javascript" src="/bundles/modernizr.js"></script>
<script type="text/javascript" src="/bundles/jquery.js"></script>
<script type="text/javascript" src="/bundles/scriptsLogin.js"></script>
</body>
</html>
/* base color */
a {
color: #404041;
}
a:hover, a:visited, a:active, a:checked {
color: #602320;
}
.badge {
background-color: #968c6d;
}
.navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus {
/*background-color: #e7e7e8;*/
background-color: #ef9800;
}
.align-right {
float:right;
display:inline-block;
margin-right:15px;
}
.alert-info {
background-image: none;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
background-repeat: repeat-x;
border-color: #c7c8ca;
color: #404041;
background-color: #f5f4f0;
border-color: #c7c8ca;
}
.alert-warning {
background-image: none;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
background-repeat: repeat-x;
border-color: #f7cbc7;
color: #404041;
background-color: #fae2bf;
border-color: #f7cbc7;
}
.alert-danger {
background-image: none;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
background-repeat: repeat-x;
border-color: #e0301e;
color: #FFF;
background-color: #e0301e;
border-color: #e0301e;
}
.cursorpointer {
cursor: pointer;
}
.link-no-underline, .link-no-underline:active, .link-no-underline:hover {
text-decoration: none;
}
.btn-customer {
display: inline-block;
margin-bottom: 0;
font-weight: normal;
text-align: center;
vertical-align: middle;
cursor: pointer;
background-image: none;
border: 1px solid transparent;
white-space: nowrap;
padding: 5px 12px;
line-height: 1.5;
border-radius: 4px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.btn-customer-lg,
.btn-customer-group-lg > .btn-customer {
padding: 6px 12px;
font-size: 20px;
line-height: 1.33;
border-radius: 6px;
}
.btn-customer:focus,
.btn-customer:active:focus,
.btn-customer.active:focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
.btn-customer:hover,
.btn-customer:focus {
/*color: #555555;*/
/*text-decoration: none;*/
}
.btn-customer:active,
.btn-customer.active {
outline: 0;
background-image: none;
background-color: #bed1e1;
}
.btn-customer.disabled,
.btn-customer[disabled],
.form-control-customer {
display: block;
width: 100%;
height: 31px;
padding: 5px 12px;
font-size: 20px;
line-height: 1.5;
color: #555555;
background-color: #ffffff;
background-image: none;
border: 1px solid #cccccc;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
}
.form-control.select-fix {
width: auto;
display: inline-block;
font-size: 14px;
margin-right: 15px;
}
.btn-fix.disabled,
.btn-fix[disabled] {
display: inline-block;
font-size: 14px;
width: auto;
}
.form-control-customer:focus {
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
}
.form-control-customer[disabled],
.form-control-customer[readonly],
fieldset[disabled] .form-control-customer {
cursor: not-allowed;
background-color: #f2f2f2;
opacity: 1;
}
textarea.form-control-customer {
height: auto;
}
span.form-control-customer {
border: none;
box-shadow: none;
}
.progress-bar {
background-color: #eb8c00;
}
/* LOGIN */
body.login-body {
background: #999999 url('/app-resources/images/login_pic.jpg') no-repeat;
height: calc(100% - 16px);
background-size: cover;
color: #333;
overflow-y: auto;
}
.login {
display: block;
margin-top: 108px;
margin-left: 120px;
width: 648px;
float: right;
font-family: "Helvetica Neue", Helvetica, Microsoft Yahei, Hiragino Sans GB, WenQuanYi Micro Hei, sans-serif;
}
.tilte {
clear: both;
margin-left: 50px;
width: 227px;
height: 114px;
font-family: 'Papyrus Bold', 'Papyrus';
font-weight: 700;
font-style: normal;
font-size: 72px;
color: #A32020;
}
.tilte .text {
position: absolute;
}
.background-frame {
background-repeat: no-repeat;
/*background-image: url('/app-resources/images/form_bg.png');*/
float: left;
display: block;
width: 643px;
height: 358px;
opacity: 0.7;
z-index: -99;
}
.loginframe {
position: relative;
display: block;
width: 410px;
height: 158px;
float: left;
margin-top: -248px;
z-index: 10;
padding-left: 120px;
}
.frame {
display: none;
}
.show {
display: block !important;
}
/* Form Style */
.form-wrapper {
width: 400px;
font-weight: 400;
font-style: normal;
font-size: 13px;
color: #333333;
text-align: center;
line-height: normal;
margin-top: -45px;
}
.form-wrapper input, .form-wrapper button {
opacity: 1;
}
.loginfull {
width: 270px;
height: 150px;
float: left;
color: white;
clear: both !important;
}
.button-wrapper {
display: block;
float: left;
margin-left: 40px;
height: 150px;
}
.login-button {
background-color: #eb8c00;
color: #fff;
width: 100px;
height: 100px;
}
.login-button:hover {
color: #fff;
background-color: #dc6900;
}
.login-button:disabled {
background-color: #968c6d;
color: #fff;
width: 100px;
height: 100px;
}
.loginfull input::-webkit-input-placeholder {
font-weight: 400;
font-size: 18px;
font-style: normal;
color: #FFFFFF !important;
font-family: "Helvetica Neue", Helvetica, Microsoft Yahei, Hiragino Sans GB, WenQuanYi Micro Hei, sans-serif;
}
.loginfull input:-moz-placeholder {
font-weight: 400;
font-size: 18px;
font-style: normal;
color: #FFFFFF !important;
font-family: "Helvetica Neue", Helvetica, Microsoft Yahei, Hiragino Sans GB, WenQuanYi Micro Hei, sans-serif;
}
.loginfull input::-moz-placeholder {
font-weight: 400;
font-size: 18px;
font-style: normal;
color: #FFFFFF !important;
font-family: "Helvetica Neue", Helvetica, Microsoft Yahei, Hiragino Sans GB, WenQuanYi Micro Hei, sans-serif;
}
.loginfull input:-ms-input-placeholder {
font-weight: 400;
font-size: 18px;
font-style: normal;
color: #FFFFFF !important;
font-family: "Helvetica Neue", Helvetica, Microsoft Yahei, Hiragino Sans GB, WenQuanYi Micro Hei, sans-serif;
}
.loginfull .form-control-customer {
background-color: #404041;
color: #FFFFFF;
font-weight: 400;
font-size: 18px;
font-style: normal;
height: 28px;
border-radius: 10px;
}
.loginfull .form-control-customer.has-error {
border-color: #a94442;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
}
.loginfull .successMsg {
float: left;
text-decoration: none;
color: #a94442;
font-size: 28px;
font-weight: 200;
margin-left: 56px;
}
.loginfull .form-forget-password {
float: left;
text-decoration: none;
color: #dc6900;
font-size: 18px;
font-weight: 200;
margin-left: 6px;
}
.has-error.label {
color: #a94442;
font-weight: 700;
}
.loadingImg {
margin-top: 135px;
z-index: -9;
margin-left: 310px;
}
.form-group {
margin-bottom: 20px;
}
form.active {
display: block !important;
height: auto;
}
form.loginfull .form-group,
form.login .form-group,
form.forgot_password .form-group,
form.email_sent .form-group,
form.forgot_fivetimes .form-group {
margin: 20px 0 20px 0;
}
form.userchoose .form-group {
margin: 0 0 10px 0;
}
.login .list-group-item-heading {
margin: 5px 0 5px 0;
}
/* LOGIN END */
/* Main page */
.navbar-brand {
float: left;
padding: 15.5px 15px;
font-size: 32px;
line-height: 19px;
height: 50px;
font-family: 'Papyrus Bold', 'Papyrus';
font-weight: 700;
font-style: normal;
color: #A32020;
}
.navbar-default .navbar-brand {
color: #A32020;
margin-left: 37px;
margin-right: 37px;
}
.sidebar-closed .navbar-default .navbar-brand {
display: none;
}
.navbar-brand:hover,
.navbar-brand:focus {
color: #A32020;
text-decoration: none;
}
@media (min-width: 768px) {
.navbar > .container .navbar-brand,
.navbar > .container-fluid .navbar-brand {
margin-left: -15px;
}
}
.navbar-fixed-top .navbar-collapse {
max-height: 440px;
}
.panelfix {
margin-bottom: 0;
border-radius: 0;
}
.navbarfix {
border-radius: 0;
}
.nav-split {
background-color: #A32020;
display: inline-block;
height: 42px;
width: 2px;
margin-top: 2px;
float: left;
margin-bottom: 0px;
margin-right: 10px;
}
.nav-company-name {
font-size: 25px;
margin-bottom: 0px;
margin-top: 10px;
font-weight: 100;
}
.nav-company {
display: none;
}
@media(min-width:768px) {
.nav-company {
display: block;
}
}
.navbar-customer {
margin-top: 0px;
width: 46px;
height: 50px;
margin-bottom: 0px;
margin-right: 10px;
padding-left: 11px;
padding-right: 11px;
border-radius: 0;
}
/* Progress */
.row-fix-width {
width: 960px;
}
.progress-table {
text-align: center;
}
.progress-table > tbody > tr > td:first-child {
text-align: left;
}
.progress-table > tbody > tr > td {
border-top: 0px;
}
.progress-table > tbody > tr > td:after {
border-top: 0px;
}
.progress-title {
text-shadow: none;
}
.btn-city {
width: 130px;
text-align: left;
}
.btn-default.step1 {
background-color: #e5e2db;
}
.btn-default.step2 {
background-color: #fae2bf;
}
.btn-default.step3 {
background-color: #f7cbc7;
}
.btn-default.step4 {
background-color: #f6d4da;
}
.btn-default.step5 {
background-color: #d7c8c7;
}
.btn-default.step6 {
background-color: #e5e2db;
}
.btn-default.review {
color: white;
background-color: #a32020;
}
.btn-default.signoff {
color: white;
background-color: #dc6900;
}
.td-line:after {
content: "";
position: absolute;
margin-top: -16px;
width: 150px;
border-bottom: 2px dashed #ccc;
}
.tr-hr:after {
content: "";
position: absolute;
margin-top: 23px;
margin-left: -720px;
width: 680px;
border-bottom: 2px dashed #e8c7c7;
}
.btn-customer.disabled, .btn-customer[disabled], fieldset[disabled] .btn-customer {
opacity: 0.5;
}
.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
border-top-right-radius: 15px;
border-bottom-right-radius: 15px;
}
.bootstrap-switch-gap {
margin-right: 10px;
}
.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-primary, .bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-primary {
background: #a32020;
}
.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-primary:hover, .bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-primary:hover {
background: #602320;
}
.bootstrap-switch.bootstrap-switch-focused {
border-color: #dc6900;
}
/* tab begin */
.nav-tabs > li .close {
margin: -2px 0 0 10px;
font-size: 18px;
}
.marginBottom {
padding-top: 3px;
margin-bottom: 1px !important;
margin-left: -15px;
}
.operationDiv {
padding: 5px 10px 5px 5px;
}
.operationDivWrapper {
margin-top: -1px;
}
.firstTab {
margin-left: 15px;
}
.leftMenu {
height: 70%;
background-color: #E6E6E6;
border-right: 2px solid #BFBFBF;
}
.close-tab-button {
margin-top: -41px;
margin-right: 6px;
font-size: 18px;
margin: -41px 6px 0 0 !important;
}
/* tab end */
.btn-position-fix {
margin-top: 25px;
}
.removeBackgroud > li > a:focus {
background-color: transparent;
color: #000;
}
.notice-center {
position: fixed;
top: 50%;
left: 50%;
/*background-color: #000;
width:50%;
height: 50%;*/
-webkit-transform: translateX(-50%) translateY(-50%);
-webkit-transform: translateX(-50%) translateY(-50%);
-moz-transform: translateX(-50%) translateY(-50%);
-ms-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
}
@-webkit-keyframes uil-flickr-anim1 {
0% {
left: 0;
}
50% {
left: 100px;
}
100% {
left: 0;
}
}
@-webkit-keyframes uil-flickr-anim1 {
0% {
left: 0;
}
50% {
left: 100px;
}
100% {
left: 0;
}
}
@-moz-keyframes uil-flickr-anim1 {
0% {
left: 0;
}
50% {
left: 100px;
}
100% {
left: 0;
}
}
@-ms-keyframes uil-flickr-anim1 {
0% {
left: 0;
}
50% {
left: 100px;
}
100% {
left: 0;
}
}
@-moz-keyframes uil-flickr-anim1 {
0% {
left: 0;
}
50% {
left: 100px;
}
100% {
left: 0;
}
}
@-webkit-keyframes uil-flickr-anim1 {
0% {
left: 0;
}
50% {
left: 100px;
}
100% {
left: 0;
}
}
@-o-keyframes uil-flickr-anim1 {
0% {
left: 0;
}
50% {
left: 100px;
}
100% {
left: 0;
}
}
@keyframes uil-flickr-anim1 {
0% {
left: 0;
}
50% {
left: 100px;
}
100% {
left: 0;
}
}
width: 100%; @-webkit-keyframes uil-flickr-anim2 {
0%;
{
left: 100px;
z-index: 1;
}
49% {
z-index: 1;
}
50% {
left: 0;
z-index: 10;
}
100% {
left: 100px;
z-index: 10;
}
}
@-webkit-keyframes uil-flickr-anim2 {
0% {
left: 100px;
z-index: 1;
}
49% {
z-index: 1;
}
50% {
left: 0;
z-index: 10;
}
100% {
left: 100px;
z-index: 10;
}
}
@-moz-keyframes uil-flickr-anim2 {
0% {
left: 100px;
z-index: 1;
}
49% {
z-index: 1;
}
50% {
left: 0;
z-index: 10;
}
100% {
left: 100px;
z-index: 10;
}
}
@-ms-keyframes uil-flickr-anim2 {
0% {
left: 100px;
z-index: 1;
}
49% {
z-index: 1;
}
50% {
left: 0;
z-index: 10;
}
100% {
left: 100px;
z-index: 10;
}
}
@-moz-keyframes uil-flickr-anim2 {
0% {
left: 100px;
z-index: 1;
}
49% {
z-index: 1;
}
50% {
left: 0;
z-index: 10;
}
100% {
left: 100px;
z-index: 10;
}
}
@-webkit-keyframes uil-flickr-anim2 {
0% {
left: 100px;
z-index: 1;
}
49% {
z-index: 1;
}
50% {
left: 0;
z-index: 10;
}
100% {
left: 100px;
z-index: 10;
}
}
@-o-keyframes uil-flickr-anim2 {
0% {
left: 100px;
z-index: 1;
}
49% {
z-index: 1;
}
50% {
left: 0;
z-index: 10;
}
100% {
left: 100px;
z-index: 10;
}
}
@keyframes uil-flickr-anim2 {
0% {
left: 100px;
z-index: 1;
}
49% {
z-index: 1;
}
50% {
left: 0;
z-index: 10;
}
100% {
left: 100px;
z-index: 10;
}
}
.uil-flickr-css {
background: none;
position: relative;
width: 200px;
height: 200px;
}
.uil-flickr-css > div {
width: 100px;
height: 100px;
border-radius: 50px;
position: absolute;
top: 50px;
}
.uil-flickr-css > div:nth-of-type(1) {
left: 0;
background: #e35839;
z-index: 5;
-ms-animation: uil-flickr-anim1 1s linear infinite;
-moz-animation: uil-flickr-anim1 1s linear infinite;
-webkit-animation: uil-flickr-anim1 1s linear infinite;
-o-animation: uil-flickr-anim1 1s linear infinite;
animation: uil-flickr-anim1 1s linear infinite;
}
.uil-flickr-css > div:nth-of-type(2) {
left: 100px;
background: #d28d4f;
-ms-animation: uil-flickr-anim2 1s linear infinite;
-moz-animation: uil-flickr-anim2 1s linear infinite;
-webkit-animation: uil-flickr-anim2 1s linear infinite;
-o-animation: uil-flickr-anim2 1s linear infinite;
animation: uil-flickr-anim2 1s linear infinite;
}
/* datepicker */
.datepicker table tr td span.active.active, .datepicker table tr td span.active.disabled.active, .datepicker table tr td span.active.disabled:active, .datepicker table tr td span.active.disabled:hover.active, .datepicker table tr td span.active.disabled:hover:active, .datepicker table tr td span.active:active, .datepicker table tr td span.active:hover.active, .datepicker table tr td span.active:hover:active {
color: #fff;
background-color: #eb8c00;
}
.datepicker table tr td span.active, .datepicker table tr td span.active.disabled, .datepicker table tr td span.active.disabled:hover, .datepicker table tr td span.active:hover {
color: #fff;
background-color: #eb8c00;
}
.datepicker table tr td span.active.active.focus, .datepicker table tr td span.active.active:focus, .datepicker table tr td span.active.active:hover, .datepicker table tr td span.active.disabled.active.focus, .datepicker table tr td span.active.disabled.active:focus, .datepicker table tr td span.active.disabled.active:hover, .datepicker table tr td span.active.disabled:active.focus, .datepicker table tr td span.active.disabled:active:focus, .datepicker table tr td span.active.disabled:active:hover, .datepicker table tr td span.active.disabled:hover.active.focus, .datepicker table tr td span.active.disabled:hover.active:focus, .datepicker table tr td span.active.disabled:hover.active:hover, .datepicker table tr td span.active.disabled:hover:active.focus, .datepicker table tr td span.active.disabled:hover:active:focus, .datepicker table tr td span.active.disabled:hover:active:hover, .datepicker table tr td span.active:active.focus, .datepicker table tr td span.active:active:focus, .datepicker table tr td span.active:active:hover, .datepicker table tr td span.active:hover.active.focus, .datepicker table tr td span.active:hover.active:focus, .datepicker table tr td span.active:hover.active:hover, .datepicker table tr td span.active:hover:active.focus, .datepicker table tr td span.active:hover:active:focus, .datepicker table tr td span.active:hover:active:hover {
color: #fff;
background-color: #dc6900;
}
.datepicker table tr td, .datepicker table tr th {
text-align: center;
}
/* ui select */
.ui-select-no-border, .ui-select-has-border {
display: inline-block;
cursor: pointer;
}
.search-container.ui-select-search-hidden {
display: none;
}
.ui-select-no-border .select2-container-active .select2-choice,
.ui-select-no-border .select2-container-active .select2-choices {
border: 1px solid rgba(0, 0, 0, 0.15);
}
.ui-select-no-border .select2-results .select2-highlighted {
background: #e0301e;
}
.ui-select-no-border .select2-results li,
.ui-select-no-border .select2-results,
.ui-select-no-border .select2-container {
outline: none;
}
.ui-select-no-border .select2-drop,
.ui-select-no-border .select2-dropdown-open .select2-choice,
.ui-select-no-border .select2-container-active .select2-choice,
.ui-select-no-border .select2-container-active .select2-choices {
border-radius: 0;
box-shadow: none;
-webkit-box-shadow: none;
}
.ui-select-no-border .select2-drop-active {
border: 1px solid rgba(0, 0, 0, 0.15);
}
.ui-select-no-border .select2-container .select2-choice .select2-arrow {
margin-right: 8px;
}
.ui-select-no-border .select2-container .select2-choice .select2-arrow,
.ui-select-no-border .select2-dropdown-open .select2-choice {
border-left: none;
background: none;
background-image: none;
}
.ui-select-no-border .select2-container .select2-choice .select2-arrow b {
background: url(/app-resources/images/vat/down.png) no-repeat scroll right center transparent;
}
.ui-select-no-border .select2-container .select2-choice {
border: none;
background-image: none;
background: none;
}
.ui-select-has-border .select2-drop-active {
border: 1px solid #adb4bd;
border-top: 1px solid #adb4bd;
}
.ui-select-has-border .select2-dropdown-open .select2-choice {
box-shadow: none;
background-color: none;
}
.ui-select-has-border .select2-container-active .select2-choices {
border: none;
}
.ui-select-has-border .select2-results .select2-highlighted {
background: #e0301e;
}
.ui-select-has-border .select2-container-active .select2-choice,
.ui-select-has-border .select2-container-active .select2-choices {
border: 1px solid #aaa;
}
.ui-select-has-border .select2-results li,
.ui-select-has-border .select2-results,
.ui-select-has-border .select2-container {
outline: none;
}
.ui-select-has-border .select2-container .select2-choice .select2-arrow {
border-left: none;
background: none;
background-image: none;
}
.ui-select-has-border .select2-container .select2-choice .select2-arrow b {
margin-top: 2px;
}
.ui-select-has-border .select2-container .select2-choice,
.ui-select-has-border .select2-container-active .select2-choice {
background-image: none;
background: none;
outline: none;
height: 34px;
padding: 6px 12px;
font-size: 14px;
line-height: 1.42857143;
color: #555555;
background-color: #ffffff;
background-image: none;
border: 1px solid #cccccc;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
}
.dx-checkbox-checked .dx-checkbox-icon {
color: #e0301e;
}
.dx-checkbox-indeterminate .dx-checkbox-icon:before {
background-color: #e0301e;
}
.dx-texteditor.dx-state-hover {
border-color: rgba(239, 213, 189, 0.5);
}
.dx-texteditor.dx-state-focused,
.dx-texteditor.dx-state-active {
border-color: rgba(239, 213, 189, 0.5);
}
.dx-list.dx-list-select-decorator-enabled .dx-list-item.dx-state-focused .dx-radiobutton-icon:before,
.dx-list.dx-list-select-decorator-enabled .dx-list-item.dx-state-focused .dx-checkbox-icon {
border: 1px solid rgba(239, 213, 189, 0.5);
}
.dx-list:not(.dx-list-select-decorator-enabled) .dx-list-item.dx-state-focused {
background-color: #dc6900;
}
.dx-list:not(.dx-list-select-decorator-enabled) .dx-list-item.dx-state-focused.dx-list-item-selected {
background-color: #dc6900;
}
.dx-list:not(.dx-list-select-decorator-enabled) .dx-list-item.dx-state-active {
background-color: #dc6900;
}
.dx-list:not(.dx-list-select-decorator-enabled) .dx-list-item.dx-state-active .dx-list-slide-item-content {
background-color: #dc6900;
}
.dx-list-item.dx-list-item-ghost-reordering.dx-state-focused.dx-state-hover {
border-top: 1px solid rgba(239, 213, 189, 0.5);
border-bottom: 1px solid rgba(239, 213, 189, 0.5);
}
.dx-list-slide-menu-button-menu {
background-color: #dc6900;
}
.dx-checkbox.dx-state-hover .dx-checkbox-icon {
border: 1px solid rgba(239, 213, 189, 0.5);
}
.dx-checkbox.dx-state-focused .dx-checkbox-icon {
border: 1px solid rgba(239, 213, 189, 0.5);
}
.dx-treeview .dx-treeview-node.dx-treeview-item-with-checkbox.dx-state-focused > .dx-checkbox .dx-checkbox-icon {
border: 1px solid rgba(239, 213, 189, 1);
}
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