14 changed files with 1374 additions and 1 deletions
@ -1,3 +1,6 @@ |
|||||||
# open-JSD-9519 |
# open-JSD-9519 |
||||||
|
|
||||||
JSD-9519 开机域认证 |
JSD-9519 开机域认证\ |
||||||
|
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ |
||||||
|
仅作为开发者学习参考使用!禁止用于任何商业用途!\ |
||||||
|
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。 |
@ -0,0 +1,22 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?><plugin> |
||||||
|
<id>com.fr.plugin.computer.domain.login</id> |
||||||
|
<name><![CDATA[开机域登录插件]]></name> |
||||||
|
<active>yes</active> |
||||||
|
<version>1.0</version> |
||||||
|
<env-version>10.0</env-version> |
||||||
|
<jartime>2018-03-12</jartime> |
||||||
|
<vendor>fr.open</vendor> |
||||||
|
<description><![CDATA[开机域登录插件]]></description> |
||||||
|
<change-notes><![CDATA[ |
||||||
|
|
||||||
|
]]></change-notes> |
||||||
|
|
||||||
|
<extra-decision> |
||||||
|
<ControllerRegisterProvider class="com.fr.plugin.domainlogin.controller.DomainLoginControllerProvider"/> |
||||||
|
<WebResourceProvider class="com.fr.plugin.domainlogin.webresource.DomainLoginWebResourceProvider"/> |
||||||
|
<LogInOutEventProvider class="com.fr.plugin.domainlogin.loginout.DomaintLogInOutEventProvider"/> |
||||||
|
</extra-decision> |
||||||
|
|
||||||
|
<lifecycle-monitor class="com.fr.plugin.domainlogin.DomainLoginPerformanceMonitor"/> |
||||||
|
<function-recorder class="com.fr.plugin.domainlogin.DomainLoginPerformanceMonitor"/> |
||||||
|
</plugin> |
@ -0,0 +1,27 @@ |
|||||||
|
package com.fr.plugin.domainlogin; |
||||||
|
|
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.plugin.context.PluginContext; |
||||||
|
import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; |
||||||
|
import com.fr.plugin.transform.FunctionRecorder; |
||||||
|
import com.fr.record.analyzer.EnableMetrics; |
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets; |
||||||
|
|
||||||
|
@EnableMetrics |
||||||
|
@FunctionRecorder |
||||||
|
public class DomainLoginPerformanceMonitor extends AbstractPluginLifecycleMonitor { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void afterRun(PluginContext pluginContext) { |
||||||
|
FineLoggerFactory.getLogger().info(pluginContext.getName() + "插件启动完成"); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void beforeStop(PluginContext pluginContext) { |
||||||
|
FineLoggerFactory.getLogger().info(pluginContext.getName()+"插件即将停止"); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
package com.fr.plugin.domainlogin.beans; |
||||||
|
|
||||||
|
public class DomainLoginBean { |
||||||
|
private String userInfo; |
||||||
|
private long timestamp; |
||||||
|
|
||||||
|
public String getUserInfo() { |
||||||
|
return userInfo; |
||||||
|
} |
||||||
|
|
||||||
|
public long getTimestamp() { |
||||||
|
return timestamp; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUserInfo(String userInfo) { |
||||||
|
this.userInfo = userInfo; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTimestamp(long timestamp) { |
||||||
|
this.timestamp = timestamp; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,91 @@ |
|||||||
|
package com.fr.plugin.domainlogin.controller; |
||||||
|
|
||||||
|
import com.fr.decision.authority.data.User; |
||||||
|
import com.fr.decision.webservice.Response; |
||||||
|
import com.fr.decision.webservice.annotation.LoginStatusChecker; |
||||||
|
import com.fr.decision.webservice.bean.authentication.LoginRequestInfoBean; |
||||||
|
import com.fr.decision.webservice.bean.authentication.LoginResponseInfoBean; |
||||||
|
import com.fr.decision.webservice.utils.DecisionServiceConstants; |
||||||
|
import com.fr.decision.webservice.v10.login.LoginService; |
||||||
|
import com.fr.decision.webservice.v10.user.UserService; |
||||||
|
import com.fr.plugin.domainlogin.beans.DomainLoginBean; |
||||||
|
import com.fr.security.encryption.transmission.impl.AESTransmissionEncryption; |
||||||
|
import com.fr.third.springframework.stereotype.Controller; |
||||||
|
import com.fr.third.springframework.web.bind.annotation.RequestBody; |
||||||
|
import com.fr.third.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import com.fr.third.springframework.web.bind.annotation.RequestMethod; |
||||||
|
import com.fr.third.springframework.web.bind.annotation.ResponseBody; |
||||||
|
import com.fr.web.controller.decision.api.auth.LoginResource; |
||||||
|
import com.fr.web.controller.decision.api.entry.HomePageResource; |
||||||
|
import com.fr.plugin.domainlogin.util.CBCDesUtil; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import java.nio.charset.StandardCharsets; |
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
@Controller |
||||||
|
@LoginStatusChecker( |
||||||
|
required = false //不需要验证是否登录
|
||||||
|
) |
||||||
|
public class DomainLoginController { |
||||||
|
|
||||||
|
private final static int MAX_LOGIN_DURATION = 2*60*1000; |
||||||
|
|
||||||
|
@RequestMapping( |
||||||
|
value = {"/localDomain/login"}, |
||||||
|
method = {RequestMethod.POST} |
||||||
|
) |
||||||
|
@ResponseBody |
||||||
|
public Response localDomainLogin(HttpServletRequest req, HttpServletResponse res, @RequestBody DomainLoginBean loginBean) throws Exception { |
||||||
|
|
||||||
|
String userInfo = loginBean.getUserInfo();// "Q8hphot6OxPHwCfpeofrbQ==";
|
||||||
|
FineLoggerFactory.getLogger().info("获取到的加密信息为:"+userInfo); |
||||||
|
String desKey = "desddddd"; |
||||||
|
String username = ""; |
||||||
|
try{ |
||||||
|
String decodeValue = CBCDesUtil.decodeValue(desKey,userInfo); |
||||||
|
username = decodeValue.split("\\\\")[1]; |
||||||
|
FineLoggerFactory.getLogger().info("解密结果为:"+username); |
||||||
|
} |
||||||
|
catch(Exception ex){ |
||||||
|
ex.printStackTrace(); |
||||||
|
FineLoggerFactory.getLogger().info("解密失败.."); |
||||||
|
return Response.error("11300007","登录失败"); |
||||||
|
} |
||||||
|
|
||||||
|
//先判断时间戳能对上不
|
||||||
|
long timeStamp = loginBean.getTimestamp()+MAX_LOGIN_DURATION; |
||||||
|
long currentTimeStamp = new Date().getTime(); |
||||||
|
if(timeStamp < currentTimeStamp){ |
||||||
|
FineLoggerFactory.getLogger().info("当前时间戳超时了。。。"); |
||||||
|
return Response.error("11300007","登录失败"); |
||||||
|
} |
||||||
|
else{ |
||||||
|
//判断该用户存在不
|
||||||
|
User user = UserService.getInstance().getUserByUserName(username); |
||||||
|
if(user == null){ |
||||||
|
FineLoggerFactory.getLogger().info("决策系统里不存在用户:"+username); |
||||||
|
return Response.error("21300006","用户不可用"); |
||||||
|
} |
||||||
|
|
||||||
|
// LoginRequestInfoBean infoBean = new LoginRequestInfoBean();
|
||||||
|
// infoBean.setEncrypted(true);
|
||||||
|
// infoBean.setPassword(AESTransmissionEncryption.getInstance().encrypt(loginBean.getPasswd()));
|
||||||
|
// infoBean.setUsername(loginBean.getUserName());
|
||||||
|
// infoBean.setValidity(-1);
|
||||||
|
// LoginResponseInfoBean responseBean = LoginService.getInstance().login(req,res,infoBean);
|
||||||
|
String token = LoginService.getInstance().login(req,res,username); |
||||||
|
FineLoggerFactory.getLogger().info("登录返回token:"+token); |
||||||
|
if(token != null){ |
||||||
|
req.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, token); |
||||||
|
return Response.ok(token); |
||||||
|
} |
||||||
|
else{ |
||||||
|
return Response.error("11300007","登录失败"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
package com.fr.plugin.domainlogin.controller; |
||||||
|
|
||||||
|
import com.fr.decision.fun.impl.AbstractControllerRegisterProvider; |
||||||
|
|
||||||
|
public class DomainLoginControllerProvider extends AbstractControllerRegisterProvider { |
||||||
|
@Override |
||||||
|
public Class<?>[] getControllers() { |
||||||
|
return new Class[]{ |
||||||
|
DomainLoginController.class |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
package com.fr.plugin.domainlogin.loginout; |
||||||
|
|
||||||
|
import com.fr.decision.fun.impl.AbstractLogInOutEventProvider; |
||||||
|
import com.fr.decision.webservice.login.LogInOutResultInfo; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import javax.servlet.http.Cookie; |
||||||
|
public class DomaintLogInOutEventProvider extends AbstractLogInOutEventProvider{ |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public String logoutAction( LogInOutResultInfo result ) { |
||||||
|
FineLoggerFactory.getLogger().info(result.getUsername()+"log out!"); |
||||||
|
Cookie cookie = new Cookie("domainloginflag","1"); |
||||||
|
cookie.setPath("/"); |
||||||
|
result.getResponse().addCookie(cookie); |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,308 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. |
||||||
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. |
||||||
|
*/ |
||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||||
|
* (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
package com.fr.plugin.domainlogin.util; |
||||||
|
|
||||||
|
/** |
||||||
|
* This class provides encode/decode for RFC 2045 Base64 as |
||||||
|
* defined by RFC 2045, N. Freed and N. Borenstein. |
||||||
|
* RFC 2045: Multipurpose Internet Mail Extensions (MIME) |
||||||
|
* Part One: Format of Internet Message Bodies. Reference |
||||||
|
* 1996 Available at: http://www.ietf.org/rfc/rfc2045.txt
|
||||||
|
* This class is used by XML Schema binary format validation |
||||||
|
* |
||||||
|
* This implementation does not encode/decode streaming |
||||||
|
* data. You need the data that you will encode/decode |
||||||
|
* already on a byte arrray. |
||||||
|
* |
||||||
|
* @xerces.internal |
||||||
|
* |
||||||
|
* @author Jeffrey Rodriguez |
||||||
|
* @author Sandy Gao |
||||||
|
*/ |
||||||
|
public final class Base64 { |
||||||
|
|
||||||
|
static private final int BASELENGTH = 128; |
||||||
|
static private final int LOOKUPLENGTH = 64; |
||||||
|
static private final int TWENTYFOURBITGROUP = 24; |
||||||
|
static private final int EIGHTBIT = 8; |
||||||
|
static private final int SIXTEENBIT = 16; |
||||||
|
static private final int SIXBIT = 6; |
||||||
|
static private final int FOURBYTE = 4; |
||||||
|
static private final int SIGN = -128; |
||||||
|
static private final char PAD = '='; |
||||||
|
static private final boolean fDebug = false; |
||||||
|
static final private byte [] base64Alphabet = new byte[BASELENGTH]; |
||||||
|
static final private char [] lookUpBase64Alphabet = new char[LOOKUPLENGTH]; |
||||||
|
|
||||||
|
static { |
||||||
|
|
||||||
|
for (int i = 0; i < BASELENGTH; ++i) { |
||||||
|
base64Alphabet[i] = -1; |
||||||
|
} |
||||||
|
for (int i = 'Z'; i >= 'A'; i--) { |
||||||
|
base64Alphabet[i] = (byte) (i-'A'); |
||||||
|
} |
||||||
|
for (int i = 'z'; i>= 'a'; i--) { |
||||||
|
base64Alphabet[i] = (byte) ( i-'a' + 26); |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = '9'; i >= '0'; i--) { |
||||||
|
base64Alphabet[i] = (byte) (i-'0' + 52); |
||||||
|
} |
||||||
|
|
||||||
|
base64Alphabet['+'] = 62; |
||||||
|
base64Alphabet['/'] = 63; |
||||||
|
|
||||||
|
for (int i = 0; i<=25; i++) |
||||||
|
lookUpBase64Alphabet[i] = (char)('A'+i); |
||||||
|
|
||||||
|
for (int i = 26, j = 0; i<=51; i++, j++) |
||||||
|
lookUpBase64Alphabet[i] = (char)('a'+ j); |
||||||
|
|
||||||
|
for (int i = 52, j = 0; i<=61; i++, j++) |
||||||
|
lookUpBase64Alphabet[i] = (char)('0' + j); |
||||||
|
lookUpBase64Alphabet[62] = (char)'+'; |
||||||
|
lookUpBase64Alphabet[63] = (char)'/'; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
protected static boolean isWhiteSpace(char octect) { |
||||||
|
return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9); |
||||||
|
} |
||||||
|
|
||||||
|
protected static boolean isPad(char octect) { |
||||||
|
return (octect == PAD); |
||||||
|
} |
||||||
|
|
||||||
|
protected static boolean isData(char octect) { |
||||||
|
return (octect < BASELENGTH && base64Alphabet[octect] != -1); |
||||||
|
} |
||||||
|
|
||||||
|
protected static boolean isBase64(char octect) { |
||||||
|
return (isWhiteSpace(octect) || isPad(octect) || isData(octect)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Encodes hex octects into Base64 |
||||||
|
* |
||||||
|
* @param binaryData Array containing binaryData |
||||||
|
* @return Encoded Base64 array |
||||||
|
*/ |
||||||
|
public static String encode(byte[] binaryData) { |
||||||
|
|
||||||
|
if (binaryData == null) |
||||||
|
return null; |
||||||
|
|
||||||
|
int lengthDataBits = binaryData.length*EIGHTBIT; |
||||||
|
if (lengthDataBits == 0) { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
|
||||||
|
int fewerThan24bits = lengthDataBits%TWENTYFOURBITGROUP; |
||||||
|
int numberTriplets = lengthDataBits/TWENTYFOURBITGROUP; |
||||||
|
int numberQuartet = fewerThan24bits != 0 ? numberTriplets+1 : numberTriplets; |
||||||
|
char encodedData[] = null; |
||||||
|
|
||||||
|
encodedData = new char[numberQuartet*4]; |
||||||
|
|
||||||
|
byte k=0, l=0, b1=0,b2=0,b3=0; |
||||||
|
|
||||||
|
int encodedIndex = 0; |
||||||
|
int dataIndex = 0; |
||||||
|
if (fDebug) { |
||||||
|
System.out.println("number of triplets = " + numberTriplets ); |
||||||
|
} |
||||||
|
|
||||||
|
for (int i=0; i<numberTriplets; i++) { |
||||||
|
b1 = binaryData[dataIndex++]; |
||||||
|
b2 = binaryData[dataIndex++]; |
||||||
|
b3 = binaryData[dataIndex++]; |
||||||
|
|
||||||
|
if (fDebug) { |
||||||
|
System.out.println( "b1= " + b1 +", b2= " + b2 + ", b3= " + b3 ); |
||||||
|
} |
||||||
|
|
||||||
|
l = (byte)(b2 & 0x0f); |
||||||
|
k = (byte)(b1 & 0x03); |
||||||
|
|
||||||
|
byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); |
||||||
|
|
||||||
|
byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0); |
||||||
|
byte val3 = ((b3 & SIGN)==0)?(byte)(b3>>6):(byte)((b3)>>6^0xfc); |
||||||
|
|
||||||
|
if (fDebug) { |
||||||
|
System.out.println( "val2 = " + val2 ); |
||||||
|
System.out.println( "k4 = " + (k<<4)); |
||||||
|
System.out.println( "vak = " + (val2 | (k<<4))); |
||||||
|
} |
||||||
|
|
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ]; |
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ val2 | ( k<<4 )]; |
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ (l <<2 ) | val3 ]; |
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ b3 & 0x3f ]; |
||||||
|
} |
||||||
|
|
||||||
|
// form integral number of 6-bit groups
|
||||||
|
if (fewerThan24bits == EIGHTBIT) { |
||||||
|
b1 = binaryData[dataIndex]; |
||||||
|
k = (byte) ( b1 &0x03 ); |
||||||
|
if (fDebug) { |
||||||
|
System.out.println("b1=" + b1); |
||||||
|
System.out.println("b1<<2 = " + (b1>>2) ); |
||||||
|
} |
||||||
|
byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); |
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ]; |
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ k<<4 ]; |
||||||
|
encodedData[encodedIndex++] = PAD; |
||||||
|
encodedData[encodedIndex++] = PAD; |
||||||
|
} else if (fewerThan24bits == SIXTEENBIT) { |
||||||
|
b1 = binaryData[dataIndex]; |
||||||
|
b2 = binaryData[dataIndex +1 ]; |
||||||
|
l = ( byte ) ( b2 &0x0f ); |
||||||
|
k = ( byte ) ( b1 &0x03 ); |
||||||
|
|
||||||
|
byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); |
||||||
|
byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0); |
||||||
|
|
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ]; |
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ val2 | ( k<<4 )]; |
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ l<<2 ]; |
||||||
|
encodedData[encodedIndex++] = PAD; |
||||||
|
} |
||||||
|
|
||||||
|
return new String(encodedData); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Decodes Base64 data into octects |
||||||
|
* |
||||||
|
* @param encoded string containing Base64 data |
||||||
|
* @return Array containind decoded data. |
||||||
|
*/ |
||||||
|
public static byte[] decode(String encoded) { |
||||||
|
|
||||||
|
if (encoded == null) |
||||||
|
return null; |
||||||
|
|
||||||
|
char[] base64Data = encoded.toCharArray(); |
||||||
|
// remove white spaces
|
||||||
|
int len = removeWhiteSpace(base64Data); |
||||||
|
|
||||||
|
if (len%FOURBYTE != 0) { |
||||||
|
return null;//should be divisible by four
|
||||||
|
} |
||||||
|
|
||||||
|
int numberQuadruple = (len/FOURBYTE ); |
||||||
|
|
||||||
|
if (numberQuadruple == 0) |
||||||
|
return new byte[0]; |
||||||
|
|
||||||
|
byte decodedData[] = null; |
||||||
|
byte b1=0,b2=0,b3=0,b4=0; |
||||||
|
char d1=0,d2=0,d3=0,d4=0; |
||||||
|
|
||||||
|
int i = 0; |
||||||
|
int encodedIndex = 0; |
||||||
|
int dataIndex = 0; |
||||||
|
decodedData = new byte[ (numberQuadruple)*3]; |
||||||
|
|
||||||
|
for (; i<numberQuadruple-1; i++) { |
||||||
|
|
||||||
|
if (!isData( (d1 = base64Data[dataIndex++]) )|| |
||||||
|
!isData( (d2 = base64Data[dataIndex++]) )|| |
||||||
|
!isData( (d3 = base64Data[dataIndex++]) )|| |
||||||
|
!isData( (d4 = base64Data[dataIndex++]) )) |
||||||
|
return null;//if found "no data" just return null
|
||||||
|
|
||||||
|
b1 = base64Alphabet[d1]; |
||||||
|
b2 = base64Alphabet[d2]; |
||||||
|
b3 = base64Alphabet[d3]; |
||||||
|
b4 = base64Alphabet[d4]; |
||||||
|
|
||||||
|
decodedData[encodedIndex++] = (byte)( b1 <<2 | b2>>4 ) ; |
||||||
|
decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ); |
||||||
|
decodedData[encodedIndex++] = (byte)( b3<<6 | b4 ); |
||||||
|
} |
||||||
|
|
||||||
|
if (!isData( (d1 = base64Data[dataIndex++]) ) || |
||||||
|
!isData( (d2 = base64Data[dataIndex++]) )) { |
||||||
|
return null;//if found "no data" just return null
|
||||||
|
} |
||||||
|
|
||||||
|
b1 = base64Alphabet[d1]; |
||||||
|
b2 = base64Alphabet[d2]; |
||||||
|
|
||||||
|
d3 = base64Data[dataIndex++]; |
||||||
|
d4 = base64Data[dataIndex++]; |
||||||
|
if (!isData( (d3 ) ) || |
||||||
|
!isData( (d4 ) )) {//Check if they are PAD characters
|
||||||
|
if (isPad( d3 ) && isPad( d4)) { //Two PAD e.g. 3c[Pad][Pad]
|
||||||
|
if ((b2 & 0xf) != 0)//last 4 bits should be zero
|
||||||
|
return null; |
||||||
|
byte[] tmp = new byte[ i*3 + 1 ]; |
||||||
|
System.arraycopy( decodedData, 0, tmp, 0, i*3 ); |
||||||
|
tmp[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ; |
||||||
|
return tmp; |
||||||
|
} else if (!isPad( d3) && isPad(d4)) { //One PAD e.g. 3cQ[Pad]
|
||||||
|
b3 = base64Alphabet[ d3 ]; |
||||||
|
if ((b3 & 0x3 ) != 0)//last 2 bits should be zero
|
||||||
|
return null; |
||||||
|
byte[] tmp = new byte[ i*3 + 2 ]; |
||||||
|
System.arraycopy( decodedData, 0, tmp, 0, i*3 ); |
||||||
|
tmp[encodedIndex++] = (byte)( b1 <<2 | b2>>4 ); |
||||||
|
tmp[encodedIndex] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ); |
||||||
|
return tmp; |
||||||
|
} else { |
||||||
|
return null;//an error like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
|
||||||
|
} |
||||||
|
} else { //No PAD e.g 3cQl
|
||||||
|
b3 = base64Alphabet[ d3 ]; |
||||||
|
b4 = base64Alphabet[ d4 ]; |
||||||
|
decodedData[encodedIndex++] = (byte)( b1 <<2 | b2>>4 ) ; |
||||||
|
decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ); |
||||||
|
decodedData[encodedIndex++] = (byte)( b3<<6 | b4 ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return decodedData; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* remove WhiteSpace from MIME containing encoded Base64 data. |
||||||
|
* |
||||||
|
* @param data the byte array of base64 data (with WS) |
||||||
|
* @return the new length |
||||||
|
*/ |
||||||
|
protected static int removeWhiteSpace(char[] data) { |
||||||
|
if (data == null) |
||||||
|
return 0; |
||||||
|
|
||||||
|
// count characters that's not whitespace
|
||||||
|
int newSize = 0; |
||||||
|
int len = data.length; |
||||||
|
for (int i = 0; i < len; i++) { |
||||||
|
if (!isWhiteSpace(data[i])) |
||||||
|
data[newSize++] = data[i]; |
||||||
|
} |
||||||
|
return newSize; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,408 @@ |
|||||||
|
package com.fr.plugin.domainlogin.util; |
||||||
|
|
||||||
|
import java.security.Key; |
||||||
|
import java.security.SecureRandom; |
||||||
|
import java.security.spec.AlgorithmParameterSpec; |
||||||
|
import javax.crypto.Cipher; |
||||||
|
import javax.crypto.SecretKeyFactory; |
||||||
|
import javax.crypto.spec.DESKeySpec; |
||||||
|
import javax.crypto.spec.IvParameterSpec; |
||||||
|
public class CBCDesUtil { |
||||||
|
public static final String ALGORITHM_DES = "DES/CBC/PKCS5Padding"; |
||||||
|
|
||||||
|
/** |
||||||
|
* DES算法,加密 |
||||||
|
* |
||||||
|
* @param data 待加密字符串 |
||||||
|
* @param key 加密私钥,长度不能够小于8位 |
||||||
|
* @return 加密后的字节数组,一般结合Base64编码使用 |
||||||
|
* @throws Exception 异常 |
||||||
|
*/ |
||||||
|
public static String encode(String key, String data) throws Exception { |
||||||
|
return encode(key, data.getBytes()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* DES算法,加密 |
||||||
|
* |
||||||
|
* @param data 待加密字符串 |
||||||
|
* @param key 加密私钥,长度不能够小于8位 |
||||||
|
* @return 加密后的字节数组,一般结合Base64编码使用 |
||||||
|
* @throws Exception 异常 |
||||||
|
*/ |
||||||
|
public static String encode(String key, byte[] data) throws Exception { |
||||||
|
try { |
||||||
|
DESKeySpec dks = new DESKeySpec(key.getBytes()); |
||||||
|
|
||||||
|
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); |
||||||
|
//key的长度不能够小于8位字节
|
||||||
|
Key secretKey = keyFactory.generateSecret(dks); |
||||||
|
Cipher cipher = Cipher.getInstance(ALGORITHM_DES); |
||||||
|
IvParameterSpec iv = new IvParameterSpec(key.getBytes()); |
||||||
|
AlgorithmParameterSpec paramSpec = iv; |
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec); |
||||||
|
|
||||||
|
byte[] bytes = cipher.doFinal(data); |
||||||
|
return Base64.encode(bytes); |
||||||
|
} catch (Exception e) { |
||||||
|
throw new Exception(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* DES算法,解密 |
||||||
|
* |
||||||
|
* @param data 待解密字符串 |
||||||
|
* @param key 解密私钥,长度不能够小于8位 |
||||||
|
* @return 解密后的字节数组 |
||||||
|
* @throws Exception 异常 |
||||||
|
*/ |
||||||
|
public static byte[] decode(String key, byte[] data) throws Exception { |
||||||
|
try { |
||||||
|
SecureRandom sr = new SecureRandom(); |
||||||
|
DESKeySpec dks = new DESKeySpec(key.getBytes()); |
||||||
|
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); |
||||||
|
//key的长度不能够小于8位字节
|
||||||
|
Key secretKey = keyFactory.generateSecret(dks); |
||||||
|
Cipher cipher = Cipher.getInstance(ALGORITHM_DES); |
||||||
|
IvParameterSpec iv = new IvParameterSpec(key.getBytes()); |
||||||
|
AlgorithmParameterSpec paramSpec = iv; |
||||||
|
cipher.init(Cipher.DECRYPT_MODE, secretKey, paramSpec); |
||||||
|
return cipher.doFinal(data); |
||||||
|
} catch (Exception e) { |
||||||
|
throw new Exception(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取编码后的值 |
||||||
|
* |
||||||
|
* @param key |
||||||
|
* @param data |
||||||
|
* @return |
||||||
|
* @throws Exception |
||||||
|
* @throws Exception |
||||||
|
*/ |
||||||
|
public static String decodeValue(String key, String data) throws Exception { |
||||||
|
byte[] datas; |
||||||
|
String value = null; |
||||||
|
|
||||||
|
datas = decode(key, Base64.decode(data)); |
||||||
|
|
||||||
|
value = new String(datas); |
||||||
|
if (value.equals("")) { |
||||||
|
throw new Exception(); |
||||||
|
} |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* |
||||||
|
* Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. |
||||||
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. |
||||||
|
*/ |
||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||||
|
* (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* This class provides encode/decode for RFC 2045 Base64 as |
||||||
|
* defined by RFC 2045, N. Freed and N. Borenstein. |
||||||
|
* RFC 2045: Multipurpose Internet Mail Extensions (MIME) |
||||||
|
* Part One: Format of Internet Message Bodies. Reference |
||||||
|
* 1996 Available at: http://www.ietf.org/rfc/rfc2045.txt
|
||||||
|
* This class is used by XML Schema binary format validation |
||||||
|
* |
||||||
|
* This implementation does not encode/decode streaming |
||||||
|
* data. You need the data that you will encode/decode |
||||||
|
* already on a byte arrray. |
||||||
|
* |
||||||
|
* @xerces.internal |
||||||
|
* |
||||||
|
* @author Jeffrey Rodriguez |
||||||
|
* @author Sandy Gao |
||||||
|
*/ |
||||||
|
public static final class Base64 { |
||||||
|
|
||||||
|
static private final int BASELENGTH = 128; |
||||||
|
static private final int LOOKUPLENGTH = 64; |
||||||
|
static private final int TWENTYFOURBITGROUP = 24; |
||||||
|
static private final int EIGHTBIT = 8; |
||||||
|
static private final int SIXTEENBIT = 16; |
||||||
|
static private final int SIXBIT = 6; |
||||||
|
static private final int FOURBYTE = 4; |
||||||
|
static private final int SIGN = -128; |
||||||
|
static private final char PAD = '='; |
||||||
|
static private final boolean fDebug = false; |
||||||
|
static final private byte [] base64Alphabet = new byte[BASELENGTH]; |
||||||
|
static final private char [] lookUpBase64Alphabet = new char[LOOKUPLENGTH]; |
||||||
|
|
||||||
|
static { |
||||||
|
|
||||||
|
for (int i = 0; i < BASELENGTH; ++i) { |
||||||
|
base64Alphabet[i] = -1; |
||||||
|
} |
||||||
|
for (int i = 'Z'; i >= 'A'; i--) { |
||||||
|
base64Alphabet[i] = (byte) (i-'A'); |
||||||
|
} |
||||||
|
for (int i = 'z'; i>= 'a'; i--) { |
||||||
|
base64Alphabet[i] = (byte) ( i-'a' + 26); |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = '9'; i >= '0'; i--) { |
||||||
|
base64Alphabet[i] = (byte) (i-'0' + 52); |
||||||
|
} |
||||||
|
|
||||||
|
base64Alphabet['+'] = 62; |
||||||
|
base64Alphabet['/'] = 63; |
||||||
|
|
||||||
|
for (int i = 0; i<=25; i++) |
||||||
|
lookUpBase64Alphabet[i] = (char)('A'+i); |
||||||
|
|
||||||
|
for (int i = 26, j = 0; i<=51; i++, j++) |
||||||
|
lookUpBase64Alphabet[i] = (char)('a'+ j); |
||||||
|
|
||||||
|
for (int i = 52, j = 0; i<=61; i++, j++) |
||||||
|
lookUpBase64Alphabet[i] = (char)('0' + j); |
||||||
|
lookUpBase64Alphabet[62] = (char)'+'; |
||||||
|
lookUpBase64Alphabet[63] = (char)'/'; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
protected static boolean isWhiteSpace(char octect) { |
||||||
|
return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9); |
||||||
|
} |
||||||
|
|
||||||
|
protected static boolean isPad(char octect) { |
||||||
|
return (octect == PAD); |
||||||
|
} |
||||||
|
|
||||||
|
protected static boolean isData(char octect) { |
||||||
|
return (octect < BASELENGTH && base64Alphabet[octect] != -1); |
||||||
|
} |
||||||
|
|
||||||
|
protected static boolean isBase64(char octect) { |
||||||
|
return (isWhiteSpace(octect) || isPad(octect) || isData(octect)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Encodes hex octects into Base64 |
||||||
|
* |
||||||
|
* @param binaryData Array containing binaryData |
||||||
|
* @return Encoded Base64 array |
||||||
|
*/ |
||||||
|
public static String encode(byte[] binaryData) { |
||||||
|
|
||||||
|
if (binaryData == null) |
||||||
|
return null; |
||||||
|
|
||||||
|
int lengthDataBits = binaryData.length*EIGHTBIT; |
||||||
|
if (lengthDataBits == 0) { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
|
||||||
|
int fewerThan24bits = lengthDataBits%TWENTYFOURBITGROUP; |
||||||
|
int numberTriplets = lengthDataBits/TWENTYFOURBITGROUP; |
||||||
|
int numberQuartet = fewerThan24bits != 0 ? numberTriplets+1 : numberTriplets; |
||||||
|
char encodedData[] = null; |
||||||
|
|
||||||
|
encodedData = new char[numberQuartet*4]; |
||||||
|
|
||||||
|
byte k=0, l=0, b1=0,b2=0,b3=0; |
||||||
|
|
||||||
|
int encodedIndex = 0; |
||||||
|
int dataIndex = 0; |
||||||
|
if (fDebug) { |
||||||
|
System.out.println("number of triplets = " + numberTriplets ); |
||||||
|
} |
||||||
|
|
||||||
|
for (int i=0; i<numberTriplets; i++) { |
||||||
|
b1 = binaryData[dataIndex++]; |
||||||
|
b2 = binaryData[dataIndex++]; |
||||||
|
b3 = binaryData[dataIndex++]; |
||||||
|
|
||||||
|
if (fDebug) { |
||||||
|
System.out.println( "b1= " + b1 +", b2= " + b2 + ", b3= " + b3 ); |
||||||
|
} |
||||||
|
|
||||||
|
l = (byte)(b2 & 0x0f); |
||||||
|
k = (byte)(b1 & 0x03); |
||||||
|
|
||||||
|
byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); |
||||||
|
|
||||||
|
byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0); |
||||||
|
byte val3 = ((b3 & SIGN)==0)?(byte)(b3>>6):(byte)((b3)>>6^0xfc); |
||||||
|
|
||||||
|
if (fDebug) { |
||||||
|
System.out.println( "val2 = " + val2 ); |
||||||
|
System.out.println( "k4 = " + (k<<4)); |
||||||
|
System.out.println( "vak = " + (val2 | (k<<4))); |
||||||
|
} |
||||||
|
|
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ]; |
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ val2 | ( k<<4 )]; |
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ (l <<2 ) | val3 ]; |
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ b3 & 0x3f ]; |
||||||
|
} |
||||||
|
|
||||||
|
// form integral number of 6-bit groups
|
||||||
|
if (fewerThan24bits == EIGHTBIT) { |
||||||
|
b1 = binaryData[dataIndex]; |
||||||
|
k = (byte) ( b1 &0x03 ); |
||||||
|
if (fDebug) { |
||||||
|
System.out.println("b1=" + b1); |
||||||
|
System.out.println("b1<<2 = " + (b1>>2) ); |
||||||
|
} |
||||||
|
byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); |
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ]; |
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ k<<4 ]; |
||||||
|
encodedData[encodedIndex++] = PAD; |
||||||
|
encodedData[encodedIndex++] = PAD; |
||||||
|
} else if (fewerThan24bits == SIXTEENBIT) { |
||||||
|
b1 = binaryData[dataIndex]; |
||||||
|
b2 = binaryData[dataIndex +1 ]; |
||||||
|
l = ( byte ) ( b2 &0x0f ); |
||||||
|
k = ( byte ) ( b1 &0x03 ); |
||||||
|
|
||||||
|
byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); |
||||||
|
byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0); |
||||||
|
|
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ]; |
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ val2 | ( k<<4 )]; |
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[ l<<2 ]; |
||||||
|
encodedData[encodedIndex++] = PAD; |
||||||
|
} |
||||||
|
|
||||||
|
return new String(encodedData); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Decodes Base64 data into octects |
||||||
|
* |
||||||
|
* @param encoded string containing Base64 data |
||||||
|
* @return Array containind decoded data. |
||||||
|
*/ |
||||||
|
public static byte[] decode(String encoded) { |
||||||
|
|
||||||
|
if (encoded == null) |
||||||
|
return null; |
||||||
|
|
||||||
|
char[] base64Data = encoded.toCharArray(); |
||||||
|
// remove white spaces
|
||||||
|
int len = removeWhiteSpace(base64Data); |
||||||
|
|
||||||
|
if (len%FOURBYTE != 0) { |
||||||
|
return null;//should be divisible by four
|
||||||
|
} |
||||||
|
|
||||||
|
int numberQuadruple = (len/FOURBYTE ); |
||||||
|
|
||||||
|
if (numberQuadruple == 0) |
||||||
|
return new byte[0]; |
||||||
|
|
||||||
|
byte decodedData[] = null; |
||||||
|
byte b1=0,b2=0,b3=0,b4=0; |
||||||
|
char d1=0,d2=0,d3=0,d4=0; |
||||||
|
|
||||||
|
int i = 0; |
||||||
|
int encodedIndex = 0; |
||||||
|
int dataIndex = 0; |
||||||
|
decodedData = new byte[ (numberQuadruple)*3]; |
||||||
|
|
||||||
|
for (; i<numberQuadruple-1; i++) { |
||||||
|
|
||||||
|
if (!isData( (d1 = base64Data[dataIndex++]) )|| |
||||||
|
!isData( (d2 = base64Data[dataIndex++]) )|| |
||||||
|
!isData( (d3 = base64Data[dataIndex++]) )|| |
||||||
|
!isData( (d4 = base64Data[dataIndex++]) )) |
||||||
|
return null;//if found "no data" just return null
|
||||||
|
|
||||||
|
b1 = base64Alphabet[d1]; |
||||||
|
b2 = base64Alphabet[d2]; |
||||||
|
b3 = base64Alphabet[d3]; |
||||||
|
b4 = base64Alphabet[d4]; |
||||||
|
|
||||||
|
decodedData[encodedIndex++] = (byte)( b1 <<2 | b2>>4 ) ; |
||||||
|
decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ); |
||||||
|
decodedData[encodedIndex++] = (byte)( b3<<6 | b4 ); |
||||||
|
} |
||||||
|
|
||||||
|
if (!isData( (d1 = base64Data[dataIndex++]) ) || |
||||||
|
!isData( (d2 = base64Data[dataIndex++]) )) { |
||||||
|
return null;//if found "no data" just return null
|
||||||
|
} |
||||||
|
|
||||||
|
b1 = base64Alphabet[d1]; |
||||||
|
b2 = base64Alphabet[d2]; |
||||||
|
|
||||||
|
d3 = base64Data[dataIndex++]; |
||||||
|
d4 = base64Data[dataIndex++]; |
||||||
|
if (!isData( (d3 ) ) || |
||||||
|
!isData( (d4 ) )) {//Check if they are PAD characters
|
||||||
|
if (isPad( d3 ) && isPad( d4)) { //Two PAD e.g. 3c[Pad][Pad]
|
||||||
|
if ((b2 & 0xf) != 0)//last 4 bits should be zero
|
||||||
|
return null; |
||||||
|
byte[] tmp = new byte[ i*3 + 1 ]; |
||||||
|
System.arraycopy( decodedData, 0, tmp, 0, i*3 ); |
||||||
|
tmp[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ; |
||||||
|
return tmp; |
||||||
|
} else if (!isPad( d3) && isPad(d4)) { //One PAD e.g. 3cQ[Pad]
|
||||||
|
b3 = base64Alphabet[ d3 ]; |
||||||
|
if ((b3 & 0x3 ) != 0)//last 2 bits should be zero
|
||||||
|
return null; |
||||||
|
byte[] tmp = new byte[ i*3 + 2 ]; |
||||||
|
System.arraycopy( decodedData, 0, tmp, 0, i*3 ); |
||||||
|
tmp[encodedIndex++] = (byte)( b1 <<2 | b2>>4 ); |
||||||
|
tmp[encodedIndex] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ); |
||||||
|
return tmp; |
||||||
|
} else { |
||||||
|
return null;//an error like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
|
||||||
|
} |
||||||
|
} else { //No PAD e.g 3cQl
|
||||||
|
b3 = base64Alphabet[ d3 ]; |
||||||
|
b4 = base64Alphabet[ d4 ]; |
||||||
|
decodedData[encodedIndex++] = (byte)( b1 <<2 | b2>>4 ) ; |
||||||
|
decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ); |
||||||
|
decodedData[encodedIndex++] = (byte)( b3<<6 | b4 ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return decodedData; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* remove WhiteSpace from MIME containing encoded Base64 data. |
||||||
|
* |
||||||
|
* @param data the byte array of base64 data (with WS) |
||||||
|
* @return the new length |
||||||
|
*/ |
||||||
|
protected static int removeWhiteSpace(char[] data) { |
||||||
|
if (data == null) |
||||||
|
return 0; |
||||||
|
|
||||||
|
// count characters that's not whitespace
|
||||||
|
int newSize = 0; |
||||||
|
int len = data.length; |
||||||
|
for (int i = 0; i < len; i++) { |
||||||
|
if (!isWhiteSpace(data[i])) |
||||||
|
data[newSize++] = data[i]; |
||||||
|
} |
||||||
|
return newSize; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,99 @@ |
|||||||
|
package com.fr.plugin.domainlogin.util; |
||||||
|
|
||||||
|
import java.security.Key; |
||||||
|
import java.security.SecureRandom; |
||||||
|
import java.security.spec.AlgorithmParameterSpec; |
||||||
|
import javax.crypto.Cipher; |
||||||
|
import javax.crypto.SecretKeyFactory; |
||||||
|
import javax.crypto.spec.DESKeySpec; |
||||||
|
import javax.crypto.spec.IvParameterSpec; |
||||||
|
|
||||||
|
public class Des { |
||||||
|
public static final String ALGORITHM_DES = "DES/CBC/PKCS5Padding"; |
||||||
|
|
||||||
|
/** |
||||||
|
* DES算法,加密 |
||||||
|
* |
||||||
|
* @param data 待加密字符串 |
||||||
|
* @param key 加密私钥,长度不能够小于8位 |
||||||
|
* @return 加密后的字节数组,一般结合Base64编码使用 |
||||||
|
* @throws Exception 异常 |
||||||
|
*/ |
||||||
|
public static String encode(String key, String data) throws Exception { |
||||||
|
return encode(key, data.getBytes()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* DES算法,加密 |
||||||
|
* |
||||||
|
* @param data 待加密字符串 |
||||||
|
* @param key 加密私钥,长度不能够小于8位 |
||||||
|
* @return 加密后的字节数组,一般结合Base64编码使用 |
||||||
|
* @throws Exception 异常 |
||||||
|
*/ |
||||||
|
public static String encode(String key, byte[] data) throws Exception { |
||||||
|
try { |
||||||
|
DESKeySpec dks = new DESKeySpec(key.getBytes()); |
||||||
|
|
||||||
|
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); |
||||||
|
//key的长度不能够小于8位字节
|
||||||
|
Key secretKey = keyFactory.generateSecret(dks); |
||||||
|
Cipher cipher = Cipher.getInstance(ALGORITHM_DES); |
||||||
|
IvParameterSpec iv = new IvParameterSpec(key.getBytes()); |
||||||
|
AlgorithmParameterSpec paramSpec = iv; |
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec); |
||||||
|
|
||||||
|
byte[] bytes = cipher.doFinal(data); |
||||||
|
return Base64.encode(bytes); |
||||||
|
} catch (Exception e) { |
||||||
|
throw new Exception(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* DES算法,解密 |
||||||
|
* |
||||||
|
* @param data 待解密字符串 |
||||||
|
* @param key 解密私钥,长度不能够小于8位 |
||||||
|
* @return 解密后的字节数组 |
||||||
|
* @throws Exception 异常 |
||||||
|
*/ |
||||||
|
public static byte[] decode(String key, byte[] data) throws Exception { |
||||||
|
try { |
||||||
|
SecureRandom sr = new SecureRandom(); |
||||||
|
DESKeySpec dks = new DESKeySpec(key.getBytes()); |
||||||
|
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); |
||||||
|
//key的长度不能够小于8位字节
|
||||||
|
Key secretKey = keyFactory.generateSecret(dks); |
||||||
|
Cipher cipher = Cipher.getInstance(ALGORITHM_DES); |
||||||
|
IvParameterSpec iv = new IvParameterSpec(key.getBytes()); |
||||||
|
AlgorithmParameterSpec paramSpec = iv; |
||||||
|
cipher.init(Cipher.DECRYPT_MODE, secretKey, paramSpec); |
||||||
|
return cipher.doFinal(data); |
||||||
|
} catch (Exception e) { |
||||||
|
throw new Exception(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取编码后的值 |
||||||
|
* |
||||||
|
* @param key |
||||||
|
* @param data |
||||||
|
* @return |
||||||
|
* @throws Exception |
||||||
|
* @throws Exception |
||||||
|
*/ |
||||||
|
public static String decodeValue(String key, String data) throws Exception { |
||||||
|
byte[] datas; |
||||||
|
String value = null; |
||||||
|
|
||||||
|
datas = decode(key, Base64.decode(data)); |
||||||
|
|
||||||
|
value = new String(datas); |
||||||
|
if (value.equals("")) { |
||||||
|
throw new Exception(); |
||||||
|
} |
||||||
|
return value; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
package com.fr.plugin.domainlogin.webresource; |
||||||
|
|
||||||
|
import com.fr.web.struct.Component; |
||||||
|
import com.fr.web.struct.browser.RequestClient; |
||||||
|
import com.fr.web.struct.category.ScriptPath; |
||||||
|
|
||||||
|
public class DomainLoginComponent extends Component { |
||||||
|
|
||||||
|
public static DomainLoginComponent KEY = new DomainLoginComponent(); |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public ScriptPath script(RequestClient req) { |
||||||
|
return ScriptPath.build("/com/fr/plugin/domainlogin/jscss/domain_login.js"); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
package com.fr.plugin.domainlogin.webresource; |
||||||
|
|
||||||
|
import com.fr.decision.fun.impl.AbstractWebResourceProvider; |
||||||
|
import com.fr.decision.web.LoginComponent; |
||||||
|
import com.fr.decision.web.MainComponent; |
||||||
|
import com.fr.web.struct.Atom; |
||||||
|
|
||||||
|
public class DomainLoginWebResourceProvider extends AbstractWebResourceProvider { |
||||||
|
|
||||||
|
@Override |
||||||
|
public Atom attach() { |
||||||
|
return LoginComponent.KEY; |
||||||
|
} |
||||||
|
|
||||||
|
public Atom client() { |
||||||
|
|
||||||
|
return DomainLoginComponent.KEY; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,325 @@ |
|||||||
|
; (function () { |
||||||
|
// $("<div/>").addClass("plugin-jscssinput-demo").html("Hello World!").appendTo("body");
|
||||||
|
console.log("本地域登录js启动...") |
||||||
|
|
||||||
|
|
||||||
|
//定义获取本地域的用户名信息
|
||||||
|
function getLocalDomainUserInfo(callback) { |
||||||
|
$.ajax({ |
||||||
|
type: "POST", |
||||||
|
//url: "${base_url}common/login.do",
|
||||||
|
url: "http://10.5.0.138:5006/api/Login", |
||||||
|
dataType: "jsonp", |
||||||
|
// data: {username:username, userpass:userpass, t:Math.random()},
|
||||||
|
success: function (data) { |
||||||
|
var userInfo = data; |
||||||
|
console.log("userInfo:" + userInfo) |
||||||
|
callback(userInfo) |
||||||
|
//这里的data是DES加密的
|
||||||
|
}, |
||||||
|
error: function () { |
||||||
|
$(".alert-error").text('登录失败'); |
||||||
|
alert('系统繁忙'); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
function domainLogin() { |
||||||
|
console.log("域登录....") |
||||||
|
//本地域用户
|
||||||
|
getLocalDomainUserInfo((userInfo) => { |
||||||
|
//时间戳
|
||||||
|
var timestamp = new Date().getTime(); |
||||||
|
|
||||||
|
Dec.reqPost("/localDomain/login", { |
||||||
|
"userInfo": userInfo, |
||||||
|
"timestamp": timestamp, |
||||||
|
}, function (res) { |
||||||
|
if (res["errorMsg"] != undefined) { |
||||||
|
console.log("/localDomain/login调用失败结果:" + res["errorMsg"]); |
||||||
|
BI.Msg.alert("提示", res["errorMsg"], function (v) { |
||||||
|
|
||||||
|
}); |
||||||
|
} |
||||||
|
else { |
||||||
|
console.log("/localDomain/login调用结果:" + res.data); |
||||||
|
BI.Cache.addCookie(DecCst.Cookie.TOKEN, res.data, Dec.loginConfig.cookiePath, 0); |
||||||
|
window.location.href = "/webroot/decision"; |
||||||
|
} |
||||||
|
|
||||||
|
}) |
||||||
|
}); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
setTimeout(() => { |
||||||
|
var domainloginflag = BI.Cache.getCookie("domainloginflag"); |
||||||
|
console.log("domainloginflag:" + domainloginflag); |
||||||
|
if (domainloginflag != "1") { |
||||||
|
|
||||||
|
Dec.Msg.confirm({ |
||||||
|
"title": "系统提示", "message": "是否尝试域认证一键登录?", "callback": function (isoK) { |
||||||
|
if (isoK) { |
||||||
|
domainLogin(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
}, 1000); |
||||||
|
|
||||||
|
|
||||||
|
function loginCompDefine() { |
||||||
|
console.log("进到我的登录组件了.....") |
||||||
|
var e = BI.inherit(BI.Widget, { |
||||||
|
props: { |
||||||
|
baseCls: "dec-login-login" |
||||||
|
}, |
||||||
|
_store: function () { |
||||||
|
return BI.Models.getModel("dec.model.login.login") |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
supportForgetPwd: function (e) { |
||||||
|
this.forgetPasswordRow.setVisible(e) |
||||||
|
}, |
||||||
|
needSlider: function (e) { |
||||||
|
this.sliderMasker.setVisible(e) |
||||||
|
} |
||||||
|
}, |
||||||
|
render: function () { |
||||||
|
var t = this; |
||||||
|
this.options; |
||||||
|
return { |
||||||
|
type: "bi.absolute", |
||||||
|
items: [ |
||||||
|
{ |
||||||
|
el: { |
||||||
|
type: "bi.vertical", |
||||||
|
items: [ |
||||||
|
{ |
||||||
|
type: "dec.login.login.item", |
||||||
|
$testId: "dec-login-username", |
||||||
|
iconCls: "login-username-font", |
||||||
|
tgap: 50, |
||||||
|
watermark: BI.i18nText("Dec-User_Name"), |
||||||
|
ref: function (e) { |
||||||
|
t.usernameRow = e |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "dec.login.login.item", |
||||||
|
$testId: "dec-login-password", |
||||||
|
iconCls: "login-password-font", |
||||||
|
watermark: BI.i18nText("Dec-Password"), |
||||||
|
inputType: "password", |
||||||
|
ref: function (e) { |
||||||
|
t.passwordRow = e |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
{ |
||||||
|
type: "bi.default", |
||||||
|
bgap: 30, |
||||||
|
cls: "clearfix", |
||||||
|
items: [ |
||||||
|
{ |
||||||
|
el: { |
||||||
|
type: "bi.multi_select_item", |
||||||
|
css: { |
||||||
|
"float": "left" |
||||||
|
}, |
||||||
|
$testId: "dec-login-remember", |
||||||
|
textLgap: 5, |
||||||
|
iconWrapperWidth: 16, |
||||||
|
height: 16, |
||||||
|
text: BI.i18nText("Dec-Login_Remember"), |
||||||
|
logic: { |
||||||
|
dynamic: !0 |
||||||
|
}, |
||||||
|
ref: function (e) { |
||||||
|
t.rememberRow = e |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
] |
||||||
|
}, |
||||||
|
|
||||||
|
{ |
||||||
|
type: "bi.horizontal_auto", |
||||||
|
bgap:20, |
||||||
|
items: [ |
||||||
|
{ |
||||||
|
type: "bi.button", |
||||||
|
cls: "login-button", |
||||||
|
text: BI.i18nText("Dec-Basic_Login"), |
||||||
|
width: 190, |
||||||
|
height: 40, |
||||||
|
handler: function () { |
||||||
|
t._start() |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "bi.horizontal_auto", |
||||||
|
|
||||||
|
items: [ |
||||||
|
{ |
||||||
|
type: "bi.button", |
||||||
|
cls: "login-button", |
||||||
|
text: '域认证一键登录', |
||||||
|
width: 190, |
||||||
|
height: 40, |
||||||
|
handler: function () { |
||||||
|
//t._start()
|
||||||
|
domainLogin(); |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
el: { |
||||||
|
type: "bi.vertical", |
||||||
|
$testId: "dec-login-logged-chang-text", |
||||||
|
cls: "login-error", |
||||||
|
invisible: !0, |
||||||
|
scrolly: !1, |
||||||
|
items: [ |
||||||
|
{ |
||||||
|
type: "bi.text", |
||||||
|
tagName: "span", |
||||||
|
whiteSpace: "normal", |
||||||
|
text: BI.i18nText("Dec-Login_Other_Logged_Tip") |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "bi.text", |
||||||
|
$testId: "dec-login-logged-chang-password", |
||||||
|
tagName: "span", |
||||||
|
cls: "password-btn", |
||||||
|
text: BI.i18nText("Dec-Login_Change_Password"), |
||||||
|
handler: function () { |
||||||
|
t.model.isNeedVerify ? t.store.setSelectedTab(DecCst.Login.Tabs.VERIFY_BING) : t.store.setSelectedTab(DecCst.Login.Tabs.PASSWORD_OLD) |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
ref: function (e) { |
||||||
|
t.loginErrorRow = e |
||||||
|
} |
||||||
|
}, |
||||||
|
tgap: 20 |
||||||
|
}, |
||||||
|
{ |
||||||
|
el: { |
||||||
|
type: "bi.text", |
||||||
|
$testId: "dec-login-logged-text", |
||||||
|
cls: "login-error", |
||||||
|
invisible: !0, |
||||||
|
whiteSpace: "normal", |
||||||
|
text: BI.i18nText("Dec-Login_Normal_Other_Logged_Tip"), |
||||||
|
ref: function (e) { |
||||||
|
t.loginNormalErrorRow = e |
||||||
|
} |
||||||
|
}, |
||||||
|
tgap: 20 |
||||||
|
}] |
||||||
|
}, |
||||||
|
top: 0, |
||||||
|
right: 40, |
||||||
|
bottom: 0, |
||||||
|
left: 40 |
||||||
|
}, |
||||||
|
{ |
||||||
|
el: { |
||||||
|
type: "bi.center_adapt", |
||||||
|
cls: "slider-masker", |
||||||
|
invisible: !0, |
||||||
|
items: [{ |
||||||
|
type: "dec.login.slider", |
||||||
|
listeners: [{ |
||||||
|
eventName: "EVENT_SUCCESS", |
||||||
|
action: function () { |
||||||
|
t._start() |
||||||
|
} |
||||||
|
}, { |
||||||
|
eventName: "EVENT_CLOSE", |
||||||
|
action: function () { |
||||||
|
t.store.resetSlider() |
||||||
|
} |
||||||
|
}], |
||||||
|
ref: function (e) { |
||||||
|
t.sliderBar = e |
||||||
|
} |
||||||
|
}], |
||||||
|
ref: function (e) { |
||||||
|
t.sliderMasker = e |
||||||
|
} |
||||||
|
}, |
||||||
|
top: 0, |
||||||
|
right: 40, |
||||||
|
bottom: 0, |
||||||
|
left: 40 |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted: function () { |
||||||
|
var t = this; |
||||||
|
this.store.initData(), |
||||||
|
this.element.keyup(function (e) { |
||||||
|
13 === e.keyCode && t._start() |
||||||
|
}) |
||||||
|
}, |
||||||
|
_createItems: function () { |
||||||
|
return BI.map(BI.Constants.getConstant("dec.constant.login.way.extend"), function (e, t) { |
||||||
|
return { |
||||||
|
type: t.cardType |
||||||
|
} |
||||||
|
}) |
||||||
|
}, |
||||||
|
_start: function () { |
||||||
|
var t = this |
||||||
|
, e = this.usernameRow.getValue() |
||||||
|
, i = this.passwordRow.getValue() |
||||||
|
, n = this.rememberRow.isSelected() ? -2 : -1; |
||||||
|
t.loginErrorRow.invisible(), |
||||||
|
t.loginNormalErrorRow.invisible(), |
||||||
|
"" !== e ? "" !== i ? (this.store.setLoginInfo({ |
||||||
|
username: e, |
||||||
|
validity: n, |
||||||
|
phone: "", |
||||||
|
captcha: "" |
||||||
|
}), |
||||||
|
this.store.login({ |
||||||
|
username: e, |
||||||
|
password: this.passwordRow.getCipher(), |
||||||
|
validity: n, |
||||||
|
sliderToken: this.model.sliderToken, |
||||||
|
origin: Dec.Utils.getUrlQuery("origin"), |
||||||
|
encrypted: !0 |
||||||
|
}, function (e) { |
||||||
|
t.store.resetSlider(), |
||||||
|
e.data && e.data.accessToken ? t.fireEvent("EVENT_LOGIN", e.data) : BI.bind(BI.Services.getService("dec.service.login.login").getHandler(e.errorCode), t)(e) |
||||||
|
})) : this.passwordRow.showError(BI.i18nText("Dec-Error_Password_Not_Null")) : this.usernameRow.showError(BI.i18nText("Dec-Error_Username_Not_Null")) |
||||||
|
} |
||||||
|
}); |
||||||
|
BI.shortcut("dec.login.login1", e) |
||||||
|
} |
||||||
|
|
||||||
|
loginCompDefine(); |
||||||
|
|
||||||
|
|
||||||
|
BI.config("dec.login.login", function (options) { |
||||||
|
options.type = "dec.login.login1"; // 将组件的type替换为自定义的组件
|
||||||
|
return options; |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
})(); |
Binary file not shown.
Loading…
Reference in new issue