Browse Source

提交开源任务材料

10.0
LAPTOP-SB56SG4Q\86185 4 years ago
parent
commit
e08cfa5133
  1. BIN
      JSD-7965-需求确认书V1-1.docx
  2. 5
      README.md
  3. BIN
      lib/EsbSDK-1.0.jar
  4. BIN
      lib/EsbSDK_Http-1.0.jar
  5. BIN
      lib/fastjson-1.2.73.jar
  6. BIN
      lib/fr-plugin-weixin-10.4.982.jar
  7. BIN
      lib/logback-classic-1.2.3.jar
  8. BIN
      lib/logback-core-1.2.3.jar
  9. BIN
      lib/slf4j-api-1.7.25.jar
  10. 66
      plugin.xml
  11. 43
      src/main/java/com/fr/plugin/loginAuth/dbAccessProvider/AuthUserController.java
  12. 305
      src/main/java/com/fr/plugin/loginAuth/dbAccessProvider/AuthUserDBController.java
  13. 79
      src/main/java/com/fr/plugin/loginAuth/dbAccessProvider/AuthUserDao.java
  14. 55
      src/main/java/com/fr/plugin/loginAuth/dbAccessProvider/AuthUserEntity.java
  15. 97
      src/main/java/com/fr/plugin/loginAuth/dbAccessProvider/AuthUserMacDAO.java
  16. 96
      src/main/java/com/fr/plugin/loginAuth/dbAccessProvider/AuthUserMacEntity.java
  17. 15
      src/main/java/com/fr/plugin/loginAuth/dbAccessProvider/ControllerBridge.java
  18. 390
      src/main/java/com/fr/plugin/loginAuth/filter/SSOFilter.java
  19. 12
      src/main/java/com/fr/plugin/loginAuth/handler/ExtendAttrHandlerProvider.java
  20. 99
      src/main/java/com/fr/plugin/loginAuth/handler/ToDecisionLogin.java
  21. 14
      src/main/java/com/fr/plugin/loginAuth/handler/URLAliasProvide.java
  22. 111
      src/main/java/com/fr/plugin/loginAuth/httpAuth/Login.java
  23. 11
      src/main/java/com/fr/plugin/loginAuth/httpAuth/Test.java
  24. 262
      src/main/java/com/fr/plugin/loginAuth/utils/CipherUtils.java
  25. 158
      src/main/java/com/fr/plugin/loginAuth/utils/FRUtils.java
  26. 300
      src/main/java/com/fr/plugin/loginAuth/utils/FWLoginFilter.java
  27. 237
      src/main/java/com/fr/plugin/loginAuth/utils/HttpUtils.java
  28. 96
      src/main/java/com/fr/plugin/loginAuth/utils/ResponseUtils.java
  29. 338
      src/main/java/com/fr/plugin/loginAuth/utils/SafeUtils.java
  30. 96
      src/main/java/com/fr/plugin/loginAuth/utils/Utils.java
  31. 35
      src/main/java/com/fr/plugin/loginAuth/webresource/WebResourceProvider.java
  32. 37
      src/main/resources/com/fr/plugin/loginAuth/html/getMac.html
  33. 4
      src/main/resources/com/fr/plugin/loginAuth/html/jquery-2.1.3.min.js
  34. 29
      src/main/resources/com/fr/plugin/loginAuth/js/login.html
  35. 333
      src/main/resources/com/fr/plugin/loginAuth/js/login.js
  36. 15
      src/main/resources/com/fr/plugin/loginAuth/login/redirect.html
  37. 18
      src/main/resources/com/fr/plugin/loginAuth/login/redirect1.html
  38. 66
      src/main/resources/com/fr/plugin/loginAuth/logout/logout2.js
  39. BIN
      使用手册.docx

BIN
JSD-7965-需求确认书V1-1.docx

Binary file not shown.

5
README.md

@ -1,3 +1,6 @@
# open-JSD-7965
JSD-7965 开源任务材料
JSD-7965 开源任务材料\
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
仅作为开发者学习参考使用!禁止用于任何商业用途!\
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。

BIN
lib/EsbSDK-1.0.jar

Binary file not shown.

BIN
lib/EsbSDK_Http-1.0.jar

Binary file not shown.

BIN
lib/fastjson-1.2.73.jar

Binary file not shown.

BIN
lib/fr-plugin-weixin-10.4.982.jar

Binary file not shown.

BIN
lib/logback-classic-1.2.3.jar

Binary file not shown.

BIN
lib/logback-core-1.2.3.jar

Binary file not shown.

BIN
lib/slf4j-api-1.7.25.jar

Binary file not shown.

66
plugin.xml

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><plugin>
<id>com.fr.plugin.loginAuth</id>
<name><![CDATA[登录认证]]></name>
<active>yes</active>
<version>1.0.22</version>
<env-version>10.0</env-version>
<jartime>2018-07-31</jartime>
<vendor>fr.open</vendor>
<description><![CDATA[登录认证]]></description>
<main-package>com.fr.plugin.loginAuth</main-package>
<change-notes>
<![CDATA[
[2021-05-12]10.4.982:
修复bug<br/>
[2021-04-28]10.4.981:
修复bug<br/>
[2021-04-14]10.4.979:
修复bug<br/>
[2021-03-16]10.4.977:
推送时定时调度运行监控页面报错优化<br/>
日志中增加错误码和解决方案页面的url<br/>
[2021-01-26]10.4.976:
解决bug<br/>
[2020-12-15]10.4.975:
微信集成下支持获取经纬度js<br/>
新增获取用户绑定关系接口<br/>
[2020-10-30]10.4.97:
链接可设置是否提前计算公式<br/>
解决bug<br/>
[2020-09-11]10.4.90:
解决bug<br/>
[2020-07-31]10.4.84:
修复微信定时调度图片持久化失败的bug<br/>
解决bug<br/>
[2020-06-30]10.4.80:
消息推送支持推送到微信群<br/>
[2020-06-03]10.4.76:
H5拍照上传支持前置摄像头和选择是否原图<br/>
生成模板链接支持选择参数<br/>
[2020-04-23]10.4.69:
支持集群<br/>
[2020-04-03]10.4.66:
增加单点登录、定时调度和同步通讯录模块的日志监控<br/>
[2020-02-28]10.4.61:
手动匹配用户时,用户名显示为姓名(用户名)格式,方便查找用户<br/>
服务器和代理服务器添加注释<br/>
]]>
</change-notes>
<function-recorder class="com.fr.plugin.loginAuth.dbAccessProvider.AuthUserDBController"/>
<extra-decision>
<HttpHandlerProvider class="com.fr.plugin.loginAuth.handler.ExtendAttrHandlerProvider"/>
<URLAliasProvider class="com.fr.plugin.loginAuth.handler.URLAliasProvide"/>
<EmbedRequestFilterProvider class="com.fr.plugin.loginAuth.filter.SSOFilter"/>
<ControllerRegisterProvider class="com.fr.plugin.loginAuth.dbAccessProvider.ControllerBridge"/>
<!-- <HttpAuthorizeProvider class="com.fr.plugin.loginAuth.httpAuth.Login"/>-->
<WebResourceProvider class="com.fr.plugin.loginAuth.webresource.WebResourceProvider"/>
</extra-decision>
<extra-core>
<DBAccessProvider class="com.fr.plugin.loginAuth.dbAccessProvider.AuthUserDBController"/>
</extra-core>
<dependence>
<Item key="com.fr.plugin.weixin" type="plugin"/>
</dependence>
</plugin>

43
src/main/java/com/fr/plugin/loginAuth/dbAccessProvider/AuthUserController.java

@ -0,0 +1,43 @@
package com.fr.plugin.loginAuth.dbAccessProvider;
import com.fr.decision.webservice.annotation.LoginStatusChecker;
import com.fr.third.springframework.stereotype.Controller;
import com.fr.third.springframework.web.bind.annotation.RequestMapping;
/**
* @author 秃破天际
* @version 10.0
* Created by 秃破天际 on 2021-04-25
**/
@Controller("DBAccessDemoController")
@LoginStatusChecker(required = false)
@RequestMapping(value = "/db/demo")
public class AuthUserController {
// @RequestMapping( value = "/dm_entity", method = RequestMethod.POST )
// @ResponseBody
// public Response add( @RequestBody AuthUserEntity bean )throws Exception{
// AuthUserDBController.add(bean);
// return Response.ok( bean );
// }
//
// @RequestMapping( value = "/dm_entity/{entity}", method = RequestMethod.DELETE )
// @ResponseBody
// public Response delete( @PathVariable("entity") String entity )throws Exception{
// return Response.ok( AuthUserDBController.deleteOrg(entity) );
// }
//
// @RequestMapping( value = "/dm_entity", method = RequestMethod.PUT )
// @ResponseBody
// public Response update( @RequestBody AuthUserEntity bean )throws Exception{
// AuthUserDBController.update(bean);
// return Response.ok( bean );
// }
//
// @RequestMapping( value = "/dm_entity", method = RequestMethod.GET )
// @ResponseBody
// public Response like( @RequestParam(value = "key") String key )throws Exception{
// return Response.ok( AuthUserDBController.like(key) );
// }
}

305
src/main/java/com/fr/plugin/loginAuth/dbAccessProvider/AuthUserDBController.java

@ -0,0 +1,305 @@
package com.fr.plugin.loginAuth.dbAccessProvider;
import com.fr.db.fun.impl.AbstractDBAccessProvider;
import com.fr.plugin.loginAuth.utils.FRUtils;
import com.fr.plugin.transform.FunctionRecorder;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.stable.db.accessor.DBAccessor;
import com.fr.stable.db.action.DBAction;
import com.fr.stable.db.dao.DAOContext;
import com.fr.stable.db.dao.DAOProvider;
import java.util.ArrayList;
import java.util.List;
/**
* @author 秃破天际
* @version 10.0
* Created by 秃破天际 on 2021-04-25
**/
@EnableMetrics
@FunctionRecorder
public class AuthUserDBController extends AbstractDBAccessProvider {
private static DBAccessor accessor;
public static DBAccessor getAccessor() {
return accessor;
}
@Override
public DAOProvider[] registerDAO() {
return new DAOProvider[]{
AuthUserDao.DAO,
AuthUserMacDAO.DAO
};
}
@Override
public void onDBAvailable(DBAccessor accessor) {
AuthUserDBController.accessor = accessor;
}
public static List<AuthUserEntity> getByUserName(final String username ){
try{
return accessor.runQueryAction(new DBAction<List<AuthUserEntity>>() {
@Override
public List<AuthUserEntity> run(DAOContext context) throws Exception {
List<AuthUserEntity> list = context.getDAO(AuthUserDao.class).getByUserName(username);
return list;
}
});
}catch(Throwable e){
FRUtils.FRLogInfo("getByUserName:"+e.getMessage());
}
return new ArrayList<AuthUserEntity>();
}
public static List<AuthUserMacEntity> getUserAuthMac(final String username, final String mac) throws Exception{
return accessor.runQueryAction(new DBAction<List<AuthUserMacEntity>>() {
@Override
public List<AuthUserMacEntity> run(DAOContext context) throws Exception {
List<AuthUserMacEntity> list = context.getDAO(AuthUserMacDAO.class).getAuthUserMac(username,mac);
return list;
}
});
}
public static List<AuthUserMacEntity> getUserAuthMac2(final String username, final String mac,final String deviceType) throws Exception{
return accessor.runQueryAction(new DBAction<List<AuthUserMacEntity>>() {
@Override
public List<AuthUserMacEntity> run(DAOContext context) throws Exception {
List<AuthUserMacEntity> list = context.getDAO(AuthUserMacDAO.class).getAuthUserMac2(username,mac,deviceType);
return list;
}
});
}
/**
* 业务对象
* @param bean
*/
public static void addUserAuth( final AuthUserEntity bean ) throws Exception {
accessor.runDMLAction(new DBAction<Boolean>() {
@Override
public Boolean run(DAOContext context) throws Exception {
context.getDAO(AuthUserDao.class).add(bean);
return true;
}
});
}
/**
* 业务对象
* @param bean
*/
public static void add( final AuthUserMacEntity bean ) throws Exception {
accessor.runDMLAction(new DBAction<Boolean>() {
@Override
public Boolean run(DAOContext context) throws Exception {
context.getDAO(AuthUserMacDAO.class).add(bean);
return true;
}
});
}
// /**
// * 获取org对象
// * @param orgCode
// * @return
// */
// public static AuthUserEntity getOrg(final String orgCode){
// try{
// return accessor.runQueryAction(new DBAction<AuthUserEntity>() {
// @Override
// public AuthUserEntity run(DAOContext context) throws Exception {
// List<AuthUserEntity> result = new ArrayList<AuthUserEntity>();
// List<AuthUserEntity> list = context.getDAO(AuthUserDao.class).likeByKey(orgCode);
// for( AuthUserEntity item : list ){
//// result.add( toDataBean(item,null) );
// }
// return result != null && result.size() > 0 ? result.get(0) : new AuthUserEntity();
// }
// });
// }catch(Throwable e){
//// LogKit.error(e,"Get DataBeans{} Error:{}",key,e.getMessage());
// }
// return new AuthUserEntity();
// }
//
// /**
// * 业务对象——增
// * @param bean
// */
// public static void add( final AuthUserEntity bean ){
// try{
// accessor.runDMLAction(new DBAction<Boolean>() {
// @Override
// public Boolean run(DAOContext context) throws Exception {
// context.getDAO(AuthUserDao.class).add( loadDemoEntity(bean,true) );
//// context.getDAO(LinkDao.class).add( loadLinkEntities(bean,true) );
// return true;
// }
// });
// }catch(Throwable e){
// e.printStackTrace();
//// LogKit.error(e,"Add DataBean Error:{}",e.getMessage());
// }
// }
//
// /**
// * 业务对象——删
// * @param id
// */
// public static AuthUserEntity deleteOrg( final String id ){
// try{
// return accessor.runDMLAction(new DBAction<AuthUserEntity>() {
// @Override
// public AuthUserEntity run(DAOContext context) throws Exception {
// AuthUserEntity entity = context.getDAO(AuthUserDao.class).getById(id);
// if( null == entity ){
// return null;
// }
// context.getDAO(AuthUserDao.class).remove( id );
//// List<LinkEntity> list = context.getDAO(LinkDao.class).removeByKey(entity.getDid());
// return toDataBean(entity,null);
// }
// });
// }catch(Throwable e){
//// LogKit.error(e,"Delete DataBean[{}] Error:{}",id,e.getMessage());
// }
// return null;
// }
//
// /**
// * 业务对象——改
// * @param bean
// */
// public static void update( AuthUserEntity bean ){
// final AuthUserEntity bean2 = bean;
// try{
// accessor.runDMLAction(new DBAction<Boolean>() {
// @Override
// public Boolean run(DAOContext context) throws Exception {
// context.getDAO(AuthUserDao.class).update( loadDemoEntity(bean2,false) );
// context.getDAO(AuthUserMacDAO.class).addOrUpdate( loadLinkEntities(bean2,false) );
// return true;
// }
// });
// }catch(Throwable e){
//// LogKit.error(e,"Update DataBean Error:{}",e.getMessage());
// }
// }
//
// /**
// * 业务对象——查
// * @param key
// * @return
// */
// public static List<AuthUserEntity> like(String key ){
// final String key2 = key;
// try{
// return accessor.runQueryAction(new DBAction<List<AuthUserEntity>>() {
// @Override
// public List<AuthUserEntity> run(DAOContext context) throws Exception {
// List<AuthUserEntity> result = new ArrayList<AuthUserEntity>();
// List<AuthUserEntity> list = context.getDAO(AuthUserDao.class).likeByKey(key2);
// for( AuthUserEntity item : list ){
//// List<LinkEntity> links = context.getDAO(LinkDao.class).getByKey(item.getDid());
// result.add( toDataBean(item,null) );
// }
// return result;
// }
// });
// }catch(Throwable e){
//// LogKit.error(e,"Get DataBeans{} Error:{}",key,e.getMessage());
// }
// return new ArrayList<AuthUserEntity>();
// }
//
// /**
// * 根据pId和type查询
// * @param pId
// * @param type
// * @return
// */
// public static List<AuthUserEntity> like(final String pId,final String type){
// try{
// return accessor.runQueryAction(new DBAction<List<AuthUserEntity>>() {
// @Override
// public List<AuthUserEntity> run(DAOContext context) throws Exception {
// List<AuthUserEntity> result = new ArrayList<AuthUserEntity>();
// List<AuthUserEntity> list = context.getDAO(AuthUserDao.class).like(pId,type);
// for( AuthUserEntity item : list ){
//// List<LinkEntity> links = context.getDAO(LinkDao.class).getByKey(item.getDid());
// result.add( toDataBean(item,null) );
// }
// return result;
// }
// });
// }catch(Throwable e){
//// LogKit.error(e,"Get DataBeans{} Error:{}",key,e.getMessage());
// }
// return new ArrayList<AuthUserEntity>();
// }
//
// private static AuthUserEntity loadDemoEntity(AuthUserEntity bean, boolean isAdd ){
// AuthUserEntity entity = new AuthUserEntity();
//// if(isAdd || StringUtils.isEmpty( bean.getId() ) ){
//// bean.setId(UUIDUtil.generate());
//// }
//// entity.setId( bean.getId() );
//// entity.setDid( bean.getDid());
//// entity.setCode(bean.getCode());
//// entity.setType(bean.getType());
//// entity.setPid(bean.getPid());
//// entity.setBean( bean.getBean() );
// return entity;
// }
//
// private static AuthUserEntity toDataBean(AuthUserEntity entity, List<AuthUserMacEntity> list ){
// AuthUserEntity bean = new AuthUserEntity();
//// bean.setId( entity.getId() );
//// bean.setDid( entity.getDid());
//// bean.setCode(entity.getCode());
//// bean.setType(entity.getType());
//// bean.setPid(entity.getPid());
//// bean.setBean( entity.getBean() );
//// bean.setAttr3( toAttrBeans(list) );
// return bean;
// }
//
// private static List<AuthUserEntity> toAttrBeans( List<AuthUserMacEntity> links ){
// List<AuthUserEntity> list = new ArrayList<AuthUserEntity>();
// for( AuthUserMacEntity item : links ){
// AuthUserEntity bean = new AuthUserEntity();
//// bean.setAttr1(item.getId());
//// bean.setAttr2(item.getAttr3());
// list.add( bean );
// }
// return list;
// }
//
// private static List<AuthUserMacEntity> loadLinkEntities(AuthUserEntity bean, boolean isAdd ){
// List<AuthUserMacEntity> list = new ArrayList<AuthUserMacEntity>();
//// List<DemoBean> attr3 = bean.getAttr3();
//// for( DemoBean item : attr3 ){
//// if(isAdd || StringUtils.isEmpty( item.getAttr1() ) ){
//// item.setAttr1(UUIDUtil.generate());
//// }
//// list.add( new LinkEntity()
//// .id( item.getAttr1() )
//// .key( bean.getKey() )
//// .attr3( item.getAttr2() )
//// );
//// }
// return list;
// }
}

79
src/main/java/com/fr/plugin/loginAuth/dbAccessProvider/AuthUserDao.java

@ -0,0 +1,79 @@
package com.fr.plugin.loginAuth.dbAccessProvider;
import com.fr.stable.db.dao.BaseDAO;
import com.fr.stable.db.dao.DAOProvider;
import com.fr.stable.db.session.DAOSession;
import com.fr.stable.query.QueryFactory;
import com.fr.stable.query.condition.QueryCondition;
import com.fr.stable.query.restriction.RestrictionFactory;
import java.util.List;
/**
* @author 秃破天际
* @version 10.0
* Created by 秃破天际 on 2021-04-25
**/
public class AuthUserDao extends BaseDAO<AuthUserEntity> {
public AuthUserDao(DAOSession session) {
super(session);
}
@Override
protected Class<AuthUserEntity> getEntityClass() {
return AuthUserEntity.class;
}
public final static DAOProvider DAO = new DAOProvider() {
@Override
public Class getEntityClass() {
return AuthUserEntity.class;
}
@Override
public Class<? extends BaseDAO> getDAOClass() {
return AuthUserDao.class;
}
};
public List<AuthUserEntity> getByUserName(String username ) throws Exception{
QueryCondition condition = QueryFactory.create()
.addRestriction(RestrictionFactory.eq(AuthUserEntity.COLUMN_WORKCODE, username));
return find(condition);
// QueryCondition condition = QueryFactory.create()
// .addRestriction(RestrictionFactory.eq(AuthUserEntity.COLUMN_WORKCODE, username));
//
// return find(condition);
}
// public List<AuthUserEntity> likeByKey(String key )throws Exception{
// QueryCondition condition = QueryFactory.create()
// .addRestriction(RestrictionFactory.eq(AuthUserEntity.COLUMN_CD, key));
// return find(condition);
// }
//
// public List<AuthUserEntity> like(String pid, String type)throws Exception{
// QueryCondition condition = QueryFactory.create()
// .addRestriction(RestrictionFactory.like(AuthUserEntity.COLUMN_CD, pid)).addRestriction(RestrictionFactory.like(AuthUserEntity.COLUMN_CD,type));
// return find(condition);
// }
//
public void add(AuthUserEntity entity) throws Exception {
getSession().persist(entity);
}
//
// public void update(AuthUserEntity entity) throws Exception {
// getSession().merge(entity);
// }
//
// public AuthUserEntity getById(String id) throws Exception {
// return getSession().getById(id, AuthUserEntity.class);
// }
//
// public void remove(String id) throws Exception {
// getSession().remove(QueryFactory.create()
// .addRestriction(RestrictionFactory.eq("id", id)),
// this.getEntityClass());
// }
}

55
src/main/java/com/fr/plugin/loginAuth/dbAccessProvider/AuthUserEntity.java

@ -0,0 +1,55 @@
package com.fr.plugin.loginAuth.dbAccessProvider;
import com.fr.stable.db.entity.BaseEntity;
import com.fr.third.javax.persistence.Column;
import com.fr.third.javax.persistence.Entity;
import com.fr.third.javax.persistence.Table;
import java.util.Date;
/**
* @author 秃破天际
* @version 10.0
* Created by 秃破天际 on 2021-04-25
**/
@Entity
@Table(name = "HT_Auth_User")
public class AuthUserEntity extends BaseEntity {
public static final String COLUMN_WORKCODE = "workcode";
public static final String COLUMN_WORKNAME = "workname";
public static final String COLUMN_CREATEDDATE = "createddate";
@Column(name = COLUMN_WORKCODE)
private String workcode = null;
@Column(name = COLUMN_WORKNAME)
private String workname = null;
@Column(name = COLUMN_CREATEDDATE)
private Date createddate = null;
public String getWorkcode() {
return workcode;
}
public void setWorkcode(String workcode) {
this.workcode = workcode;
}
public String getWorkname() {
return workname;
}
public void setWorkname(String workname) {
this.workname = workname;
}
public Date getCreateddate() {
return createddate;
}
public void setCreateddate(Date createddate) {
this.createddate = createddate;
}
}

97
src/main/java/com/fr/plugin/loginAuth/dbAccessProvider/AuthUserMacDAO.java

@ -0,0 +1,97 @@
package com.fr.plugin.loginAuth.dbAccessProvider;
import com.fr.stable.db.dao.BaseDAO;
import com.fr.stable.db.dao.DAOProvider;
import com.fr.stable.db.session.DAOSession;
import com.fr.stable.query.QueryFactory;
import com.fr.stable.query.condition.QueryCondition;
import com.fr.stable.query.restriction.RestrictionFactory;
import java.util.List;
/**
* @author 秃破天际
* @version 10.0
* Created by 秃破天际 on 2021-04-25
**/
public class AuthUserMacDAO extends BaseDAO<AuthUserMacEntity> {
public AuthUserMacDAO(DAOSession session) {
super(session);
}
@Override
protected Class<AuthUserMacEntity> getEntityClass() {
return AuthUserMacEntity.class;
}
public final static DAOProvider DAO = new DAOProvider() {
@Override
public Class getEntityClass() {
return AuthUserMacEntity.class;
}
@Override
public Class<? extends BaseDAO> getDAOClass() {
return AuthUserMacDAO.class;
}
};
public List<AuthUserMacEntity> getAuthUserMac(String username, String mac ) throws Exception{
QueryCondition condition = QueryFactory.create().addRestriction(RestrictionFactory.eq(AuthUserMacEntity.COLUMN_WC, username))
.addRestriction(RestrictionFactory.eq(AuthUserMacEntity.COLUMN_DM, mac));
return find(condition);
}
public void add( AuthUserMacEntity item) throws Exception {
getSession().persist(item);
}
public List<AuthUserMacEntity> getAuthUserMac2(String username, String mac, String deviceType) throws Exception {
QueryCondition condition = QueryFactory.create().addRestriction(RestrictionFactory.eq(AuthUserMacEntity.COLUMN_WC, username))
.addRestriction(RestrictionFactory.eq(AuthUserMacEntity.COLUMN_DM, mac)).addRestriction(RestrictionFactory.eq(AuthUserMacEntity.COLUMN_DT,deviceType));
return find(condition);
}
//
// public void addOrUpdate( List<AuthUserMacEntity> list )throws Exception {
// for( AuthUserMacEntity item : list ){
// addOrUpdate(item);
// }
// }
//
// public List<AuthUserMacEntity> removeByKey(String key )throws Exception{
// QueryCondition condition = QueryFactory.create().addRestriction(RestrictionFactory.eq(AuthUserMacEntity.COLUMN_AS, key));
// List<AuthUserMacEntity> list = find(condition);
// for( AuthUserMacEntity item : list ){
// remove( item.getId() );
// }
// return list;
// }
//
// public List<AuthUserMacEntity> getByKey(String key )throws Exception{
// QueryCondition condition = QueryFactory.create().addRestriction(RestrictionFactory.eq(AuthUserMacEntity.COLUMN_AS, key));
// return find(condition);
// }
//
// public void add(AuthUserMacEntity entity) throws Exception {
// getSession().persist(entity);
// }
//
// public void update(AuthUserMacEntity entity) throws Exception {
// getSession().merge(entity);
// }
//
// public void addOrUpdate(AuthUserMacEntity entity) throws Exception {
// if (entity != null && this.getById(entity.getId()) != null) {
// update(entity);
// } else {
// add(entity);
// }
// }
//
// public AuthUserMacEntity getById(String id) throws Exception {
// return this.getSession().getById(id, AuthUserMacEntity.class);
// }
//
// public void remove(String id) throws Exception {
// this.getSession().remove(QueryFactory.create().addRestriction(RestrictionFactory.eq("id", id)), this.getEntityClass());
// }
}

96
src/main/java/com/fr/plugin/loginAuth/dbAccessProvider/AuthUserMacEntity.java

@ -0,0 +1,96 @@
package com.fr.plugin.loginAuth.dbAccessProvider;
import com.fr.stable.db.entity.BaseEntity;
import com.fr.stable.db.entity.TableAssociation;
import com.fr.third.javax.persistence.Column;
import com.fr.third.javax.persistence.Entity;
import com.fr.third.javax.persistence.Table;
import java.util.Date;
/**
* @author 秃破天际
* @version 10.0
* Created by 秃破天际 on 2021-04-25
**/
@Entity
@Table(name = "HT_Auth_UserMac")
@TableAssociation(associated = true)
public class AuthUserMacEntity extends BaseEntity {
public static final String COLUMN_WC = "workcode";
public static final String COLUMN_DM = "devicemac";
public static final String COLUMN_DT = "devicetype";
public static final String COLUMN_AS = "authstatus";
public static final String COLUMN_CD = "createddate";
public static final String COLUMN_AD = "authdate";
@Column(name = COLUMN_WC)
private String workcode = null;
@Column(name = COLUMN_DM)
private String devicemac = null;
@Column(name = COLUMN_DT)
private String devicetype = null;
@Column(name = COLUMN_AS)
private int authstatus = 0;
@Column(name = COLUMN_CD)
private Date createddate = null;
@Column(name = COLUMN_AD)
private Date authdate = null;
public String getWorkcode() {
return workcode;
}
public void setWorkcode(String workcode) {
this.workcode = workcode;
}
public String getDevicemac() {
return devicemac;
}
public void setDevicemac(String devicemac) {
this.devicemac = devicemac;
}
public String getDevicetype() {
return devicetype;
}
public void setDevicetype(String devicetype) {
this.devicetype = devicetype;
}
public int getAuthstatus() {
return authstatus;
}
public void setAuthstatus(int authstatus) {
this.authstatus = authstatus;
}
public Date getCreateddate() {
return createddate;
}
public void setCreateddate(Date createddate) {
this.createddate = createddate;
}
public Date getAuthdate() {
return authdate;
}
public void setAuthdate(Date authdate) {
this.authdate = authdate;
}
}

15
src/main/java/com/fr/plugin/loginAuth/dbAccessProvider/ControllerBridge.java

@ -0,0 +1,15 @@
package com.fr.plugin.loginAuth.dbAccessProvider;
import com.fr.decision.fun.impl.AbstractControllerRegisterProvider;
/**
* @author 秃破天际
* @version 10.0
* Created by 秃破天际 on 2021-04-25
**/
public class ControllerBridge extends AbstractControllerRegisterProvider {
@Override
public Class<?>[] getControllers() {
return new Class[]{AuthUserController.class};
}
}

390
src/main/java/com/fr/plugin/loginAuth/filter/SSOFilter.java

@ -0,0 +1,390 @@
package com.fr.plugin.loginAuth.filter;
import com.fr.base.TemplateUtils;
import com.fr.decision.fun.impl.AbstractEmbedRequestFilterProvider;
import com.fr.decision.webservice.utils.WebServiceUtils;
import com.fr.decision.webservice.v10.login.LoginService;
import com.fr.json.JSONObject;
import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.loginAuth.dbAccessProvider.AuthUserDBController;
import com.fr.plugin.loginAuth.dbAccessProvider.AuthUserEntity;
import com.fr.plugin.loginAuth.dbAccessProvider.AuthUserMacEntity;
import com.fr.plugin.loginAuth.utils.FRUtils;
import com.fr.plugin.loginAuth.utils.ResponseUtils;
import com.fr.plugin.loginAuth.utils.SafeUtils;
import com.fr.plugin.loginAuth.utils.Utils;
import com.fr.plugin.weixin.server.bean.WeiXinAgent;
import com.fr.plugin.weixin.server.config.WeiXinConfig;
import com.fr.plugin.weixin.server.constant.WeiXinConstants;
import com.fr.plugin.weixin.server.log.WeiXinLogErrorCode;
import com.fr.plugin.weixin.server.log.WeiXinLoggerFactory;
import com.fr.plugin.weixin.server.util.*;
import com.fr.stable.StringUtils;
import com.fr.web.utils.WebUtils;
import org.slf4j.MDC;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.*;
public class SSOFilter extends AbstractEmbedRequestFilterProvider {
// 默认密钥信息
static byte[] IVByte = {22, 45, 60, 97, 23, 33, 56, 9};// IVStr.getBytes();
static byte[] keyByte = Base64.getDecoder().decode("58A50618868F445AA96283532ACF8020");
@Override
public void filter(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
String url = FRUtils.getAllUrl(httpServletRequest);
//PC认证
if (url.contains("/decision/login")) {
pcAuth(httpServletRequest,httpServletResponse);
return;
}
//企业微信单点
boolean isWeixin = url.contains("weixin/single/login");
if (isWeixin) {
try {
weixinAuth(httpServletRequest,httpServletResponse);
} catch (Exception e) {
FRUtils.FRLogInfo("微信认证异常:"+e.getMessage());
}
return ;
}
//OA单点认证
String authtokenDec = httpServletRequest.getParameter("authtoken");
if(Utils.isNotNullStr(authtokenDec)){
ssoAuth(httpServletRequest,httpServletResponse,url,authtokenDec);
}
}
private static boolean blackList(String type,String mac,String username,HttpServletResponse httpServletResponse){
if(Utils.isNullStr(mac)){
mac = "";
}
if(type.equals("PC") && Utils.isNullStr(mac)){
AuthUserMacEntity ame = new AuthUserMacEntity();
ame.setAuthstatus(1);
ame.setDevicemac(mac);
ame.setWorkcode(username);
ame.setId(UUID.randomUUID().toString());
ame.setCreateddate(new Date());
ame.setDevicetype("PC");
List<AuthUserEntity> authUserMac = AuthUserDBController.getByUserName(username);
if(authUserMac != null && authUserMac.size() > 0){
try {
if (authUserMac != null && authUserMac.size() > 0) {
List<AuthUserMacEntity> authUserMacs = AuthUserDBController.getUserAuthMac2(username, mac, type);
if (authUserMacs != null && authUserMacs.size() <= 0) {
AuthUserDBController.add(ame);
}
}
} catch (Exception e) {
FRUtils.FRLogInfo("添加mac匹配异常:" + e.getMessage());
}
JSONObject json = new JSONObject();
json.put("errorCode", "90000");
json.put("errorMsg", "没有权限登录");
ResponseUtils.response(httpServletResponse, json);
return false;
}
return true;
}
List<AuthUserEntity> blackList = null;
try {
blackList = AuthUserDBController.getByUserName(username);
} catch (Exception e) {
FRUtils.FRLogInfo("获取黑名单异常:" + e.getMessage());
JSONObject json = new JSONObject();
json.put("errorCode", "90000");
json.put("errorMsg", "没有权限登录");
ResponseUtils.response(httpServletResponse, json);
return false;
}
if (blackList != null && blackList.size() > 0) {
FRUtils.FRLogInfo("黑名单:" + blackList.size());
FRUtils.FRLogInfo("黑名单:" + blackList.get(0).getWorkcode());
//查询AuthUserMac表
List<AuthUserMacEntity> authUserMac = null;
try {
authUserMac = AuthUserDBController.getUserAuthMac2(username, mac, type);
} catch (Exception e) {
FRUtils.FRLogInfo("获取mac匹配异常:" + e.getMessage());
JSONObject json = new JSONObject();
json.put("errorCode", "90000");
json.put("errorMsg", "没有权限登录");
ResponseUtils.response(httpServletResponse, json);
return false;
}
//如果没有或者只有姓名,则添加一条username
if (authUserMac == null || authUserMac.size() <= 0) {
AuthUserMacEntity ame = new AuthUserMacEntity();
ame.setAuthstatus(1);
ame.setDevicemac(mac);
ame.setWorkcode(username);
ame.setId(UUID.randomUUID().toString());
ame.setCreateddate(new Date());
ame.setDevicetype("PC");
FRUtils.FRLogInfo("添加mac");
try {
AuthUserDBController.add(ame);
} catch (Exception e) {
FRUtils.FRLogInfo("添加mac匹配异常:" + e.getMessage());
}
JSONObject json = new JSONObject();
json.put("errorCode", "90000");
json.put("errorMsg", "没有权限登录");
ResponseUtils.response(httpServletResponse, json);
return false;
}
//如果有并且匹配,查询状态并确定是否放行
boolean flag = false;
for (AuthUserMacEntity ame : authUserMac) {
if (ame.getAuthstatus() == 0) {
flag = true;
}
}
if (!flag) {
JSONObject json = new JSONObject();
json.put("errorCode", "90000");
json.put("errorMsg", "没有权限登录");
ResponseUtils.response(httpServletResponse, json);
return false;
}
}
return true;
}
private static boolean pcAuth(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse){
String username = httpServletRequest.getHeader("username");
String mac = httpServletRequest.getHeader("mac");
FRUtils.FRLogInfo("pcParam:username=" + username + ";mac=" + mac);
if (Utils.isNotNullStr(username)) {
return blackList("PC",mac,username,httpServletResponse);
}
return false;
}
private static boolean ssoAuth(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,String url,String authtokenDec){
String mac = httpServletRequest.getParameter("mac");
if(Utils.isNullStr(mac)){
String path2 = httpServletRequest.getContextPath() +httpServletRequest.getServletPath();
//跳转到获取cookie页面
Map<String, String> parameterMap = new HashMap<String, String>();
String path = "/com/fr/plugin/loginAuth/html/getMac.html";
parameterMap.put("url", url);
parameterMap.put("path",path2);
try {
String macPage = TemplateUtils.renderTemplate(path, parameterMap);
WebUtils.printAsString(httpServletResponse, macPage);
}catch (Exception e){
FRUtils.FRLogInfo("跳转获取cookie页面异常:"+e.getMessage());
}
return false;
}
mac = "none".equals(mac)?"":mac;
String decode = decode(authtokenDec);
if (StringUtils.isNotBlank(decode)) {
try {
FineLoggerFactory.getLogger().info("收到登录请求:{}", decode);
boolean safeCheck = SafeUtils.safeCheck2(decode);
if (safeCheck) {
JSONObject jsonObject = new JSONObject(decode);
String acount = jsonObject.getString("Account");
boolean allowLogin = blackList("PC",mac,acount,httpServletResponse);
if(allowLogin){
login(httpServletRequest, httpServletResponse, acount);
FineLoggerFactory.getLogger().info("登录成功:{}", acount);
}
}
}catch(Exception e){
FRUtils.FRLogInfo("单点登陆异常:"+e.getMessage());
return false;
}
}
return true;
}
private static void weixinAuth(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
boolean available = WeiXinUtils.isLicenseAvailable();
if (available) {
MDC.put("logger", WeiXinConstants.LOGIN);
FRUtils.FRLogInfo("===开始单点登录===");
String decUserName = StringUtils.EMPTY;
String code = WebUtils.getHTTPRequestParameter(httpServletRequest, "code");
FRUtils.FRLogInfo("code: " + code);
String param = WebUtils.getHTTPRequestParameter(httpServletRequest, "sb");
FRUtils.FRLogInfo("sb: " + param);
String redirectUrl = httpServletRequest.getParameter("redirectUrl"); // 这里不能使用WebUtils的方法,会把中文模板名称的编码给解析了导致找不到模板
if (WeiXinConfig.getInstance().getUrlMap().containsKey(redirectUrl)) {
redirectUrl = WeiXinConfig.getInstance().getUrlMap().get(redirectUrl);
}
FRUtils.FRLogInfo("redirectUrl: " + redirectUrl);
FRUtils.FRLogInfo("isnotEmpty:" + StringUtils.isNotEmpty(redirectUrl));
FRUtils.FRLogInfo("2:" + WeiXinUtils.compareUrlDomain(redirectUrl, WeiXinConfig.getInstance().getUrl()));
if (StringUtils.isNotEmpty(redirectUrl) && WeiXinUtils.compareUrlDomain(redirectUrl, WeiXinConfig.getInstance().getUrl())) {
FRUtils.FRLogInfo("agent:1");
WeiXinAgent agent = WeiXinAgentUtils.getAgentByCheckMD5(param);
FRUtils.FRLogInfo("agent:2");
String secret = StringUtils.EMPTY;
if (agent != null) {
secret = agent.getSecret();
} else {
FRUtils.FRLogInfo("单点登录请求中sb参数不正确,无法找到对应微信应用!" + WeiXinLogErrorCode.LOST_SB_PARAM);
}
FRUtils.FRLogInfo("secret:" + secret);
JSONObject userInfo = WeiXinRequest.getUserInfoByCode(code, secret);
FRUtils.FRLogInfo("userInfo:" + userInfo.toString());
if (userInfo != null && userInfo.has("UserId")) {
String userId = userInfo.optString("UserId");
JSONObject detailUserInfo = WeiXinRequest.getDetailUserInfoByUserId(secret, userId);
if (WeiXinRequest.isOk(detailUserInfo)) {
FRUtils.FRLogInfo(String.format("userid为%s的用户详细信息为:", userId) + detailUserInfo.toString());
if (WeiXinUserUtils.isWeiXinUserEnable(detailUserInfo)) {
WeiXinLoggerFactory.getLogger().debug("开始匹配平台用户。。。");
decUserName = WeiXinUserUtils.weiXinUserToDecUser(detailUserInfo);
} else {
FRUtils.FRLogInfo("微信用户被禁用,请于微信管理后台设置!" + WeiXinLogErrorCode.WEIXIN_USER_DISABLE);
}
} else {
FRUtils.FRLogInfo(String.format("获取userId为%s的用户详细信息失败!", userId) + WeiXinLogErrorCode.GET_USER_DETAIL_FAIL);
}
} else {
FRUtils.FRLogInfo("code换取userId失败,请检查网络设置!" + WeiXinLogErrorCode.GET_USERID_FAIL);
}
if (WeiXinDecUserUtils.isUserExist(decUserName)) {
FRUtils.FRLogInfo("decUserName:"+decUserName);
String mac = userInfo.getString("DeviceId");
boolean isLogin = blackList("mobile",mac,decUserName,httpServletResponse);
if(!isLogin){
ResponseUtils.failedResponse(httpServletResponse,"您的电脑未授权,请联系管理员");
return ;
}
String token = LoginService.getInstance().login(httpServletRequest, httpServletResponse, decUserName, StringUtils.EMPTY, WeiXinConstants.WEIXIN_PLUGIN_ID);
FRUtils.FRLogInfo("单点登录成功!生成token为:" + token);
} else if (StringUtils.isNotEmpty(decUserName)) {
FRUtils.FRLogInfo(String.format("平台用户中无%s用户!", decUserName) + WeiXinLogErrorCode.NO_DEC_USER);
}
String jsApiPath = com.fr.base.Base64.encode(WeiXinConstants.WEIXIN_JSAPI_PATH.getBytes("UTF-8"));
redirectUrl = WeiXinURLUtils.putParamToUrl(redirectUrl, "js_api_path", jsApiPath);
redirectUrl = redirectUrl + "&sb=" + param;
FRUtils.FRLogInfo("开始跳转url:" + redirectUrl);
httpServletResponse.sendRedirect(redirectUrl);
FRUtils.FRLogInfo("===单点登录结束===");
MDC.clear();
} else {
FRUtils.FRLogInfo("进入了else2");
WebUtils.printAsString(httpServletResponse, WebServiceUtils.generateUnavailableWebPage(
InterProviderFactory.getProvider().getLocText("Dec-WeiXin_Not_Trusted_Domain_Error"),
"",
InterProviderFactory.getProvider().getLocText("Dec-WeiXin_Not_Trusted_Domain_Exception")
));
}
} else {
FRUtils.FRLogInfo("进入了else");
WeiXinUtils.routeToExpirePage(httpServletRequest, httpServletResponse);
}
}
private static String decode(String str) {
//解密后结果
String dencryptStr = "";
try {
dencryptStr = new String((des3DecodeCBC(keyByte,
IVByte, Base64.getUrlDecoder().decode(str))), StandardCharsets.UTF_8);
return dencryptStr;
//例子的结果数据为 : {"Acount":"8422","TimeStamp":"1558661504"}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
/**
* @param key 密钥
* @param keyiv IV
* @param data Base64编码的密文
* @return 明文
* @throws Exception
* @Description CBC解密
* @author Shindo
* @date 2016年11月16日 上午10:13:49
*/
public static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data)
throws Exception {
Key deskey = null;
DESedeKeySpec spec = new DESedeKeySpec(key);
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
deskey = keyfactory.generateSecret(spec);
Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding");
IvParameterSpec ips = new IvParameterSpec(keyiv);
cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
byte[] bOut = cipher.doFinal(data);
return bOut;
}
private static String login(HttpServletRequest req, HttpServletResponse res, String username) throws Exception {
String token = LoginService.getInstance().login(req, res, username);
req.setAttribute("fine_auth_token", token);
FineLoggerFactory.getLogger().info("fr FrFilter is over with username is ###" + username);
return token;
}
}

12
src/main/java/com/fr/plugin/loginAuth/handler/ExtendAttrHandlerProvider.java

@ -0,0 +1,12 @@
package com.fr.plugin.loginAuth.handler;
import com.fr.decision.fun.HttpHandler;
import com.fr.decision.fun.impl.AbstractHttpHandlerProvider;
public class ExtendAttrHandlerProvider extends AbstractHttpHandlerProvider {
@Override
public HttpHandler[] registerHandlers() {
return new HttpHandler[]{
};
}
}

99
src/main/java/com/fr/plugin/loginAuth/handler/ToDecisionLogin.java

@ -0,0 +1,99 @@
package com.fr.plugin.loginAuth.handler;
import com.fr.base.ServerConfig;
import com.fr.decision.config.AppearanceConfig;
import com.fr.decision.fun.impl.BaseHttpHandler;
import com.fr.decision.web.LoginComponent;
import com.fr.decision.webservice.utils.WebServiceUtils;
import com.fr.decision.webservice.v10.config.ConfigService;
import com.fr.decision.webservice.v10.login.LoginService;
import com.fr.general.CloudCenter;
import com.fr.general.CloudCenterConfig;
import com.fr.security.SecurityConfig;
import com.fr.security.encryption.SystemEncryptionManager;
import com.fr.security.encryption.transmission.impl.SM4TransmissionEncryption;
import com.fr.third.fasterxml.jackson.databind.ObjectMapper;
import com.fr.third.springframework.web.bind.annotation.RequestMethod;
import com.fr.web.Browser;
import com.fr.web.struct.AtomBuilder;
import com.fr.web.struct.PathGroup;
import com.fr.web.utils.WebUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
public class ToDecisionLogin extends BaseHttpHandler {
public ToDecisionLogin() {
}
@Override
public RequestMethod getMethod() {
return RequestMethod.GET;
}
@Override
public String getPath() {
return "/toDecisionLogin";
}
@Override
public boolean isPublic() {
return true;
}
@Override
public void handle(HttpServletRequest req, HttpServletResponse res) throws Exception {
//特定版本
Map<String, Object> param = new HashMap();
ObjectMapper mapper = new ObjectMapper();
param.put("title", AppearanceConfig.getInstance().getPlatformTitle());
param.put("loginConfig", mapper.writeValueAsString(ConfigService.getInstance().getLoginAppearanceConfig()));
param.put("charset", ServerConfig.getInstance().getServerCharset());
PathGroup group = AtomBuilder.create().buildAssembleFilePath(Browser.resolve(req), LoginComponent.KEY);
param.put("styleTag", AtomBuilder.create().toHtmlTag(group.toStylePathGroup()));
param.put("scriptTag", AtomBuilder.create().toHtmlTag(group.toScriptPathGroup()));
Map<String, Object> system = new HashMap();
system.put("frontSeed", SecurityConfig.getInstance().getFrontSeed());
system.put("cloudEnabled", CloudCenterConfig.getInstance().isOnline());
system.put("urlIP", CloudCenter.getInstance().acquireConf("decision.queryip", ""));
if (AppearanceConfig.getInstance().isCopyrightInfoDisplay()) {
system.putAll(LoginService.getInstance().getCopyrightInfo(req));
}
param.put("system", mapper.writeValueAsString(system));
String a = WebServiceUtils.parseWebPageResourceSafe("/com/fr/plugin/loginAuth/js/login.html", param);
WebUtils.printAsString(res, a);
// HashMap var3 = new HashMap();
// ObjectMapper var4 = new ObjectMapper();
// var3.put("title", AppearanceConfig.getInstance().getPlatformTitle());
// var3.put("loginConfig", var4.writeValueAsString(ConfigService.getInstance().getLoginAppearanceConfig()));
// var3.put("charset", ServerConfig.getInstance().getServerCharset());
// PathGroup var5 = AtomBuilder.create().buildAssembleFilePath(Browser.resolve(req), LoginComponent.KEY);
// var3.put("styleTag", AtomBuilder.create().toHtmlTag(var5.toStylePathGroup()));
// var3.put("scriptTag", AtomBuilder.create().toHtmlTag(var5.toScriptPathGroup()));
// HashMap var6 = new HashMap();
// var6.put("frontSeed", SecurityConfig.getInstance().getFrontSeed());
// var6.put("transmissionEncryption", SystemEncryptionManager.getInstance().getTransmissionEncryption().getType());
// var6.put("frontSM4Key", SM4TransmissionEncryption.getInstance().getTransmissionKey());
// var6.put("cloudEnabled", CloudCenterConfig.getInstance().isOnline());
// var6.put("urlIP", CloudCenter.getInstance().acquireConf("decision.queryip", ""));
// if (AppearanceConfig.getInstance().isCopyrightInfoDisplay()) {
// var6.putAll(LoginService.getInstance().getCopyrightInfo(req));
// }
//
// var3.put("system", var4.writeValueAsString(var6));
//
// String a =WebServiceUtils.parseWebPageResourceSafe("/com/fr/web/controller/decision/entrance/resources/login.html", var3);
// WebUtils.printAsString(res, a);
}
}

14
src/main/java/com/fr/plugin/loginAuth/handler/URLAliasProvide.java

@ -0,0 +1,14 @@
package com.fr.plugin.loginAuth.handler;
import com.fr.decision.fun.impl.AbstractURLAliasProvider;
import com.fr.decision.webservice.url.alias.URLAlias;
import com.fr.decision.webservice.url.alias.URLAliasFactory;
public class URLAliasProvide extends AbstractURLAliasProvider {
@Override
public URLAlias[] registerAlias() {
return new URLAlias[]{
URLAliasFactory.createPluginAlias("/toDecisionLogin","/toDecisionLogin",true)
};
}
}

111
src/main/java/com/fr/plugin/loginAuth/httpAuth/Login.java

@ -0,0 +1,111 @@
package com.fr.plugin.loginAuth.httpAuth;
import com.fr.decision.authority.data.User;
import com.fr.decision.fun.impl.AbstractHttpAuthorizeProvider;
import com.fr.json.JSONObject;
import com.fr.plugin.loginAuth.dbAccessProvider.AuthUserDBController;
import com.fr.plugin.loginAuth.dbAccessProvider.AuthUserEntity;
import com.fr.plugin.loginAuth.dbAccessProvider.AuthUserMacEntity;
import com.fr.plugin.loginAuth.utils.CipherUtils;
import com.fr.plugin.loginAuth.utils.FRUtils;
import com.fr.plugin.loginAuth.utils.HttpUtils;
import com.fr.plugin.loginAuth.utils.Utils;
import com.fr.plugin.transform.FunctionRecorder;
import java.util.List;
import java.util.UUID;
@FunctionRecorder
public class Login extends AbstractHttpAuthorizeProvider {
@Override
public Scope scope() {
return Scope.REPLACE;
}
@Override
public boolean authorize(String userName, String psd, String s2, String s3) {
//查询用户是否再AuthUser表中,如果在
List<AuthUserEntity> blackList = null;
try {
blackList = AuthUserDBController.getByUserName(userName);
} catch (Exception e) {
FRUtils.FRLogInfo("获取黑名单异常:"+e.getMessage());
return false;
}
if(blackList != null && blackList.size() > 0){
String mac = getMac();
if(Utils.isNullStr(mac)){
return false;
}
//查询AuthUserMac表
List<AuthUserMacEntity> authUserMac = null;
try {
authUserMac = AuthUserDBController.getUserAuthMac(userName,mac);
} catch (Exception e) {
FRUtils.FRLogInfo("获取mac匹配异常:"+e.getMessage());
return false;
}
//如果没有或者只有姓名,则添加一条
if(authUserMac == null || authUserMac.size() <= 0){
AuthUserMacEntity ame = new AuthUserMacEntity();
ame.setAuthstatus(1);
ame.setDevicemac(mac);
ame.setWorkcode(userName);
ame.setId(UUID.randomUUID().toString());
try {
AuthUserDBController.add(ame);
} catch (Exception e) {
FRUtils.FRLogInfo("添加mac匹配异常:"+e.getMessage());
}
return false;
}
//如果有并且匹配,查询状态并确定是否放行
boolean flag = false;
for(AuthUserMacEntity ame : authUserMac){
if(ame.getAuthstatus() == 0){
flag = true;
}
}
if(!flag){
return false;
}
}
String password = CipherUtils.jdksha256(psd);
User user = FRUtils.getFRUserByUserName(userName);
return password.equals(user.getPassword());
//
}
@Override
public boolean authorize(String s, String s1) {
return false;
}
private String getMac(){
String url = "http://localhost:9090/domain/getDomain";
String result = HttpUtils.get(url,null,null);
if(Utils.isNullStr(result)){
return "";
}
JSONObject json = new JSONObject(result);
boolean success = json.getBoolean("success");
if(!success){
return "";
}
return json.getString("domain");
}
}

11
src/main/java/com/fr/plugin/loginAuth/httpAuth/Test.java

@ -0,0 +1,11 @@
package com.fr.plugin.loginAuth.httpAuth;
import com.fr.plugin.loginAuth.utils.CipherUtils;
public class Test {
public static void main(String[] args) {
String a = "YL365XOEliTb47pFLn9fTw==";
System.out.println(CipherUtils.jdksha256("xiamaofa888"));
}
}

262
src/main/java/com/fr/plugin/loginAuth/utils/CipherUtils.java

@ -0,0 +1,262 @@
package com.fr.plugin.loginAuth.utils;
import com.fr.log.FineLoggerFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.SecureRandom;
/**
* 加解密工具类
*/
public class CipherUtils {
/**
* 加密
*
* @param datasource
* byte[]
* @param password
* String
* @return byte[]
*/
public static byte[] desEncrypt(byte[] datasource, String password) {
try {
SecureRandom random = new SecureRandom();
DESKeySpec desKey = new DESKeySpec(password.getBytes());
// 创建一个密匙工厂,然后用它把DESKeySpec转换成
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(desKey);
// Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密匙初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
// 现在,获取数据并加密
// 正式执行加密操作
return cipher.doFinal(datasource);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
/**
* 解密
*
* @param src
* byte[]
* @param password
* String
* @return byte[]
* @throws Exception
*/
public static byte[] desDecrypt(byte[] src, String password) throws Exception {
// DES算法要求有一个可信任的随机数源
SecureRandom random = new SecureRandom();
// 创建一个DESKeySpec对象
DESKeySpec desKey = new DESKeySpec(password.getBytes("UTF-8"));
// 创建一个密匙工厂
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// 将DESKeySpec对象转换成SecretKey对象
SecretKey securekey = keyFactory.generateSecret(desKey);
// Cipher对象实际完成解密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密匙初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, securekey, random);
// 真正开始解密操作
return cipher.doFinal(src);
}
/**
* 自定义一个key
**/
public static byte[] getKey(String keyRule) {
Key key = null;
byte[] keyByte = keyRule.getBytes();
// 创建一个空的八位数组,默认情况下为0
byte[] byteTemp = new byte[8];
// 将用户指定的规则转换成八位数组
for (int i = 0; i < byteTemp.length && i < keyByte.length; i++) {
byteTemp[i] = keyByte[i];
}
key = new SecretKeySpec(byteTemp, "DES");
return key.getEncoded();
}
/**
* 将16进制转换为二进制
*
* @param hexStr
* @return
*/
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1) return null;
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
/***
* 解密数据
* @param decryptString
* @param decryptKey
* @return
* @throws Exception
*/
public static String decryptDES(String decryptString, String decryptKey) throws Exception {
SecretKeySpec key = new SecretKeySpec(getKey(decryptKey), "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
byte decryptedData[] = cipher.doFinal(parseHexStr2Byte(decryptString));
return new String(decryptedData,"utf-8");
}
/**
* jdksha256加密
* @param str
* @return
*/
public static String jdksha256(String str)
{
String sha256Str = "";
try {
MessageDigest sha256Deget = MessageDigest.getInstance("SHA-256");
byte[] sha256Encode = sha256Deget.digest(str.getBytes());
sha256Str = ByteToHexStr(sha256Encode);
}catch (Exception e){
FineLoggerFactory.getLogger().info("FRLOG:SHA256加密异常:"+e.getMessage());
}
return sha256Str;
}
/**
* byte数组转16进制字符串
* @param bytes
* @return
*/
private static String ByteToHexStr(byte[] bytes)
{
String hexStr = "";
for(int i =0;i<bytes.length;i++)
{
int temp = bytes[i] & 0xff;
String tempHex = Integer.toHexString(temp);
if(tempHex.length() < 2)
{
hexStr += "0"+tempHex;
}
else {
hexStr += tempHex;
}
}
return hexStr;
}
/**
* base64加密
* @param key
* @return
*/
public static String base64Encode(String key){
return (new BASE64Encoder()).encodeBuffer(key.getBytes());
}
/**
* base64解密
* @param key
* @return
*/
public static String base64Decode(String key){
String result = "";
try {
result = new String((new BASE64Decoder()).decodeBuffer(key));
} catch (IOException e) {
FineLoggerFactory.getLogger().info("FRLOG:BASE64解密异常:"+e.getMessage());
}
return result;
}
public static String getBase64DecodeStr(String str){
if(str == null || str.isEmpty()){
return "";
}
String result = base64Decode(str);
return result.contains("base64")?result:str;
}
/**
* 是否被base64加密过
* @param str
* @return
*/
public static boolean isBase64(String str) {
if (str == null || str.trim().length() == 0) {
return false;
}
else {
if (str.length() % 4 != 0) {
return false;
}
char[] strChars = str.toCharArray();
for (char c:strChars) {
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')
|| c == '+' || c == '/' || c == '=') {
continue;
}
else {
return false;
}
}
return true;
}
}
public static void main(String[] args) throws Exception {
// String key = "z2bse2zh";
// String key = "ajshcjzj";
// String str = "男";
////
// byte[] a =desEncrypt(str.getBytes(),key);
//// System.out.println(new String(a));
// String a1 = new BASE64Encoder().encodeBuffer(a);
////
// System.out.println(a1);
////
//// byte[] b = desDecrypt(a,key);
//// System.out.println(new String(b));
//
// String key2 = "rdTK5iLsDFw=";
// byte[] b2 = desDecrypt(new BASE64Decoder().decodeBuffer(key2),"ajshcjzj");
// System.out.println(new String(b2));
// //密钥
// String key = "z2bse2zh";
// //解密数据
// String encryDate = "DF2DF0F837C38A1233A8B1255B0532E36E9D29052873B7F8707936C025E2FE368B0A8919A93C8869";
// String a = "ED33AD65CDBAEF49";
// String result = decryptDES(a, key);
//
// System.out.println("result:" + result);
// System.out.println("result2:"+new String(decrypt(result.getBytes(),key)));
}
}

158
src/main/java/com/fr/plugin/loginAuth/utils/FRUtils.java

@ -0,0 +1,158 @@
package com.fr.plugin.loginAuth.utils;
import com.fr.decision.authority.AuthorityContext;
import com.fr.decision.authority.data.User;
import com.fr.decision.webservice.login.LogInOutResultInfo;
import com.fr.decision.webservice.utils.DecisionServiceConstants;
import com.fr.decision.webservice.v10.login.LoginService;
import com.fr.decision.webservice.v10.login.event.LogInOutEvent;
import com.fr.decision.webservice.v10.user.UserService;
import com.fr.event.EventDispatcher;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.stable.query.QueryFactory;
import com.fr.stable.query.restriction.RestrictionFactory;
import com.fr.web.utils.WebUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;
public class FRUtils {
/**
* 判断用户是否存在
* @param userName
* @return
*/
public static boolean isUserExist(String userName){
if (StringUtils.isEmpty(userName)) {
return false;
} else {
try {
List var1 = AuthorityContext.getInstance().getUserController().find(QueryFactory.create().addRestriction(RestrictionFactory.eq("userName", userName)));
return var1 != null && !var1.isEmpty();
} catch (Exception var2) {
FineLoggerFactory.getLogger().error(var2.getMessage());
return false;
}
}
}
/**
* 判断是否登录FR
* @param req
* @return
*/
public static boolean isLogin(HttpServletRequest req){
return LoginService.getInstance().isLogged(req);
}
/**
* 帆软登录
* @param httpServletRequest
* @param httpServletResponse
* @param userName
* @param url
*/
public static void login(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,String userName,String url){
FineLoggerFactory.getLogger().info("FRLOG:用户名:"+userName);
FineLoggerFactory.getLogger().info("FRLOG:跳转链接:"+url);
//判断用户名是否为空
if(!Utils.isNullStr(userName)){
if(isUserExist(userName)){
String FRToken = "";
try {
HttpSession session = httpServletRequest.getSession(true);
FRToken = LoginService.getInstance().login(httpServletRequest, httpServletResponse, userName);
httpServletRequest.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME,FRToken);
session.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, FRToken);
EventDispatcher.fire(LogInOutEvent.LOGIN,new LogInOutResultInfo(httpServletRequest,httpServletResponse,userName,true));
FineLoggerFactory.getLogger().info("FRLOG:登陆成功!");
if(!Utils.isNullStr(url)){
httpServletResponse.sendRedirect(url);
}
} catch (Exception e) {
ResponseUtils.failedResponse(httpServletResponse,"登录异常,请联系管理员!");
FineLoggerFactory.getLogger().info("FRLOG:登录异常,请联系管理员!");
FineLoggerFactory.getLogger().info("FRLOGException:"+e.getMessage());
}
}else{
ResponseUtils.failedResponse(httpServletResponse,"用户在报表系统中不存在!");
FineLoggerFactory.getLogger().info("FRLOG:用户在报表系统中不存在!");
}
}else{
ResponseUtils.failedResponse(httpServletResponse,"用户名不能为空!");
FineLoggerFactory.getLogger().info("FRLOG:用户名不能为空!");
}
}
/**
*
* @param httpServletRequest
* @param httpServletResponse
*/
public static void logout(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse)
{
if(!isLogin(httpServletRequest)){
return ;
}
try {
LoginService.getInstance().logout(httpServletRequest,httpServletResponse);
} catch (Exception e) {
ResponseUtils.failedResponse(httpServletResponse,"登出异常,请联系管理员!");
FineLoggerFactory.getLogger().info("FRLOG:登出异常,请联系管理员!");
FineLoggerFactory.getLogger().info("FRLOGException:"+e.getMessage());
}
}
/**
* 打印FR日志
* @param message
*/
public static void FRLogInfo(String message){
FineLoggerFactory.getLogger().info("FRLOG:"+message);
}
/**
* 根据用户名获取用户信息
* @param userName
* @return
*/
public static User getFRUserByUserName(String userName){
try {
return UserService.getInstance().getUserByUserName(userName);
} catch (Exception e) {
FRLogInfo("获取用户信息异常:"+e.getMessage());
}
return null;
}
/**
* 解密FR密码
* @param password
* @return
*/
// public static String decryptFRPsd(String password){
// FRLogInfo("解密密码:"+password);
// return TransmissionTool.decrypt(password);
// }
/**
* 获取带参数的访问链接
* @return
*/
public static String getAllUrl(HttpServletRequest httpServletRequest){
return WebUtils.getOriginalURL(httpServletRequest);
}
}

300
src/main/java/com/fr/plugin/loginAuth/utils/FWLoginFilter.java

@ -0,0 +1,300 @@
package com.fr.plugin.loginAuth.utils;
import com.fr.data.NetworkHelper;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
import com.fr.decision.mobile.terminal.TerminalHandler;
import com.fr.decision.webservice.v10.login.LoginService;
import com.fr.general.ComparatorUtils;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.transform.ExecuteFunctionRecord;
import com.fr.plugin.transform.FunctionRecorder;
import com.fr.security.JwtUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.web.Device;
import com.fr.web.utils.WebUtils;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
/**
* 帆软登录拦截器
* 对接泛微统一认证
*/
@FunctionRecorder
public class FWLoginFilter extends AbstractGlobalRequestFilterProvider {
// 默认密钥信息
static String keyStr = "58A50618868F445AA96283532ACF8020";
static byte[] IVByte = {22, 45, 60, 97, 23, 33, 56, 9};// IVStr.getBytes();
static byte[] keyByte = Base64.getDecoder().decode("58A50618868F445AA96283532ACF8020");
/**
* 放行地址
*/
private static String[] paths = new String[]{
"/decision/remote/design",
"/WebReport/decision/login",
"/WebReport/decision/file",
"/WebReport/decision/resources",
"/WebReport/decision/system",
"/WebReport/index.html",
};
@Override
public String filterName() {
return "loginFilter";
}
@Override
public String[] urlPatterns() {
return new String[]{"/*"};
}
@Override
public void init(FilterConfig filterConfig) {
FineLoggerFactory.getLogger().info("泛微单点启动...");
super.init(filterConfig);
}
@Override
@ExecuteFunctionRecord
public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) {
try {
String authtokenDec = req.getParameter("authtoken");
if (StringUtils.isNotBlank(authtokenDec)) {
// 判断帆软是否已登录
if (isLogged(req)) {
filterChain.doFilter(req, res);
return;
}
String decode = decode(authtokenDec);
if (StringUtils.isNotBlank(decode)) {
FineLoggerFactory.getLogger().info("收到登录请求:{}", decode);
boolean safeCheck = SafeUtils.safeCheck2(decode);
if (safeCheck) {
JSONObject jsonObject = new JSONObject(decode);
String acount = jsonObject.getString("Account");
login(req, res, acount);
FineLoggerFactory.getLogger().info("登录成功:{}", acount);
}
}
}
filterChain.doFilter(req, res);
} catch (Exception var14) {
var14.printStackTrace();
printException2Frlog(var14);
try {
filterChain.doFilter(req, res);
} catch (IOException e) {
e.printStackTrace();
} catch (ServletException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
String test = "{\"Account\":\"8422\",\"Token\":\"a4fecb63135649819f517573924e75aa\"}";
JSONObject jsonObject = null;
jsonObject = new JSONObject(test);
String acount = jsonObject.getString("Account");
System.out.println(acount);
}
private static String decode(String str) {
//解密后结果
String dencryptStr = "";
try {
dencryptStr = new String((des3DecodeCBC(keyByte,
IVByte, Base64.getUrlDecoder().decode(str))), StandardCharsets.UTF_8);
return dencryptStr;
//例子的结果数据为 : {"Acount":"8422","TimeStamp":"1558661504"}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
/**
* @param key 密钥
* @param keyiv IV
* @param data Base64编码的密文
* @return 明文
* @throws Exception
* @Description CBC解密
* @author Shindo
* @date 2016年11月16日 上午10:13:49
*/
public static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data)
throws Exception {
Key deskey = null;
DESedeKeySpec spec = new DESedeKeySpec(key);
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
deskey = keyfactory.generateSecret(spec);
Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding");
IvParameterSpec ips = new IvParameterSpec(keyiv);
cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
byte[] bOut = cipher.doFinal(data);
return bOut;
}
/**
* 查询是否放行
*
* @param req
* @return
*/
private Boolean isSkipPath(HttpServletRequest req) {
// 获取当前地址
String requestUrl = req.getRequestURI();
for (String releasePath : FWLoginFilter.paths) {
if (requestUrl.indexOf(releasePath) == 0) {
return true;
}
}
return false;
}
/**
* 处理登出
*
* @param req
*/
private Boolean dealLoginOut(HttpServletRequest req, HttpServletResponse res) throws Exception {
String logoutRequest = req.getParameter("logoouta");
String logoutRequest1 = req.getParameter("logoutRequest");
if ((StringUtils.isNotBlank(logoutRequest) && "true".equals(logoutRequest)) || (StringUtils.isNotBlank(logoutRequest1))) {
// 清除登录标记
HttpSession session = req.getSession(true);
session.removeAttribute("weaver_login_type");
session.invalidate();
// 帆软退出登录
LoginService.getInstance().logout(req, res);
FineLoggerFactory.getLogger().error("12222退出登录--清空weaver session");
return true;
}
return false;
}
/**
* 重定向到决策中心
*
* @param res
* @param userName
*/
private void sendRedirect(HttpServletRequest req, HttpServletResponse res, String userName) {
HashMap hashMap = new HashMap();
hashMap.put("loginUser", userName);
hashMap.put("callBack", getURI(req));
try {
WebUtils.writeOutTemplate("com/fr/plugin/login/redirect.html", res, hashMap);
return;
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 重定向到泛微登录
*
* @param res
* @param userName
*/
private void sendRedirect1(HttpServletRequest req, HttpServletResponse res, String userName) {
HashMap hashMap = new HashMap();
hashMap.put("loginUser", userName);
hashMap.put("callBack", getURI(req));
try {
WebUtils.writeOutTemplate("com/fr/plugin/login/redirect1.html", res, hashMap);
return;
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取默认跳转链接
*
* @param req
* @return
*/
private String getURI(HttpServletRequest req) {
StringBuilder path = new StringBuilder();
path.append("http://").append(req.getServerName()).append(":").append(req.getServerPort()).append(req.getRequestURI());
Map<String, String[]> parameterMap = new HashMap<String, String[]>(req.getParameterMap());
parameterMap.remove("token");
parameterMap.remove("callBack");
String queryurl = StringUtils.EMPTY;
for (String x : parameterMap.keySet()) {
queryurl += x + "=" + parameterMap.get(x)[0] + "&";
}
if (parameterMap.size() != 0) {
path.append("?").append(queryurl.substring(0, queryurl.length() - 1));
}
return path.toString();
}
public boolean isLogged(HttpServletRequest req) {
return LoginService.getInstance().isLogged(req);
}
public static void printException2Frlog(Exception e) {
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
String s = writer.toString();
FineLoggerFactory.getLogger().error("错误:{}", s);
}
private String login(HttpServletRequest req, HttpServletResponse res, String username) throws Exception {
String token = LoginService.getInstance().login(req, res, username);
req.setAttribute("fine_auth_token", token);
FineLoggerFactory.getLogger().info("fr FrFilter is over with username is ###" + username);
return token;
}
private boolean checkTokenValid(HttpServletRequest req, String token, String currentUserName) {
try {
if (!ComparatorUtils.equals(currentUserName, JwtUtils.parseJWT(token).getSubject())) {
FineLoggerFactory.getLogger().info("username changed:" + currentUserName);
return false;
} else {
Device device = NetworkHelper.getDevice(req);
LoginService.getInstance().loginStatusValid(token, TerminalHandler.getTerminal(req, device));
return true;
}
} catch (Exception var5) {
return false;
}
}
@Override
public void destroy() {
super.destroy();
}
}

237
src/main/java/com/fr/plugin/loginAuth/utils/HttpUtils.java

@ -0,0 +1,237 @@
package com.fr.plugin.loginAuth.utils;
import com.fr.log.FineLoggerFactory;
import com.fr.third.org.apache.http.HttpEntity;
import com.fr.third.org.apache.http.HttpResponse;
import com.fr.third.org.apache.http.HttpStatus;
import com.fr.third.org.apache.http.NameValuePair;
import com.fr.third.org.apache.http.client.CookieStore;
import com.fr.third.org.apache.http.client.entity.UrlEncodedFormEntity;
import com.fr.third.org.apache.http.client.methods.HttpGet;
import com.fr.third.org.apache.http.client.methods.HttpPost;
import com.fr.third.org.apache.http.conn.ssl.NoopHostnameVerifier;
import com.fr.third.org.apache.http.entity.StringEntity;
import com.fr.third.org.apache.http.impl.client.BasicCookieStore;
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient;
import com.fr.third.org.apache.http.impl.client.HttpClients;
import com.fr.third.org.apache.http.impl.cookie.BasicClientCookie;
import com.fr.third.org.apache.http.message.BasicNameValuePair;
import com.fr.third.org.apache.http.ssl.SSLContexts;
import com.fr.third.org.apache.http.ssl.TrustStrategy;
import com.fr.third.org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import javax.servlet.http.Cookie;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
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.Set;
public class HttpUtils {
/**
* httpGet请求
* @param url
* @return
*/
public static String get(String url,Cookie[] cookies,Map<String,String> header){
FineLoggerFactory.getLogger().info("FRLOG:HttpUtils.get--url:"+url);
//创建httpClient
CloseableHttpClient httpclient = createHttpClient(cookies);
HttpGet getMethod = new HttpGet(url);
if(header != null && header.size() > 0){
Set<String> keySet = header.keySet();
for(String key : keySet){
getMethod.setHeader(key,header.get(key));
}
}
try {
HttpResponse response = httpclient.execute(getMethod);
FineLoggerFactory.getLogger().info("FRLOG:HttpUtils.get--status:"+response.getStatusLine().getStatusCode());
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
String returnResult = EntityUtils.toString(entity, "utf-8");
FineLoggerFactory.getLogger().info("FRLOG:HttpUtils.get--returnResult:"+returnResult);
return returnResult;
}
} catch (Exception e) {
FineLoggerFactory.getLogger().info("FRLOG:HttpUtils.get--exception:"+e.getMessage());
}
return "";
}
/**
* HttpPost请求
* @param postMethod
* @return
*/
private static String HttpPost(HttpPost postMethod){
CloseableHttpClient httpclient = createHttpClient(null);
try {
HttpResponse response = httpclient.execute(postMethod);
FineLoggerFactory.getLogger().info("FRLOG:HttpPost:status:"+response.getStatusLine().getStatusCode());
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
String returnResult = EntityUtils.toString(entity, "utf-8");
FineLoggerFactory.getLogger().info("FRLOG:HttpPost:returnResult:"+returnResult);
return returnResult;
}
} catch (Exception e) {
FineLoggerFactory.getLogger().info("FRLOG:HttpPost:exception:"+e.getMessage());
}
return "";
}
public static String HttpPostXML(String url, String xmlParam){
FineLoggerFactory.getLogger().info("FRLOG:HttpPostXML:url:"+url);
HttpPost postMethod = new HttpPost(url);
postMethod.setHeader("Content-type", "text/html");
HttpEntity entity2 = null;
try {
entity2 = new StringEntity(xmlParam);
} catch (UnsupportedEncodingException e) {
FineLoggerFactory.getLogger().info("FRLOG:HttpPostXML:参数异常:"+e.getMessage());
return "";
}
postMethod.setEntity(entity2);
return HttpPost(postMethod);
}
public static String HttpPostJson(String url, String param,Map<String,String> header){
FineLoggerFactory.getLogger().info("FRLOG:HttpPostJSON:url:"+url);
HttpPost postMethod = new HttpPost(url);
postMethod.setHeader("Content-Type","application/json");
if(header != null && header.size() > 0){
Set<String> keySet = header.keySet();
for(String key : keySet){
postMethod.setHeader(key,header.get(key));
}
}
if(!Utils.isNullStr(param)){
HttpEntity entity2 = null;
try {
entity2 = new StringEntity(param);
} catch (UnsupportedEncodingException e) {
FineLoggerFactory.getLogger().info("FRLOG:HttpPostJSON:参数异常:"+e.getMessage());
return "";
}
postMethod.setEntity(entity2);
}
return HttpPost(postMethod);
}
public static String HttpPostWWWForm(String url, Map<String,String> header,Map<String,String> param){
FineLoggerFactory.getLogger().info("FRLOG:HttpWWWForm:url:"+url);
HttpPost postMethod = new HttpPost(url);
if(header != null && header.size() > 0){
Set<String> keySet = header.keySet();
for(String key : keySet){
postMethod.setHeader(key,header.get(key));
}
}
if(param != null && param.size() > 0){
List<NameValuePair> params = new ArrayList<NameValuePair>(param.size());
for(Map.Entry<String,String> map : param.entrySet()){
params.add(new BasicNameValuePair(map.getKey(), map.getValue()));
}
try {
postMethod.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
} catch (UnsupportedEncodingException e) {
FineLoggerFactory.getLogger().info("FRLOG:HttpWWWForm:异常:"+e.getMessage());
return "";
}
}
return HttpPost(postMethod);
}
private static CloseableHttpClient createHttpClient(Cookie[] cookies){
SSLContext sslContext = null;
try {
sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
return true;
}
}).build();
} catch (NoSuchAlgorithmException e) {
FRUtils.FRLogInfo("createHttpClientException:"+e.getMessage());
} catch (KeyManagementException e) {
FRUtils.FRLogInfo("createHttpClientException:"+e.getMessage());
} catch (KeyStoreException e) {
FRUtils.FRLogInfo("createHttpClientException:"+e.getMessage());
}
CloseableHttpClient httpclient = null;
if(cookies != null && cookies.length > 0){
CookieStore cookieStore = cookieToCookieStore(cookies);
httpclient = HttpClients.custom().setSslcontext(sslContext).
setSSLHostnameVerifier(new NoopHostnameVerifier()).setDefaultCookieStore(cookieStore).build();
}
else{
httpclient = HttpClients.custom().setSslcontext(sslContext).
setSSLHostnameVerifier(new NoopHostnameVerifier()).build();
}
return httpclient;
}
/**
* cookies转cookieStore
* @param cookies
* @return
*/
public static CookieStore cookieToCookieStore(Cookie[] cookies){
CookieStore cookieStore = new BasicCookieStore();
if(cookies != null && cookies.length>0){
for(Cookie cookie : cookies){
BasicClientCookie cookie1 = new BasicClientCookie(cookie.getName(), cookie.getValue());
cookieStore.addCookie(cookie1);
}
}
return cookieStore;
}
}

96
src/main/java/com/fr/plugin/loginAuth/utils/ResponseUtils.java

@ -0,0 +1,96 @@
package com.fr.plugin.loginAuth.utils;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.web.utils.WebUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
public class ResponseUtils {
private static final int SUCCESS = 200;
private static final int FAILED = -1;
public static void successResponse(HttpServletResponse res, String body) {
response(res, body, SUCCESS);
}
public static void failedResponse(HttpServletResponse res, String body) {
response(res, body, FAILED);
}
private static void response(HttpServletResponse res, String body, int code) {
FRUtils.FRLogInfo("body:"+body+";code:"+code);
JSONObject object = new JSONObject();
PrintWriter pw;
try {
object.put("code", code);
object.put("data", body);
pw = WebUtils.createPrintWriter(res);
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
return;
}
res.setContentType("application/json;charset=utf-8");
String result = object.toString();
pw.println(result);
pw.flush();
pw.close();
}
public static void response(HttpServletResponse res,JSONObject json){
PrintWriter pw;
try {
pw = WebUtils.createPrintWriter(res);
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
return;
}
res.setContentType("application/json;charset=utf-8");
String result = json.toString();
pw.println(result);
pw.flush();
pw.close();
}
public static void responseXml(HttpServletResponse res,String xml){
PrintWriter pw;
try {
pw = WebUtils.createPrintWriter(res);
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
return;
}
res.setContentType("text/xml;charset=utf-8");
pw.println(xml);
pw.flush();
pw.close();
}
public static void setCSRFHeader(HttpServletResponse httpServletResponse){
httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE,HEAD,PUT,PATCH");
httpServletResponse.setHeader("Access-Control-Max-Age", "36000");
httpServletResponse.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,Authorization,authorization");
}
public static void responseJsonp(HttpServletRequest req, HttpServletResponse res, JSONObject json){
PrintWriter pw;
try {
pw = WebUtils.createPrintWriter(res);
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
return;
}
res.setContentType("text/javascript;charset=utf-8;charset=utf-8");
String result = json.toString();
String jsonp=req.getParameter("callback");
pw.println(jsonp+"("+result+")");
pw.flush();
pw.close();
}
}

338
src/main/java/com/fr/plugin/loginAuth/utils/SafeUtils.java

@ -0,0 +1,338 @@
package com.fr.plugin.loginAuth.utils;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.weaver.esb.spi.EsbManager;
import com.weaver.esb.spi.EsbService;
import com.weaver.esb.spi.RequestConfig;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* API 输入参数签名结果, 签名算法生成示例
* <p>
* 签名大体过程如下:
* <p>
* 1. 对所有API请求参数除去sign参数根据参数名称的ASCII码表的顺序排序
* foo:1, bar:2, foo_bar:3, foobar:4
* 排序后的顺序是
* bar:2, foo:1, foo_bar:3, foobar:4
* <p>
* 2. 将排序好的参数名和参数值拼装在一起根据上面的示例得到的结果为
* bar2foo1foo_bar3foobar4
* <p>
* 3. 用app的secret初始化HMAC_MD5算法后再进行摘要
* SecretKey secretKey = new SecretKeySpec(secret.getBytes(), "HmacMD5");
* Mac mac = Mac.getInstance(secretKey.getAlgorithm());
* mac.init(secretKey);
* bytes = mac.doFinal(bar2foo1foo_bar3foobar4.getBytes());
* <p>
* 4. 将摘要得到的字节流结果使用十六进制表示
* hex(helloworld.getBytes(utf-8)) = 68656C6C6F776F726C64
*/
public class SafeUtils {
public static boolean safeCheck2(String json) {
// ESB 服务地址
String serverUrl = "http://oa.haitian.com/";
// ESB 分配给产品的 AppKey, 进入 ESB 中心 "产品管理-安全设置" 可查看该产品的公共参数信息。
String appKey = "64caed2d-ab47-4116-b1be-6caec02a2fa1";
// ESB 中心 "产品管理-安全设置" 中 Secret Key
String sercetKey = "b9ff64a3c99e8f38a97f16f9514ddefc";
// 认证用户名,ESB 中心 "产品管理-安全设置" 中认证开启时必填指定加密方式后, 值为加密(username + timestamp),加密算法参照下面介绍
String userName = "admin";
// 认证密码,ESB 中心 "产品管理-安全设置" 中认证开启时必填指定加密方式后,值为加密(password + timestamp),加密算法参照下面介绍
String password = "admin";
// 加密方式
String encryption = "";
// 事件标识,支持URL传参、Header传参,优先以 URL 参数为准
String eventkey = "HT_HRM_LOGINVER";
JSONObject entries = new JSONObject(json);
// 请求参数(根据事件请求参数配置传入 JSON 或 XML 字符串)
// String params = "{\"rygh\":\"11809\",\"ryuid\":\"e0d8733f009749498f4e44b098dda271\"}";
// 请求参数(根据事件请求参数配置传入 JSON 或 XML 字符串)
String account = entries.getString("Account");
String token = entries.getString("Token");
String params = String.format("{\"rygh\":\"%s\",\"ryuid\":\"%s\"}", account, token);
RequestConfig requestConfig = new RequestConfig();
requestConfig.setAppKey(appKey);
requestConfig.setServerUrl(serverUrl);
requestConfig.setSign(true); // 启用签名
requestConfig.setSercetKey(sercetKey);
requestConfig.setUserName(userName); // 认证用户名,通过 SDK 调用无需加密,SDK 将根据加密方式自动加密
requestConfig.setPassword(password); // 认证密码,通过 SDK 调用无需加密,SDK 将根据加密方式自动加密
requestConfig.setEncryption(encryption);
FineLoggerFactory.getLogger().info("请求的params:{}", params);
EsbService service = EsbManager.getService("http", requestConfig); // 获取 ESB 服务
String response = service.execute(eventkey, params); // 触发 ESB 事件
System.out.println(response);
FineLoggerFactory.getLogger().info("请求响应的2json:{}", response);
try {
JSONObject jsonObject = new JSONObject(response);
int code1 = jsonObject.getInt("code");
if (code1 == 100) {
JSONObject data = jsonObject.getJSONObject("data");
String code = data.getString("data");
return StringUtils.equals(code, "true");
}
}catch (Exception exception){
exception.printStackTrace();
}
return false;
}
public static boolean safeCheck(String json) {
JSONObject entries = new JSONObject(json);
// ESB 分配给产品的 AppKey, 进入 ESB 中心 "产品管理-安全设置" 可查看该产品的公共参数信息。
String appKey = "64caed2d-ab47-4116-b1be-6caec02a2fa1";
// 认证用户名,ESB 中心 "产品管理-安全设置" 中认证开启时必填指定加密方式后, 值为加密(username + timestamp),加密算法参照下面介绍
String username = "admin";
// 认证密码,ESB 中心 "产品管理-安全设置" 中认证开启时必填指定加密方式后,值为加密(password + timestamp),加密算法参照下面介绍
String password = "admin";
// 时间戳,精确到毫秒,时区需与 ESB 中心所在服务器的一致,ESB API 允许客户端最大时间误差为 15 分钟
String timestamp = System.currentTimeMillis() + "";
// 事件标识,支持URL传参、Header传参,优先以 URL 参数为准
String eventkey = "HT_HRM_LOGINVER";
// 请求参数(根据事件请求参数配置传入 JSON 或 XML 字符串)
String account = entries.getString("Account");
String token = entries.getString("Token");
String params = String.format("{\"rygh\":\"%s\",\"ryuid\":\"%s\"}", account, token); // "{}"
// 响应格式。默认为事件配置的数据格式,可选值:xml,json。
String format = "json";
Map<String, String> map = new HashMap<String, String>();
map.put("appkey", appKey);
map.put("timestamp", timestamp);
map.put("username", username);
map.put("password", password);
map.put("eventkey", eventkey);
map.put("format", format);
map.put("params", params);
// ESB 中心 "产品管理-安全设置" 中 Secret Key
String secret = "b9ff64a3c99e8f38a97f16f9514ddefc";
// API 输入参数签名结果
String sign = sign(map, secret);
FineLoggerFactory.getLogger().info("timestamp:{} ", timestamp);
FineLoggerFactory.getLogger().info("sign:" + sign);
FineLoggerFactory.getLogger().info("请求的参数 :{}", map);
String url = "http://oa.haitian.com/api/esb/execute" + map2Url(map);
FineLoggerFactory.getLogger().info("请求的URL :{}", url);
String resp = fakePost(url);
FineLoggerFactory.getLogger().info("请求响应的json:{}", resp);
JSONObject jsonObject = new JSONObject(resp);
int code1 = jsonObject.getInt("code");
if (code1 == 100) {
JSONObject data = jsonObject.getJSONObject("data");
String code = data.getString("code");
return StringUtils.equals(code, "0");
}
return false;
}
public static void main(String[] args) {
// ESB 服务地址
String serverUrl = "http://oa.haitian.com/";
// ESB 分配给产品的 AppKey, 进入 ESB 中心 "产品管理-安全设置" 可查看该产品的公共参数信息。
String appKey = "64caed2d-ab47-4116-b1be-6caec02a2fa1";
// ESB 中心 "产品管理-安全设置" 中 Secret Key
String sercetKey = "b9ff64a3c99e8f38a97f16f9514ddefc";
// 认证用户名,ESB 中心 "产品管理-安全设置" 中认证开启时必填指定加密方式后, 值为加密(username + timestamp),加密算法参照下面介绍
String userName = "admin";
// 认证密码,ESB 中心 "产品管理-安全设置" 中认证开启时必填指定加密方式后,值为加密(password + timestamp),加密算法参照下面介绍
String password = "admin";
// 加密方式
String encryption = "";
// 事件标识,支持URL传参、Header传参,优先以 URL 参数为准
String eventkey = "HT_HRM_LOGINVER";
// 请求参数(根据事件请求参数配置传入 JSON 或 XML 字符串)
String params = "{\"rygh\":\"8422\",\"ryuid\":\"a4fecb63135649819f517573924e75aa\"}";
RequestConfig requestConfig = new RequestConfig();
requestConfig.setAppKey(appKey);
requestConfig.setServerUrl(serverUrl);
requestConfig.setSign(true); // 启用签名
requestConfig.setSercetKey(sercetKey);
requestConfig.setUserName(userName); // 认证用户名,通过 SDK 调用无需加密,SDK 将根据加密方式自动加密
requestConfig.setPassword(password); // 认证密码,通过 SDK 调用无需加密,SDK 将根据加密方式自动加密
requestConfig.setEncryption(encryption);
EsbService service = EsbManager.getService("http", requestConfig); // 获取 ESB 服务
String response = service.execute(eventkey, params); // 触发 ESB 事件
System.out.println(response);
}
private static String map2Url(Map<String, String> map) {
StringBuffer buffer = new StringBuffer("?");
Set<String> keySet = map.keySet();
for (String key : keySet) {
try {
buffer.append(key).append("=").append(URLEncoder.encode(map.get(key), StandardCharsets.UTF_8.toString())).append("&");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return buffer.toString();
}
/**
* get请求方式
*
* @param path
* @return
*/
private static String fakePost(String path) {
StringBuffer buffer = new StringBuffer();
try {
URL url = new URL(path);
//打开和url之间的连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
conn.setRequestProperty("Accept-Charset", "UTF-8");
conn.setRequestMethod("POST");
conn.connect();
//构造一个字符流缓存
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(new String(line.getBytes(), "UTF-8"));
}
//关闭流
reader.close();
conn.disconnect();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return buffer.toString();
}
//
// public static void main(String args[]) {
// // ESB 分配给产品的 AppKey, 进入 ESB 中心 "产品管理-安全设置" 可查看该产品的公共参数信息。
// String appKey = "64caed2d-ab47-4116-b1be-6caec02a2fa1";
// // 认证用户名,ESB 中心 "产品管理-安全设置" 中认证开启时必填指定加密方式后, 值为加密(username + timestamp),加密算法参照下面介绍
// String username = "admin";
// // 认证密码,ESB 中心 "产品管理-安全设置" 中认证开启时必填指定加密方式后,值为加密(password + timestamp),加密算法参照下面介绍
// String password = "admin";
// // 时间戳,精确到毫秒,时区需与 ESB 中心所在服务器的一致,ESB API 允许客户端最大时间误差为 15 分钟
// String timestamp = System.currentTimeMillis() + "";
// // 事件标识,支持URL传参、Header传参,优先以 URL 参数为准
// String eventkey = "HT_HRM_LOGINVER";
// // 请求参数(根据事件请求参数配置传入 JSON 或 XML 字符串)
// String params = "{\"rygh\":\"11809\",\"ryuid\":\"e0d8733f009749498f4e44b098dda271\"}"; // "{}"
// // 响应格式。默认为事件配置的数据格式,可选值:xml,json。
// String format = "json";
//
// Map<String, String> map = new HashMap<String, String>();
// map.put("appkey", appKey);
// map.put("timestamp", timestamp);
// map.put("username", username);
// map.put("password", password);
// map.put("eventkey", eventkey);
// map.put("format", format);
// map.put("params", params);
//
// // ESB 中心 "产品管理-安全设置" 中 Secret Key
// String secret = "b9ff64a3c99e8f38a97f16f9514ddefc";
//
// // API 输入参数签名结果
// String sign = sign(map, secret);
//
// System.out.println("timestamp: " + timestamp);
// System.out.println("sign:" + sign);
// }
public static String sign(Map<String, String> params, String secret) {
// 第一步:检查参数是否已经排序
String[] keys = params.keySet().toArray(new String[0]);
Arrays.sort(keys);
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder();
for (String key : keys) {
if (key != null && !key.isEmpty()) {
String value = params.get(key);
if (value != null && !value.isEmpty()) {
query.append(key).append(value);
}
}
}
// 第三步:使用HMAC加密
byte[] bytes = encryptHMAC(query.toString(), secret);
// 第四步:把二进制转化为大写的十六进制(正确签名应该为32大写字符串,此方法需要时使用)
return byte2hex(bytes);
}
/**
* 使用HMAC加密
*
* @param data
* @param secret
* @return
*/
private static byte[] encryptHMAC(String data, String secret) {
byte[] bytes = null;
try {
SecretKey secretKey = new SecretKeySpec(secret.getBytes(), "HmacMD5");
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);
bytes = mac.doFinal(data.getBytes());
} catch (Exception e) {
}
return bytes;
}
/**
* 二进制转化为大写的十六进制
*
* @param bytes
* @return
*/
private static String byte2hex(byte[] bytes) {
StringBuilder sign = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xFF);
if (hex.length() == 1) {
sign.append("0");
}
sign.append(hex.toUpperCase());
}
return sign.toString();
}
}

96
src/main/java/com/fr/plugin/loginAuth/utils/Utils.java

@ -0,0 +1,96 @@
package com.fr.plugin.loginAuth.utils;
import com.fr.json.JSONObject;
import com.fr.stable.CodeUtils;
import com.fr.third.org.apache.commons.codec.digest.DigestUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.util.UUID;
public class Utils {
/**
* 判断字符串是否为空
* @param str
* @return true 空字符串 false 非空字符串
*/
public static boolean isNullStr(String str){
return !(str != null && !str.isEmpty() && !"null".equals(str));
}
/**
* 判断字符串是否非空
* @param str
* @return
*/
public static boolean isNotNullStr(String str){
return !isNullStr(str);
}
/**
* MD5加密
* @param str
* @return
*/
public static String getMd5Str(String str)
{
return DigestUtils.md5Hex(str);
}
/**
* 获取完整的访问路径
*/
public static String getAllUrl(HttpServletRequest req, String queryStr){
String url = req.getRequestURL().toString();
if(isNullStr(queryStr)){
return url;
}
return url+"?"+queryStr;
}
/**
* 帆软shaEncode加密
*/
public static String shaEncode(String str){
return CodeUtils.sha256Encode(str);
}
/**
* 获取uuid
*/
public static String uuid(){
return UUID.randomUUID().toString();
}
public static String replaceNullStr(String str,String replace){
if(isNullStr(str)){
return replace;
}
return str;
}
public static JSONObject getRequestBody(HttpServletRequestWrapper req){
StringBuffer sb = new StringBuffer();
String line = null;
try {
BufferedReader reader = req.getReader();
while ((line = reader.readLine()) != null)
sb.append(line);
} catch (Exception e) {
FRUtils.FRLogInfo("getRequestBody:exception:"+e.getMessage());
}
//将空格和换行符替换掉避免使用反序列化工具解析对象时失败
String jsonString = sb.toString().replaceAll("\\s","").replaceAll("\n","");
JSONObject json = new JSONObject(jsonString);
return json;
}
}

35
src/main/java/com/fr/plugin/loginAuth/webresource/WebResourceProvider.java

@ -0,0 +1,35 @@
package com.fr.plugin.loginAuth.webresource;
import com.fr.decision.fun.impl.AbstractWebResourceProvider;
import com.fr.decision.web.LoginComponent;
import com.fr.web.struct.Atom;
import com.fr.web.struct.Component;
import com.fr.web.struct.browser.RequestClient;
import com.fr.web.struct.category.ScriptPath;
import com.fr.web.struct.category.StylePath;
/**
* Created by zhouping on 2019/1/16.
*/
public class WebResourceProvider extends AbstractWebResourceProvider {
@Override
public Atom attach() {
return LoginComponent.KEY;
}
@Override
public Atom client() {
return new Component() {
@Override
public ScriptPath script(RequestClient requestClient) {
return ScriptPath.build("/com/fr/plugin/loginAuth/js/login.js");
}
@Override
public StylePath style(RequestClient requestClient) {
return StylePath.EMPTY;
// return StylePath.build("/com/fr/plugin/jdfSSO/css/icon.css");
}
};
}
}

37
src/main/resources/com/fr/plugin/loginAuth/html/getMac.html

@ -0,0 +1,37 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>cli3demo</title>
<script type="text/javascript" src="${path}/file?path=/com/fr/plugin/loginAuth/html/jquery-2.1.3.min.js" ></script>
<!-- <script type="text/javascript" src="/webroot/decision/file?path=/com/fr/plugin/login/html/jquery-2.1.3.min.js" ></script>-->
<script type="text/javascript">
$(function(){
var url = $("#url").val();
var mac = getMac();
url = url+'&mac='+mac;
window.location.href = url;
})
function getMac(){
var mac = "none";
$.ajax({
type:"get",
async:false,
url:"http://localhost:9090/domain/getDomain",
success:function(data){
mac = data.domain;
}
})
return mac;
}
</script>
</head>
<body>
<input type="hidden" id="url" value="${url}">
</body>
</html>

4
src/main/resources/com/fr/plugin/loginAuth/html/jquery-2.1.3.min.js vendored

File diff suppressed because one or more lines are too long

29
src/main/resources/com/fr/plugin/loginAuth/js/login.html

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=${charset}">
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>${title}</title>
<!--css文件-->
${styleTag}
</head>
<body>
<div id="wrapper"></div>
<script type="text/javascript">
window.Dec = window.Dec || {};
window.Dec.injection = window.Dec.injection || {};
</script>
<script type="text/javascript">
Dec.fineServletURL = "${fineServletURL}";
Dec.loginConfig = ${loginConfig};
Dec.system = ${system};
</script>
${scriptTag}
<script>
Dec.start();
</script>
</body>
</html>

333
src/main/resources/com/fr/plugin/loginAuth/js/login.js

@ -0,0 +1,333 @@
var t = "default_fail",
e = BI.inherit(BI.OB, {
init: function () {
this.failMap = {},
this._initErrorHandler()
},
addHandler: function (e, t) {
this.failMap[e] = t
},
getHandler: function (e) {
return BI.isFunction(this.failMap[e]) ? this.failMap[e] : this.failMap[t]
},
_initErrorHandler: function () {
this.failMap[DecCst.ErrorCode.USER_LOGGED] = function (e) {
this.store.setPropsInfo({
token: e.errorMsg,
isChangePwd: !0,
from: DecCst.Login.AuthenticationModule.SINGLE
}),
this.store.setNeedSlider(!1),
this.loginErrorRow.visible()
},
this.failMap[DecCst.ErrorCode.USER_LOGGED_CAN_NOT_CHANGE_PASSWORD] = function () {
this.store.setNeedSlider(!1),
this.loginNormalErrorRow.visible()
},
this.failMap[DecCst.ErrorCode.USERNAME_UNAVAILABLE] = function () {
this.usernameRow.showError(BI.i18nText("Dec-Error_Login_Username_Unable"))
},
this.failMap[DecCst.ErrorCode.USERNAME_NOT_EXIST_PASSWORD_ERROR] = function () {
this.passwordRow.showError(BI.i18nText("Dec-Error_Incorrect_Password_Username"))
},
this.failMap[90000] = function () {
this.passwordRow.showError("您的电脑未授权,请联系管理员。")
},
this.failMap[DecCst.ErrorCode.SMS_CAPTCHA_UNCHECK] = function (e) {
this.store.setPropsInfo({
token: e.errorMsg,
isChangePwd: !1,
from: DecCst.Login.AuthenticationModule.LOGIN
}),
this.store.setSelectedTab(DecCst.Login.Tabs.VERIFY_BING)
},
this.failMap[DecCst.ErrorCode.PASSWORD_NEED_SPLIDER] = function () {
this.store.setNeedSlider(!0),
this.sliderBar.resetAll()
},
this.failMap[DecCst.ErrorCode.PASSWORD_LOCKED] = function (e) {
this.store.setPropsInfo({
errorMsg: e.errorMsg
}),
this.store.setSelectedTab(DecCst.Login.Tabs.LOCKED)
},
this.failMap[DecCst.ErrorCode.PASSWORD_NEED_UPDATE] = function (e) {
this.store.setPropsInfo({
token: e.errorMsg,
isChangePwd: !0,
from: DecCst.Login.AuthenticationModule.PWD_UPDATE
}),
this.model.isNeedVerify ? this.store.setSelectedTab(DecCst.Login.Tabs.VERIFY_BING) : this.store.setSelectedTab(DecCst.Login.Tabs.PASSWORD_OLD)
},
this.failMap[DecCst.ErrorCode.PASSWORD_STRENGTH] = function (e) {
this.store.setPropsInfo({
token: e.errorMsg,
isChangePwd: !0,
from: DecCst.Login.AuthenticationModule.PWD_STRENGTH
}),
this.model.isNeedVerify ? this.store.setSelectedTab(DecCst.Login.Tabs.VERIFY_BING) : this.store.setSelectedTab(DecCst.Login.Tabs.PASSWORD_OLD)
},
this.failMap[DecCst.ErrorCode.CAPTCHA_TIMEOUT] = function () {
this.sliderError.setText(BI.i18nText("Dec-Basic_Captcha_Timeout")),
this.sliderBar.resetAll()
},
this.addHandler(t, function () {
this.passwordRow.showError(BI.i18nText("Dec-Login_Fail"))
})
}
});
BI.service("dec.service.login.login", e)
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.left_right_vertical_adapt",
bgap: 30,
items: {
left: [{
type: "bi.multi_select_item",
$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
}
}
],
right: [{
type: "bi.button",
$testId: "dec-login-forget-password",
clear: !0,
height: 16,
invisible: !this.model.supportForgetPwd,
text: BI.i18nText("Dec-Basic_Forget_Password"),
ref: function (e) {
t.forgetPasswordRow = e
},
handler: function () {
t.store.setSelectedTab(DecCst.Login.Tabs.FORGET_PASSWORD)
}
}
].concat(this._createItems())
}
}, {
type: "bi.horizontal_auto",
items: [{
type: "bi.button",
cls: "login-button",
text: BI.i18nText("Dec-Basic_Login"),
width: 190,
height: 40,
handler: function () {
t._start()
}
}
]
}, {
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) {
console.info(e);
console.info(BI.Services.getService("dec.service.login.login").getHandler(e.errorCode));
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.login", e)
Dec.Utils.login = function(v,callback){
console.info(callback);
console.info("登录方法注入!");
var mac = getMac();
console.info(mac);
console.info(Dec.fineServletURL);
$.ajax({
type: 'POST',
url: Dec.fineServletURL+"/login",
contentType: "application/json",
headers: {
'mac':mac,
'username':v.username
},
data: JSON.stringify(v),
dataType:'json',
success: callback
});
// Dec.reqPost("/login",v,callback);
}
function getMac(){
var mac = "";
$.ajax({
type:"get",
async:false,
url:"http://localhost:9090/domain/getDomain",
success:function(data){
mac = data.domain;
}
})
return mac;
}

15
src/main/resources/com/fr/plugin/loginAuth/login/redirect.html

@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<script type="text/javascript">
let loginUser = '${loginUser}';
// if(loginUser && loginUser === "" ){
// alert("用户"+loginUser+"未关联到帆软用户体系!")
// }
// 重定向到决策中心
window.location.href = '${callBack}';
</script>
</head>
<body>
</body>
</html>

18
src/main/resources/com/fr/plugin/loginAuth/login/redirect1.html

@ -0,0 +1,18 @@
<!doctype html>
<html lang="en">
<head>
<script type="text/javascript">
let loginUser = '${loginUser}';
if(loginUser && loginUser !== "" ){
alert("用户"+loginUser+"未关联到帆软用户体系!")
}
// 重定向到泛微登录页
// http://61.163.80.101:55580/wui/index.html#/?appid=fr&service=http%3A%2F%2F127.0.0.1%3A8088%2Fwebroot%2Fdecision%2Flogin%3Bjsessionid%3D87E6EAA5F78D2EAD4BDC085FFAE2D2BA%3Forigin%3Db27caec4-cae8-4c57-9cc9-29bd8ef27148&_key=bvxibe
let url = "http://61.163.80.101:55580/wui/index.html#/?appid=fr";
url += "&service=" + '${callBack}';
window.location.href = url;
</script>
</head>
<body>
</body>
</html>

66
src/main/resources/com/fr/plugin/loginAuth/logout/logout2.js

@ -0,0 +1,66 @@
(function () {
if (typeof docCookies == "undefined") {
docCookies = {
getItem: function (sKey) {
return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
},
setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) {
return false;
}
var sExpires = "";
if (vEnd) {
switch (vEnd.constructor) {
case Number:
sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd;
break;
case String:
sExpires = "; expires=" + vEnd;
break;
case Date:
sExpires = "; expires=" + vEnd.toUTCString();
break;
}
}
document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
return true;
},
removeItem: function (sKey, sPath, sDomain) {
if (!sKey || !this.hasItem(sKey)) {
return false;
}
document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "");
return true;
},
hasItem: function (sKey) {
return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
}
};
}
Dec.Utils = Dec.Utils || {};
BI.extend(Dec.Utils, {
logout: function (e) {
Dec.reqPostHandle("/logout", {}, e);
Dec.reqPostHandle("/logout?logoouta=true", {}, BI.emptyFn)
}
});
/**
* 产品中的 account.constant.js 中调用了 Dec.Logout所以覆盖 Dec.Logout 即可
*/
Dec.Logout = function () {
// data 是 /logout 接口返回的数据
Dec.Utils.logout(function (data) {
BI.Cache.deleteCookie(DecCst.Cookie.TOKEN, Dec.system.cookiePath);
BI.Cache.deleteCookie("fine_login_users", Dec.system.cookiePath);
BI.Cache.deleteCookie("confSessionId", "/WebReport");
var noIdmCookie = docCookies.getItem("no-idm");
if (noIdmCookie === "true") {
window.location.href = data;
} else {
window.location.href = "http://61.163.80.101:55581/cas/logout"
// window.location.href = "http://61.163.80.101:55580/sso/logout?service=" + encodeURIComponent("http://61.163.80.101:55580/sso/login?appid=fr&service=" + encodeURIComponent("http://61.163.80.102:8088/WebReport/index.html"));
}
});
};
})();

BIN
使用手册.docx

Binary file not shown.
Loading…
Cancel
Save