├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── ki4so-app ├── .gitignore ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── github │ │ └── ebnew │ │ └── ki4so │ │ └── app │ │ ├── custom │ │ ├── AppClientLoginHandler.java │ │ └── AppClientLogoutHandlerImpl.java │ │ └── web │ │ └── action │ │ └── HomeAction.java │ ├── resources │ └── spring │ │ ├── spring-beans.xml │ │ └── springmvc-config.xml │ └── webapp │ ├── META-INF │ ├── MANIFEST.MF │ └── context.xml │ ├── WEB-INF │ ├── pages │ │ └── home.jsp │ └── web.xml │ └── index.jsp ├── ki4so-common ├── pom.xml └── src │ ├── main │ └── java │ │ ├── META-INF │ │ └── MANIFEST.MF │ │ └── com │ │ └── github │ │ └── ebnew │ │ └── ki4so │ │ ├── common │ │ ├── KnightBase64Coder.java │ │ ├── KnightDECoder.java │ │ └── utils │ │ │ └── StringUtils.java │ │ ├── core │ │ ├── app │ │ │ └── KnightApp.java │ │ ├── authentication │ │ │ ├── KnightAbstractParameter.java │ │ │ ├── KnightCredential.java │ │ │ ├── KnightEncryCredential.java │ │ │ ├── KnightEncryCredentialManager.java │ │ │ ├── KnightEncryCredentialManagerImpl.java │ │ │ └── KnightParameter.java │ │ ├── exception │ │ │ ├── AuthenticationException.java │ │ │ ├── EmptyCredentialException.java │ │ │ ├── InvalidCredentialException.java │ │ │ ├── InvalidEncryCredentialException.java │ │ │ ├── NoAuthenticationPostHandlerException.java │ │ │ ├── NoKi4soKeyException.java │ │ │ ├── ParamsNotInitiatedCorrectly.java │ │ │ ├── PasswordInvalidException.java │ │ │ ├── UnsupportedCredentialsException.java │ │ │ ├── UsernameInvalidException.java │ │ │ ├── UsernameOrPasswordEmptyException.java │ │ │ └── UsernameOrPasswordInvalidException.java │ │ ├── key │ │ │ ├── KnightKey.java │ │ │ └── KnightKeyService.java │ │ └── model │ │ │ └── KnightCredentialInfo.java │ │ └── web │ │ └── utils │ │ └── WebConstants.java │ └── test │ └── java │ └── com │ └── github │ └── ebnew │ └── ki4so │ ├── common │ ├── Base64CoderTest.java │ └── DESCoderTest.java │ └── core │ └── authentication │ └── EncryCredentialManagerImplTest.java ├── ki4so-core ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ ├── META-INF │ │ │ └── MANIFEST.MF │ │ ├── README.md │ │ └── com │ │ │ └── github │ │ │ └── ebnew │ │ │ └── ki4so │ │ │ └── core │ │ │ ├── app │ │ │ ├── KnightAppService.java │ │ │ └── KnightAppServiceImpl.java │ │ │ ├── authentication │ │ │ ├── AbstractKnightUser.java │ │ │ ├── DefaultKnightUser.java │ │ │ ├── KnightAuthentication.java │ │ │ ├── KnightAuthenticationImpl.java │ │ │ ├── KnightAuthenticationManager.java │ │ │ ├── KnightAuthenticationManagerImpl.java │ │ │ ├── KnightAuthenticationPostHandler.java │ │ │ ├── KnightDefaultAuthenticationPostHandler.java │ │ │ ├── KnightNamePasswordCredential.java │ │ │ ├── KnightUser.java │ │ │ ├── handlers │ │ │ │ ├── AbstractPreAndPostProcessingAuthenticationHandler.java │ │ │ │ ├── AbstractUsernamePasswordAuthenticationHandler.java │ │ │ │ ├── AuthenticationHandler.java │ │ │ │ ├── DefaultPasswordEncoder.java │ │ │ │ ├── EncryCredentialAuthenticationHandler.java │ │ │ │ ├── PasswordEncoder.java │ │ │ │ ├── PlainTextPasswordEncoder.java │ │ │ │ └── SimpleTestUsernamePasswordAuthenticationHandler.java │ │ │ ├── resolvers │ │ │ │ ├── CredentialToPrincipalResolver.java │ │ │ │ ├── EncryCredentialToPrincipalResolver.java │ │ │ │ └── UsernamePasswordCredentialToPrincipalResolver.java │ │ │ └── status │ │ │ │ ├── KnightDefaultUserLoginStatusStore.java │ │ │ │ ├── KnightUserLoggedStatusStore.java │ │ │ │ └── KnightUserLoginStatus.java │ │ │ ├── dao │ │ │ └── fs │ │ │ │ └── KnightFileSystemDao.java │ │ │ ├── key │ │ │ ├── KnightKeyServiceImpl.java │ │ │ └── KnightRSASecurityUtil.java │ │ │ ├── message │ │ │ └── MessageUtils.java │ │ │ └── service │ │ │ ├── KnightService.java │ │ │ ├── KnightServiceImpl.java │ │ │ ├── LoginResult.java │ │ │ ├── LogoutAppService.java │ │ │ ├── LogoutAppServiceImpl.java │ │ │ └── LogoutService.java │ └── resources │ │ ├── apps.js │ │ ├── keys.js │ │ └── log4j.properties │ └── test │ └── java │ ├── META-INF │ └── MANIFEST.MF │ ├── README.md │ └── com │ └── github │ └── ebnew │ └── ki4so │ └── core │ ├── TestUtils.java │ ├── authentication │ ├── AuthenticationManagerImplTest.java │ ├── DefaultAuthenticationPostHandlerTest.java │ ├── EncryCredentialManagerImplTest.java │ ├── app │ │ └── AppServiceImplTest.java │ ├── handlers │ │ ├── DefaultPasswordEncoderTests.java │ │ ├── EncryCredentialAuthenticationHandlerTest.java │ │ ├── PlainTextPasswordEncoderTests.java │ │ └── SimpleTestUsernamePasswordHandlerTests.java │ ├── key │ │ └── KeyServiceImplTest.java │ ├── resolvers │ │ ├── EncryCredentialToPrincipalResolverTest.java │ │ └── UsernamePasswordCredentialToPrincipalResolverTest.java │ └── status │ │ └── DefaultUserLoggedStatusStoreTest.java │ ├── message │ └── MessageUtilsTest.java │ └── service │ ├── Ki4soServiceTest.java │ └── LogoutAppServiceTest.java ├── ki4so-java-client ├── .gitignore ├── pom.xml └── src │ └── main │ ├── java │ ├── META-INF │ │ └── MANIFEST.MF │ └── com │ │ └── github │ │ └── ebnew │ │ └── ki4so │ │ └── client │ │ ├── handler │ │ ├── KnightAppClientLoginHandler.java │ │ └── KnightAppClientLogoutHandler.java │ │ ├── key │ │ └── DefaultKeyServiceImpl.java │ │ ├── session │ │ └── SessionStorage.java │ │ └── web │ │ └── filters │ │ ├── BaseClientFilter.java │ │ ├── Ki4soClientLogoutFilter.java │ │ ├── KnightClientFilter.java │ │ └── KnightGeneratePrivateKeyFilter.java │ └── resources │ └── keySecurity.properties ├── ki4so-jdbc ├── pom.xml └── src │ └── main │ └── java │ ├── META-INF │ └── MANIFEST.MF │ └── com │ └── github │ └── ebnew │ └── ki4so │ └── core │ └── authentication │ └── handlers │ └── jdbc │ ├── AbstractJdbcUsernamePasswordAuthenticationHandler.java │ ├── QueryDatabaseAuthenticationHandler.java │ └── SearchModeSearchDatabaseAuthenticationHandler.java ├── ki4so-web ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ ├── README.md │ │ └── com │ │ │ └── github │ │ │ └── ebnew │ │ │ └── ki4so │ │ │ └── web │ │ │ └── action │ │ │ ├── KeyAction.java │ │ │ ├── KnightAbstractParameterCredentialResolver.java │ │ │ ├── KnightAbstractPreAndPostProcessingCredentialResolver.java │ │ │ ├── KnightCompositeCredentialResolver.java │ │ │ ├── KnightCredentialResolver.java │ │ │ ├── KnightEncryCredentialResolver.java │ │ │ ├── KnightLoginResultToView.java │ │ │ ├── KnightUsernamePasswordCredentialResolver.java │ │ │ ├── KnigtDefaultLoginResultToView.java │ │ │ ├── LoginAction.java │ │ │ ├── LoginResultToView.java │ │ │ └── LogoutAction.java │ ├── resources │ │ ├── log4j.properties │ │ └── spring │ │ │ ├── spring-beans.xml │ │ │ └── springmvc-config.xml │ └── webapp │ │ ├── META-INF │ │ ├── MANIFEST.MF │ │ └── context.xml │ │ ├── WEB-INF │ │ ├── pages │ │ │ ├── login.jsp │ │ │ ├── loginSucess.jsp │ │ │ └── logoutSucess.jsp │ │ └── web.xml │ │ ├── index.jsp │ │ └── js │ │ └── jquery-1.4.2.min.js │ └── test │ └── java │ ├── README.md │ └── com │ └── github │ └── ebnew │ └── ki4so │ └── web │ └── action │ ├── CompositeCredentialResolverTest.java │ ├── DefaultLoginResultToViewTest.java │ ├── EncryCredentialResolverTest.java │ ├── KeyActionTest.java │ ├── LoginActionTest.java │ ├── LogoutActionTest.java │ └── UsernamePasswordCredentialResolverTest.java └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /ki4so-core/.settings 2 | /ki4so-core/.project 3 | /ki4so-core/.classpath 4 | /ki4so-web/.project 5 | /ki4so-web/.settings 6 | /ki4so-web/.classpath 7 | /ki4so-web/target 8 | /ki4so-core/target 9 | /ki4so-common/.project 10 | /ki4so-common/.settings 11 | /ki4so-common/target 12 | /ki4so-common/.classpath 13 | /.project 14 | /.gitignore 15 | /ki4so-parent.ipr 16 | /ki4so-parent.iws 17 | /ki4so-parent.iml 18 | /ki4so-core/ki4so-core.iml 19 | /ki4so-core/.idea 20 | /ki4so-web/ki4so-web.iml 21 | /ki4so-web/.idea 22 | /ki4so-common/ki4so-common.iml 23 | 24 | /ki4so-app/.project 25 | /ki4so-app/.settings 26 | /ki4so-app/target 27 | /ki4so-app/.classpath 28 | /ki4so-java-client/.project 29 | /ki4so-java-client/.settings 30 | /ki4so-java-client/target 31 | /ki4so-java-client/.classpath 32 | /ki4so-jdbc/.project 33 | /ki4so-jdbc/.settings 34 | /ki4so-jdbc/target 35 | /ki4so-jdbc/.classpath 36 | /.settings 37 | /ki4so-app/.mymetadata 38 | /ki4so-app/.springBeans 39 | /ki4so-web/.mymetadata 40 | /ki4so-web/.springBeans 41 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | script: 3 | - mvn test 4 | env: MAVEN_OPTS="-XX:MaxPermSize=128m" -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #web-sso单点登录 2 | 参考 http://git.oschina.net/ywbrj042/ki4so 本文内容仅供自己学习,作为学习笔记。如若需要,可以前往:http://git.oschina.net/ywbrj042/ki4so 3 | 4 | ##提供另外一个简单的单点登录思想:: 5 | 比如存在3个域名a.com,b.com,c.com.其中a.com作为主域名,不论b.com还是c.com登录时请求都提交到a.com,所有的存储都在a.com,其他域名不允许访问。在a.com登录成功后,将登录信息存放在a.com域下的cookie中。此时发起广播,由client端通知b.com和c.com,说用户已经登录(仅仅是告诉他们已经登录),此时用户访问b.com或者c.com时有server端向a.com请求获取用户信息,并将非敏感信息存储到自己的存储当中。同理,登出时也是向a.com发起登出请求,a.com将用户cookie清掉,b.com和c.com再次向a.com请求验证用户身份时,则验证失败。 6 | -------------------------------------------------------------------------------- /ki4so-app/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /bin 3 | -------------------------------------------------------------------------------- /ki4so-app/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | com.github.ki4so 6 | ki4so-parent 7 | 1.0.1-SNAPSHOT 8 | 9 | 4.0.0 10 | ki4so-app 11 | war 12 | ki4so-app 13 | 14 | 简约单点系统的实例应用,其它的需要集成ki4so的java web应用可以参考本应用实现。 15 | 如果是其它语言的应用需要集成ki4so,只需要遵循协议约束实现即可,各种平台的客户端包 16 | 在不断完善和开发中,期待更多人参与开发和完善各种平台的集成示例。 17 | 18 | 19 | 20 | 21 | 22 | com.github.ki4so 23 | ki4so-java-client 24 | ${ki4so.version} 25 | 26 | 27 | 28 | org.springframework 29 | spring-web 30 | ${spring.version} 31 | 32 | 33 | org.springframework 34 | spring-webmvc 35 | ${spring.version} 36 | 37 | 38 | javax.servlet 39 | servlet-api 40 | 2.5 41 | provided 42 | 43 | 44 | javax.servlet 45 | jstl 46 | 1.2 47 | 48 | 49 | taglibs 50 | standard 51 | 1.1.2 52 | 53 | 54 | org.springframework 55 | spring-core 56 | 57 | 58 | 59 | org.springframework 60 | spring-beans 61 | 62 | 63 | 64 | org.springframework 65 | spring-context 66 | 67 | 68 | 69 | org.codehaus.jackson 70 | jackson-core-asl 71 | 1.9.12 72 | 73 | 74 | 75 | org.codehaus.jackson 76 | jackson-mapper-asl 77 | 1.9.12 78 | 79 | 80 | 81 | com.fasterxml.jackson.core 82 | jackson-databind 83 | 2.0.1 84 | 85 | 86 | 87 | junit 88 | junit 89 | 90 | 91 | 92 | org.mockito 93 | mockito-core 94 | 95 | 96 | 97 | org.springframework 98 | spring-test 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /ki4so-app/src/main/java/com/github/ebnew/ki4so/app/custom/AppClientLoginHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.app.custom; 2 | 3 | import com.github.ebnew.ki4so.client.handler.KnightAppClientLoginHandler; 4 | import com.github.ebnew.ki4so.core.model.KnightCredentialInfo; 5 | import org.apache.log4j.Logger; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | 10 | /** 11 | * 默认的登录认证实现 12 | * @author zhenglu 13 | * @since 15/4/30 14 | */ 15 | public class AppClientLoginHandler implements KnightAppClientLoginHandler{ 16 | 17 | private static Logger logger = Logger.getLogger(AppClientLoginHandler.class); 18 | 19 | public static final String USER_KEY = "USER_KEY_SESSION"; 20 | 21 | @Override 22 | public void loginClient(KnightCredentialInfo credentialInfo, HttpServletRequest request, HttpServletResponse response) { 23 | request.getSession().setAttribute(USER_KEY,credentialInfo); 24 | logger.info("the user id is "+ credentialInfo.getUserId() + "has logined in the app"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ki4so-app/src/main/java/com/github/ebnew/ki4so/app/custom/AppClientLogoutHandlerImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.app.custom; 2 | 3 | import com.github.ebnew.ki4so.client.handler.KnightAppClientLogoutHandler; 4 | import com.github.ebnew.ki4so.common.utils.StringUtils; 5 | import org.apache.log4j.Logger; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | 10 | /** 11 | * @author zhenglu 12 | * @since 15/4/30 13 | */ 14 | public class AppClientLogoutHandlerImpl implements KnightAppClientLogoutHandler { 15 | 16 | private static final Logger logger = Logger.getLogger(AppClientLogoutHandlerImpl.class); 17 | 18 | 19 | 20 | @Override 21 | public void logoutClient(HttpServletRequest request, HttpServletResponse response, String userId) { 22 | if(!StringUtils.isEmpty(userId)){ 23 | //remove the exception 24 | 25 | logger.info("the user id is userid has logout the app"); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ki4so-app/src/main/java/com/github/ebnew/ki4so/app/web/action/HomeAction.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.app.web.action; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpSession; 5 | 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.servlet.ModelAndView; 9 | 10 | 11 | @Controller 12 | public class HomeAction { 13 | 14 | public static final String USER_KEY = "USER_KEY_SESSION"; 15 | 16 | @RequestMapping("home") 17 | public ModelAndView home(HttpServletRequest request, HttpSession session){ 18 | ModelAndView mv = new ModelAndView(); 19 | mv.addObject("user", session.getAttribute(USER_KEY)); 20 | return mv; 21 | } 22 | } -------------------------------------------------------------------------------- /ki4so-app/src/main/resources/spring/spring-beans.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ki4so-app/src/main/resources/spring/springmvc-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | text/html;charset=UTF-8 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /ki4so-app/src/main/webapp/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /ki4so-app/src/main/webapp/META-INF/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /ki4so-app/src/main/webapp/WEB-INF/pages/home.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 4 | 5 | 6 | 7 | 8 | 9 | Ki4so单点登录系统集成示例 10 | 11 | 12 |

这是ki4so集成单点登录系统的示例一个用,演示了如何集成单点登录系统ki4so.

13 |

14 | 单点登录成功,当前登录的用户是:${user.userId}.登录的应用ID是:${user.appId} 15 |

16 | 17 |

18 | 统一登出 19 |

20 | 21 | -------------------------------------------------------------------------------- /ki4so-app/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | ki4so-web 8 | 9 | 本项目是ki4so的客户端应用示例工程,演示了如何继承Ki4so单点登录服务。 10 | 11 | 12 | 13 | 14 | springmvc 15 | org.springframework.web.servlet.DispatcherServlet 16 | 17 | contextConfigLocation 18 | classpath:spring/*.xml 19 | 20 | 0 21 | 22 | 23 | 24 | springmvc 25 | *.do 26 | 27 | 28 | 29 | 30 | knightClientFilter 31 | com.github.ebnew.ki4so.client.web.filters.KnightClientFilter 32 | 33 | ki4so服务器主机地址 34 | ki4soServerHost 35 | http://localhost:8080/ki4so-web/ 36 | 37 | 38 | 39 | ki4so服务器登录地址 40 | ki4soServerLoginUrl 41 | http://localhost:8080/ki4so-web/login.do 42 | 43 | 44 | 45 | ki4so服务器获取应用秘钥信息的URL地址 46 | ki4soServerFetchKeyUrl 47 | http://localhost:8080/ki4so-web/fetchKey.do 48 | 49 | 50 | 51 | 本应用在ki4so服务器上的应用ID值 52 | ki4soClientAppId 53 | 1001 54 | 55 | 56 | 57 | 登录本应用处理器类 58 | appClientLoginHandlerClass 59 | com.github.ebnew.ki4so.app.custom.AppClientLoginHandler 60 | 61 | 62 | 63 | 64 | knightClientFilter 65 | /home.do 66 | 67 | 68 | 69 | 70 | ki4soClientLogoutFilter 71 | com.github.ebnew.ki4so.client.web.filters.Ki4soClientLogoutFilter 72 | 73 | 74 | 登出本应用处理器类 75 | appClientLogoutHandler 76 | com.github.ebnew.ki4so.app.custom.AppClientLogoutHandlerImpl 77 | 78 | 79 | 80 | 81 | ki4soClientLogoutFilter 82 | /logout.do 83 | 84 | 85 | 86 | 87 | /index.jsp 88 | 89 | 90 | -------------------------------------------------------------------------------- /ki4so-app/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | 4 | 5 | 6 | 7 | 首页 8 | 9 | 10 |

11 | 这是ki4so单点登录系统集成的应用示例,是一个简单的java web应用, 12 | 可以参考本应用集成其它应用从而实现单点登录。 13 |

14 | 15 |

16 | 进入受保护资源,需要登录 17 |

18 | 19 | -------------------------------------------------------------------------------- /ki4so-common/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ki4so-parent 6 | com.github.ki4so 7 | 1.0.1-SNAPSHOT 8 | 9 | com.github.ki4so 10 | ki4so-common 11 | ${ki4so.version} 12 | ki4so-common 13 | 简约单点登录系统工具模块,提供加密解密等工具类 14 | 15 | 16 | 1.4.12 17 | 18 | 19 | 20 | 21 | 22 | junit 23 | junit 24 | 25 | 26 | 27 | org.mockito 28 | mockito-core 29 | 30 | 31 | 32 | org.powermock 33 | powermock-module-junit4 34 | ${powermock.version} 35 | test 36 | 37 | 38 | 39 | org.powermock 40 | powermock-api-mockito 41 | ${powermock.version} 42 | test 43 | 44 | 45 | 46 | com.alibaba 47 | fastjson 48 | 1.1.35 49 | jar 50 | compile 51 | 52 | 53 | 54 | org.apache.httpcomponents 55 | httpclient 56 | 4.3-beta2 57 | jar 58 | compile 59 | 60 | 61 | 62 | log4j 63 | log4j 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/common/KnightBase64Coder.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.common; 2 | 3 | import org.apache.log4j.Logger; 4 | import sun.misc.BASE64Decoder; 5 | import sun.misc.BASE64Encoder; 6 | 7 | import java.io.IOException; 8 | 9 | /** 10 | * @author zhenglu 11 | * @since 15/4/23 12 | */ 13 | public class KnightBase64Coder { 14 | 15 | private static final Logger logger = Logger.getLogger(KnightBase64Coder.class); 16 | 17 | /** 18 | * 编码 19 | * @param bstr 20 | * @return 21 | */ 22 | 23 | public static String encryptBase64(byte[] bstr){ 24 | if(bstr == null || bstr.length == 0){ 25 | return null; 26 | } 27 | return new BASE64Encoder().encode(bstr); 28 | } 29 | 30 | /** 31 | * 解码 32 | */ 33 | public static byte[] decryptBase64(String str){ 34 | if(str == null || str.length() == 0){ 35 | return null; 36 | } 37 | byte[] result = null; 38 | BASE64Decoder decoder = new BASE64Decoder(); 39 | try { 40 | result = decoder.decodeBuffer(str); 41 | 42 | 43 | } catch (IOException e) { 44 | logger.error("出错:decode base64 error:: " + e.getMessage() ); 45 | } 46 | 47 | return result; 48 | } 49 | } 50 | 51 | 52 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/common/KnightDECoder.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.common; 2 | 3 | import sun.util.resources.CurrencyNames_iw_IL; 4 | 5 | import javax.crypto.Cipher; 6 | import javax.crypto.KeyGenerator; 7 | import javax.crypto.SecretKey; 8 | import javax.crypto.SecretKeyFactory; 9 | import javax.crypto.spec.DESedeKeySpec; 10 | import java.security.Key; 11 | import java.security.SecureRandom; 12 | 13 | /** 14 | * @author zhenglu 15 | * @since 15/4/23 16 | */ 17 | public class KnightDECoder { 18 | 19 | /** 20 | * 21 | * 密钥算法 22 | */ 23 | private static final String KEY_ALGORIHM = "DESede"; 24 | 25 | private static final String DEFAULT_CIPHER_ALGORIHM ="DESede/ECB/ISO10126Padding"; 26 | 27 | private static final int KEY_SITE = 168; 28 | 29 | 30 | /** 31 | * 初始化密钥 32 | * @param seed 33 | * @return 34 | * @throws Exception 35 | */ 36 | public static Key initSecretKey(String seed) throws Exception{ 37 | //返回生成指定算法的密钥 KeyGenerator 38 | KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORIHM); 39 | //初始化此密钥生成器,使其具有确定的密钥大小 40 | SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); 41 | secureRandom.setSeed(seed.getBytes()); 42 | keyGenerator.init(KEY_SITE,secureRandom); 43 | 44 | //生成一个密钥 45 | SecretKey secretKey = keyGenerator.generateKey(); 46 | //实例化DES 密钥规则 47 | DESedeKeySpec deSedeKeySpec = new DESedeKeySpec(secretKey.getEncoded()); 48 | //实例化密钥工厂 49 | SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(KEY_ALGORIHM); 50 | //生成密钥 51 | return secretKeyFactory.generateSecret(deSedeKeySpec); 52 | } 53 | 54 | public static byte[] encrypt(byte[] data,Key key) throws Exception{ 55 | return encrypt(data,key,DEFAULT_CIPHER_ALGORIHM); 56 | } 57 | 58 | /** 59 | * 60 | * @param data 原始数据 61 | * @param key 密钥 62 | * @param algorithm 加密算法、工作模式、填充模式 63 | * @return 64 | * @throws Exception 65 | */ 66 | public static byte[] encrypt(byte[] data,Key key,String algorithm) throws Exception{ 67 | Cipher cipher = Cipher.getInstance(algorithm); 68 | 69 | 70 | /** 71 | * 72 | * DECRYPT_MODE 用于将 cipher 初始化为解密模式的常量 73 | * 74 | * PRIVATE_KEY 用于指示要打开的密钥为“私钥”的常量。 75 | * 76 | * PUBLIC_KEY 用于指示要打开的密钥为“公钥”的常量。 77 | * 78 | * SECRET_KEY 用于指示要打开的密钥为“秘密密钥”的常量。 79 | * 80 | * UNWRAP_MODE 用于将 cipher 初始化为密钥打开模式的常量。 81 | * 82 | * WRAP_MODE 用于将 cipher 初始化为密钥包装模式的常量 83 | */ 84 | //使用密钥初始化,设置为加密模式 85 | cipher.init(Cipher.DECRYPT_MODE,key); 86 | return cipher.doFinal(data); 87 | } 88 | 89 | public static byte[] decrypt(byte[] data,Key key,String algorithm) throws Exception{ 90 | Cipher cipher = Cipher.getInstance(algorithm); 91 | cipher.init(Cipher.DECRYPT_MODE,key); 92 | return cipher.doFinal(); 93 | } 94 | 95 | public static byte[] decrypt(byte[] data,Key key) throws Exception{ 96 | return decrypt(data,key,DEFAULT_CIPHER_ALGORIHM); 97 | } 98 | 99 | 100 | 101 | 102 | } 103 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/common/utils/StringUtils.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.common.utils; 2 | 3 | public class StringUtils { 4 | 5 | /** 6 | * 判断字符串是否为空。 7 | * @param str 源字符串。 8 | * @return 9 | */ 10 | public static boolean isEmpty(String str){ 11 | return str == null || str.length()==0; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/app/KnightApp.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.app; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * 应用描述信息 7 | * @author zhenglu 8 | * @since 15/4/25 9 | */ 10 | public class KnightApp implements Serializable { 11 | 12 | private static final long serialVersionUID = -1850808070447330706L; 13 | 14 | 15 | /** 16 | * 应用id 17 | */ 18 | private String appId; 19 | 20 | /** 21 | * 应用名称 22 | */ 23 | 24 | private String appName; 25 | 26 | /*** 27 | * 应用所在的主机地址 28 | */ 29 | 30 | private String host; 31 | 32 | /** 33 | * 应用退出地址 34 | */ 35 | 36 | private String logoutPath; 37 | 38 | 39 | /** 40 | * 是否是knight服务本身 41 | */ 42 | private boolean knightService = false; 43 | 44 | public String getAppId() { 45 | return appId; 46 | } 47 | 48 | public void setAppId(String appId) { 49 | this.appId = appId; 50 | } 51 | 52 | public String getAppName() { 53 | return appName; 54 | } 55 | 56 | public void setAppName(String appName) { 57 | this.appName = appName; 58 | } 59 | 60 | public String getHost() { 61 | return host; 62 | } 63 | 64 | public void setHost(String host) { 65 | this.host = host; 66 | } 67 | 68 | public String getLogoutPath() { 69 | return logoutPath; 70 | } 71 | 72 | public void setLogoutPath(String logoutPath) { 73 | this.logoutPath = logoutPath; 74 | } 75 | 76 | public boolean isKnightService() { 77 | return knightService; 78 | } 79 | 80 | public void setKnightService(boolean knightService) { 81 | this.knightService = knightService; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/authentication/KnightAbstractParameter.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * 抽象的参数化实现类 7 | * @author zhenglu 8 | * @since 15/4/27 9 | */ 10 | public abstract class KnightAbstractParameter implements KnightParameter{ 11 | 12 | /** 13 | * 其他参数表 14 | */ 15 | protected Map paramters; 16 | 17 | @Override 18 | public Object getParameterValue(String parameName) { 19 | 20 | return this.paramters == null?null:this.paramters.get(parameName); 21 | } 22 | 23 | @Override 24 | public Map getParameters() { 25 | return this.paramters; 26 | } 27 | 28 | @Override 29 | public void setParameters(Map parameters) { 30 | this.paramters = parameters; 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/authentication/KnightCredential.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication; 2 | 3 | /** 4 | * 用户凭据,代表了一个用户的身份,这是一个抽象的概念 5 | * 这种凭据可以是一个用户名和密码对,也可以是一个加密后的信息,也可以是人和可以识别用户的信息 6 | * @author zhenglu 7 | * @since 15/4/23 8 | */ 9 | public interface KnightCredential { 10 | 11 | 12 | /** 13 | * 是否是原始凭据,即未认证过的原始信息 14 | * 15 | * @return true :原始凭据,false:加密后的凭据 16 | */ 17 | public boolean isOriginal(); 18 | } 19 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/authentication/KnightEncryCredential.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication; 2 | 3 | import com.github.ebnew.ki4so.core.model.KnightCredentialInfo; 4 | 5 | /** 6 | * 认证过的加密后的用户凭证,用于输出客户端 7 | * @author zhenglu 8 | * @since 15/4/27 9 | */ 10 | public class KnightEncryCredential extends KnightAbstractParameter implements KnightCredential{ 11 | /** 12 | * 加密后的用户凭证串 13 | */ 14 | private String credential; 15 | 16 | 17 | private KnightCredentialInfo credentialInfo; 18 | 19 | 20 | public String getCredential() { 21 | return credential; 22 | } 23 | 24 | public void setCredential(String credential) { 25 | this.credential = credential; 26 | } 27 | 28 | public KnightCredentialInfo getCredentialInfo() { 29 | return credentialInfo; 30 | } 31 | 32 | public void setCredentialInfo(KnightCredentialInfo credentialInfo) { 33 | this.credentialInfo = credentialInfo; 34 | } 35 | 36 | @Override 37 | public boolean isOriginal() { 38 | return false; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/authentication/KnightEncryCredentialManager.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication; 2 | 3 | 4 | import com.github.ebnew.ki4so.core.model.KnightCredentialInfo; 5 | 6 | /** 7 | * 加密凭据的管理器,包括对加密凭据加密和解密等操作 8 | * @author zhenglu 9 | * @since 15/4/27 10 | */ 11 | public interface KnightEncryCredentialManager { 12 | 13 | 14 | /** 15 | * 对斑马的凭据信息进行解码,解码后为一个凭据对象 16 | * @param credential 17 | * @return 18 | */ 19 | public KnightCredentialInfo decrypt(KnightEncryCredential credential); 20 | 21 | /** 22 | * 对一个凭据对象进行加密,返回加密后的字符串 23 | * @param credentialInfo 24 | * @return 25 | */ 26 | 27 | public String encrypt(KnightCredentialInfo credentialInfo); 28 | 29 | /** 30 | * 检查用户凭据信息的合法性,是否合法,是否过期 是否有效等 31 | * @param credentialInfo 32 | * @return 33 | */ 34 | 35 | public boolean checkEncryCredentialInfo(KnightCredentialInfo credentialInfo); 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/authentication/KnightParameter.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * 参数,定义了获得动态参数列表的接口 7 | * @author zhenglu 8 | * @since 15/4/27 9 | */ 10 | public interface KnightParameter { 11 | 12 | /** 13 | * 通过参数名获得参数值的方法 14 | * @param parameName 15 | * @return 16 | */ 17 | public Object getParameterValue(String parameName); 18 | 19 | 20 | /** 21 | * 获得所有的参数 22 | * @return 所有的参数列表 23 | */ 24 | public Map getParameters(); 25 | 26 | /** 27 | * 设置参数列表 28 | * @param parameters 29 | */ 30 | 31 | public void setParameters(Map parameters); 32 | } 33 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/exception/AuthenticationException.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.exception; 2 | 3 | 4 | /** 5 | * 基础异常类,定义了根级异常类。 6 | * @author burgess yang. 7 | * 8 | */ 9 | public abstract class AuthenticationException extends RuntimeException { 10 | 11 | /** 12 | * 13 | */ 14 | private static final long serialVersionUID = -1783421378934140252L; 15 | 16 | /** 17 | * 异常代号。 18 | */ 19 | private String code; 20 | 21 | /** 22 | * 异常详细信息键值,根据该键值查找某种语言下的具体值。 23 | */ 24 | private String msgKey; 25 | 26 | public String getCode() { 27 | return code; 28 | } 29 | 30 | public void setCode(String code) { 31 | this.code = code; 32 | } 33 | 34 | public String getMsgKey() { 35 | return msgKey; 36 | } 37 | 38 | public void setMsgKey(String msgKey) { 39 | this.msgKey = msgKey; 40 | } 41 | 42 | public AuthenticationException(String code, String msgKey) { 43 | super(); 44 | this.code = code; 45 | this.msgKey = msgKey; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/exception/EmptyCredentialException.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.exception; 2 | 3 | public class EmptyCredentialException extends InvalidCredentialException { 4 | 5 | public static final EmptyCredentialException INSTANCE = new EmptyCredentialException(); 6 | 7 | /** 8 | * 9 | */ 10 | private static final long serialVersionUID = -1075351110429734216L; 11 | 12 | /** 13 | * 异常代码值。 14 | */ 15 | public static final String CODE = "EMPTY.CREDENTIAL.CODE"; 16 | 17 | /** 18 | * 异常信息键值,要转换为具体的语言值。 19 | */ 20 | public static final String MSG_KEY = "EMPTY.CREDENTIAL.MSG"; 21 | 22 | 23 | public EmptyCredentialException() { 24 | super(CODE, MSG_KEY); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/exception/InvalidCredentialException.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.exception; 2 | 3 | /** 4 | * 表示不合法的用户凭据异常信息类 5 | * @author Administrator 6 | * 7 | */ 8 | public class InvalidCredentialException extends AuthenticationException { 9 | 10 | public static final InvalidCredentialException INSTANCE = new InvalidCredentialException(); 11 | 12 | /** 13 | * 异常代码值。 14 | */ 15 | public static final String CODE = "INVALID.CREDENTIAL.CODE"; 16 | 17 | /** 18 | * 异常信息键值,要转换为具体的语言值。 19 | */ 20 | public static final String MSG_KEY = "INVALID.CREDENTIAL.MSG"; 21 | 22 | public InvalidCredentialException(String code, String msgKey) { 23 | super(code, msgKey); 24 | } 25 | 26 | public InvalidCredentialException() { 27 | super(CODE, MSG_KEY); 28 | } 29 | 30 | /** 31 | * 32 | */ 33 | private static final long serialVersionUID = 3350784910105909683L; 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/exception/InvalidEncryCredentialException.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.exception; 2 | 3 | /** 4 | * 不合法的已认证凭据异常信息类 5 | * @author Administrator 6 | * 7 | */ 8 | public class InvalidEncryCredentialException extends InvalidCredentialException { 9 | 10 | public static final InvalidEncryCredentialException INSTANCE = new InvalidEncryCredentialException(); 11 | 12 | /** 13 | * 14 | */ 15 | private static final long serialVersionUID = -7019558865450982143L; 16 | 17 | /** 18 | * 异常代码值。 19 | */ 20 | public static final String CODE = "INVALID.ENC.CREDENTIAL.CODE"; 21 | 22 | /** 23 | * 异常信息键值,要转换为具体的语言值。 24 | */ 25 | public static final String MSG_KEY = "INVALID.ENC.CREDENTIAL.MSG"; 26 | 27 | 28 | public InvalidEncryCredentialException() { 29 | super(CODE, MSG_KEY); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/exception/NoAuthenticationPostHandlerException.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.exception; 2 | 3 | public class NoAuthenticationPostHandlerException extends AuthenticationException{ 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = 8319434404552943653L; 9 | 10 | /** 11 | * 异常代码值。 12 | */ 13 | public static final String CODE = "NO.AUTH.HANDLER.CODE"; 14 | 15 | /** 16 | * 异常信息键值,要转换为具体的语言值。 17 | */ 18 | public static final String MSG_KEY = "NO.AUTH.HANDLER.MSG"; 19 | 20 | public NoAuthenticationPostHandlerException() { 21 | super(CODE, MSG_KEY); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/exception/NoKi4soKeyException.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.exception; 2 | 3 | public class NoKi4soKeyException extends AuthenticationException{ 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = 115935182258831210L; 9 | 10 | public static final NoKi4soKeyException INSTANCE = new NoKi4soKeyException(); 11 | 12 | /** 13 | * 异常代码值。 14 | */ 15 | public static final String CODE = "NO.KI4SO.KEY.CODE"; 16 | 17 | /** 18 | * 异常信息键值,要转换为具体的语言值。 19 | */ 20 | public static final String MSG_KEY = "NO.KI4SO.KEY.MSG"; 21 | 22 | public NoKi4soKeyException(String code, String msgKey) { 23 | super(code, msgKey); 24 | } 25 | 26 | public NoKi4soKeyException() { 27 | super(CODE, MSG_KEY); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/exception/ParamsNotInitiatedCorrectly.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.exception; 2 | 3 | /** 4 | * 参数未初始化异常 5 | * @author Huiqiang Lai 6 | * 7 | */ 8 | public class ParamsNotInitiatedCorrectly extends RuntimeException { 9 | 10 | /** 11 | * 12 | */ 13 | private static final long serialVersionUID = 1L; 14 | 15 | public ParamsNotInitiatedCorrectly(String message){ 16 | super(message); 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/exception/PasswordInvalidException.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.exception; 2 | 3 | /** 4 | * 密码不合法的异常类 5 | * @author burgess yang 6 | * 7 | */ 8 | public class PasswordInvalidException extends InvalidCredentialException { 9 | 10 | public static final PasswordInvalidException INSTANCE = new PasswordInvalidException(); 11 | 12 | /** 13 | * 14 | */ 15 | private static final long serialVersionUID = -4250926514996058588L; 16 | 17 | /** 18 | * 异常代码值。 19 | */ 20 | public static final String CODE = "PASSWORD.INVALID.CODE"; 21 | 22 | /** 23 | * 异常信息键值,要转换为具体的语言值。 24 | */ 25 | public static final String MSG_KEY = "PASSWORD.INVALID.MSG"; 26 | 27 | public PasswordInvalidException() { 28 | super(CODE, MSG_KEY); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/exception/UnsupportedCredentialsException.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.exception; 2 | 3 | public class UnsupportedCredentialsException extends InvalidCredentialException { 4 | /** 5 | * 6 | */ 7 | private static final long serialVersionUID = -4250926514996058588L; 8 | 9 | /** 10 | * 异常代码值。 11 | */ 12 | public static final String CODE = "UNSUPPORTED.CREDENTIALS.CODE"; 13 | 14 | /** 15 | * 异常信息键值,要转换为具体的语言值。 16 | */ 17 | public static final String MSG_KEY = "UNSUPPORTED.CREDENTIALS.MSG"; 18 | 19 | public UnsupportedCredentialsException() { 20 | super(CODE, MSG_KEY); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/exception/UsernameInvalidException.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.exception; 2 | 3 | /** 4 | * 用户名不合法的异常类。 5 | * @author burgess yang 6 | * 7 | */ 8 | public class UsernameInvalidException extends InvalidCredentialException{ 9 | 10 | public static final UsernameInvalidException INSTANCE = new UsernameInvalidException(); 11 | 12 | /** 13 | * 14 | */ 15 | private static final long serialVersionUID = -4250926514996058588L; 16 | 17 | /** 18 | * 异常代码值。 19 | */ 20 | public static final String CODE = "USERNAME.INVALID.CODE"; 21 | 22 | /** 23 | * 异常信息键值,要转换为具体的语言值。 24 | */ 25 | public static final String MSG_KEY = "USERNAME.INVALID.MSG"; 26 | 27 | public UsernameInvalidException() { 28 | super(CODE, MSG_KEY); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/exception/UsernameOrPasswordEmptyException.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.exception; 2 | 3 | /** 4 | * 用户名或者密码为空的异常类 5 | * @author burgess yang 6 | * 7 | */ 8 | public class UsernameOrPasswordEmptyException extends InvalidCredentialException{ 9 | /** 10 | * 11 | */ 12 | private static final long serialVersionUID = 5781748461802851385L; 13 | 14 | /** 15 | * 异常代码值。 16 | */ 17 | public static final String CODE = "USERNAME.OR.PWD.EMPTY.CODE"; 18 | 19 | /** 20 | * 异常信息键值,要转换为具体的语言值。 21 | */ 22 | public static final String MSG_KEY = "USERNAME.OR.PWD.EMPTY.MSG"; 23 | 24 | 25 | public UsernameOrPasswordEmptyException() { 26 | super(CODE, MSG_KEY); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/exception/UsernameOrPasswordInvalidException.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.exception; 2 | 3 | /** 4 | * 用户名或者密码不合法的异常信息 5 | * @author burgess yang 6 | * 7 | */ 8 | public class UsernameOrPasswordInvalidException extends InvalidCredentialException { 9 | 10 | public static final UsernameOrPasswordInvalidException INSTANCE = new UsernameOrPasswordInvalidException(); 11 | 12 | /** 13 | * 14 | */ 15 | private static final long serialVersionUID = -4250926514996058588L; 16 | 17 | /** 18 | * 异常代码值。 19 | */ 20 | public static final String CODE = "USERNAME.OR.PWD.INVALID.CODE"; 21 | 22 | /** 23 | * 异常信息键值,要转换为具体的语言值。 24 | */ 25 | public static final String MSG_KEY = "USERNAME.OR.PWD.INVALID.MSG"; 26 | 27 | public UsernameOrPasswordInvalidException() { 28 | super(CODE, MSG_KEY); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/key/KnightKey.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.key; 2 | 3 | import com.github.ebnew.ki4so.common.KnightDECoder; 4 | 5 | import java.io.Serializable; 6 | import java.security.Key; 7 | 8 | /** 9 | * @author zhenglu 10 | * @since 15/4/23 11 | */ 12 | public class KnightKey implements Serializable { 13 | 14 | private static final long serialVersionUID = 3535643339281384507L; 15 | /** 16 | * 私钥ID 17 | */ 18 | private String keyId; 19 | 20 | 21 | /** 22 | * 应用id 23 | */ 24 | private String appId; 25 | 26 | 27 | /** 28 | * 私钥值 29 | */ 30 | private String value; 31 | 32 | /** 33 | * 私钥文件存放的路径 34 | */ 35 | private String keyPath; 36 | 37 | public String getKeyId() { 38 | return keyId; 39 | } 40 | 41 | public void setKeyId(String keyId) { 42 | this.keyId = keyId; 43 | } 44 | 45 | public String getAppId() { 46 | return appId; 47 | } 48 | 49 | public void setAppId(String appId) { 50 | this.appId = appId; 51 | } 52 | 53 | public String getValue() { 54 | return value; 55 | } 56 | 57 | public void setValue(String value) { 58 | this.value = value; 59 | } 60 | 61 | public String getKeyPath() { 62 | return keyPath; 63 | } 64 | 65 | public void setKeyPath(String keyPath) { 66 | this.keyPath = keyPath; 67 | } 68 | 69 | 70 | public Key toSecurityKey(){ 71 | try{ 72 | if(this.getValue() != null){ 73 | return KnightDECoder.initSecretKey(this.getValue()); 74 | } 75 | }catch (Exception e){ 76 | e.printStackTrace(); 77 | return null; 78 | } 79 | return null; 80 | 81 | } 82 | @Override 83 | public String toString() { 84 | return "knight: [keyId=" + keyId + ", appId=" + appId + ", value=" 85 | + value + ",keyPath=" + keyPath + "]"; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/key/KnightKeyService.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.key; 2 | 3 | /** 4 | * 利用非对称加密保证key的安全性 5 | * @author zhenglu 6 | * @since 15/4/24 7 | */ 8 | public interface KnightKeyService { 9 | 10 | /** 11 | * 根据密钥id查找对应的密钥信息 12 | * @param keyId 13 | * @return 14 | */ 15 | public KnightKey findKeyByKeyId(String keyId); 16 | 17 | /** 18 | * 根据应用id查找对应的密钥信息 19 | * @param appId 20 | * @return 21 | */ 22 | public KnightKey findKeyByAppId(String appId); 23 | 24 | 25 | /** 26 | * 判断密钥文件是否生成 27 | * @param token 改文件存在的标识 28 | * @return 29 | */ 30 | public boolean checkKeyFileExistByToken(String token); 31 | 32 | 33 | /** 34 | * 生成非对称加密文件(客户端生成私钥文件;服务端生成公钥文件) 35 | * @param token 36 | * @return 37 | */ 38 | public Object generateKeyFile(String token); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/core/model/KnightCredentialInfo.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.model; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | /** 7 | * 加密凭证信息 8 | * @author zhenglu 9 | * @since 15/4/23 10 | */ 11 | public class KnightCredentialInfo implements Serializable{ 12 | 13 | private static final long serialVersionUID = -6546063621536994328L; 14 | /** 15 | * 应用唯一标识 16 | */ 17 | private String appId; 18 | 19 | /** 20 | * 用户唯一标识 21 | */ 22 | 23 | private String userId; 24 | 25 | /** 26 | * 密钥唯一标识 27 | */ 28 | private String keyId; 29 | 30 | 31 | /** 32 | * 加密凭证的创建时间 33 | */ 34 | private Date createTime; 35 | 36 | 37 | /** 38 | * 加密凭证的失效时间 39 | */ 40 | private Date expireTime; 41 | 42 | /** 43 | * 加密凭证的盐值 44 | */ 45 | 46 | private String salt; 47 | 48 | 49 | public String getAppId() { 50 | return appId; 51 | } 52 | 53 | public void setAppId(String appId) { 54 | this.appId = appId; 55 | } 56 | 57 | public String getUserId() { 58 | return userId; 59 | } 60 | 61 | public void setUserId(String userId) { 62 | this.userId = userId; 63 | } 64 | 65 | public String getKeyId() { 66 | return keyId; 67 | } 68 | 69 | public void setKeyId(String keyId) { 70 | this.keyId = keyId; 71 | } 72 | 73 | public Date getCreateTime() { 74 | return createTime; 75 | } 76 | 77 | public void setCreateTime(Date createTime) { 78 | this.createTime = createTime; 79 | } 80 | 81 | public Date getExpireTime() { 82 | return expireTime; 83 | } 84 | 85 | public void setExpireTime(Date expireTime) { 86 | this.expireTime = expireTime; 87 | } 88 | 89 | public String getSalt() { 90 | return salt; 91 | } 92 | 93 | public void setSalt(String salt) { 94 | this.salt = salt; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /ki4so-common/src/main/java/com/github/ebnew/ki4so/web/utils/WebConstants.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.web.utils; 2 | 3 | /** 4 | * web相关的常量类,定义了与web相关的所有常量值。 5 | * @author burgess yang 6 | * 7 | */ 8 | public interface WebConstants { 9 | 10 | /** 11 | * ki4so中心认证服务器写入到用户web客户端cookie中的认证加密后的凭据的键名称。 12 | */ 13 | public static final String KI4SO_SERVER_ENCRYPTED_CREDENTIAL_COOKIE_KEY = "KI4SO_SERVER_EC"; 14 | 15 | /** 16 | * ki4so客户端应用服务器写入到用户web客户端cookie中的认证加密后的凭据的键名称。 17 | */ 18 | public static final String KI4SO_CLIENT_ENCRYPTED_CREDENTIAL_COOKIE_KEY = "KI4SO_CLIENT_EC"; 19 | 20 | /** 21 | * 目的服务地址service的参数名。 22 | */ 23 | public static final String SERVICE_PARAM_NAME = "service"; 24 | 25 | /** 26 | * 目的服务地址存储在session中的key值。 27 | */ 28 | public static final String KI4SO_SERVICE_KEY_IN_SESSION = "KI4SO_SERVICE_KEY"; 29 | 30 | /** 31 | * 用户标识的参数名。 32 | */ 33 | public static final String USER_ID_PARAM_NAME = "userId"; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /ki4so-common/src/test/java/com/github/ebnew/ki4so/common/Base64CoderTest.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.common; 2 | 3 | import junit.framework.Assert; 4 | 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | public class Base64CoderTest { 10 | 11 | @Before 12 | public void setUp() throws Exception { 13 | } 14 | 15 | @After 16 | public void tearDown() throws Exception { 17 | } 18 | 19 | @Test 20 | public void testEncryptBASE64() { 21 | //测试空情况。 22 | Assert.assertNull(Base64Coder.encryptBASE64(null)); 23 | Assert.assertNull(Base64Coder.encryptBASE64(new byte[]{})); 24 | 25 | //测试正常输入。 26 | Assert.assertNotNull(Base64Coder.encryptBASE64(new byte[]{2,2,'a'})); 27 | } 28 | 29 | @Test 30 | public void testDecryptBASE64() { 31 | //测试空情况。 32 | Assert.assertNull(Base64Coder.decryptBASE64(null)); 33 | Assert.assertNull(Base64Coder.decryptBASE64("")); 34 | 35 | //测试随意的输入情况。 36 | Assert.assertNotNull(Base64Coder.decryptBASE64("ddd")); 37 | 38 | //测试加密解密匹配的情况。 39 | byte[] i =new byte[]{1}; 40 | String s = Base64Coder.encryptBASE64(i); 41 | byte[] b = Base64Coder.decryptBASE64(s); 42 | 43 | Assert.assertEquals(i[0], b[0]); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /ki4so-common/src/test/java/com/github/ebnew/ki4so/common/DESCoderTest.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.common; 2 | 3 | import java.security.Key; 4 | import java.util.Map; 5 | 6 | import junit.framework.Assert; 7 | 8 | import org.junit.Test; 9 | 10 | import com.alibaba.fastjson.JSON; 11 | 12 | public class DESCoderTest { 13 | 14 | @SuppressWarnings("unchecked") 15 | @Test 16 | public void test() throws Exception { 17 | 18 | //获得秘钥 19 | Key key = DESCoder.initSecretKey("12345645"); 20 | 21 | String data ="{id:1234,loginName:\"tianchen\",appId:123}"; 22 | 23 | System.out.println("en before :"+data); 24 | 25 | byte[] encryptData = DESCoder.encrypt(data.getBytes(), key); 26 | 27 | String enStr = Base64Coder.encryptBASE64(encryptData); 28 | System.out.println("en affter:"+enStr); 29 | 30 | byte[] decryptData = DESCoder.decrypt(Base64Coder.decryptBASE64(enStr), key); 31 | System.out.println("de affter:"+new String(decryptData)); 32 | Map map = (Map) JSON.parse(new String(decryptData));; 33 | System.out.println(map); 34 | } 35 | 36 | /** 37 | * 对加密解密性能测试。 38 | * @throws Exception 39 | */ 40 | @Test 41 | public void testPerformance() throws Exception{ 42 | //获得秘钥 43 | Key key = DESCoder.initSecretKey("12345645"); 44 | String data ="{id:1234,loginName:\"tianchen\",appId:123}"; 45 | 46 | //检测加密时间。 47 | long s = System.currentTimeMillis(); 48 | byte[] encryptData = DESCoder.encrypt(data.getBytes(), key); 49 | String enStr = Base64Coder.encryptBASE64(encryptData); 50 | long e = System.currentTimeMillis(); 51 | System.out.println("encrypt time:"+(e-s)); 52 | 53 | 54 | //检测解密时间。 55 | s = System.currentTimeMillis(); 56 | byte[] decryptData = DESCoder.decrypt(Base64Coder.decryptBASE64(enStr), key); 57 | @SuppressWarnings({ "unused", "unchecked" }) 58 | Map map = (Map) JSON.parse(new String(decryptData));; 59 | e = System.currentTimeMillis(); 60 | System.out.println("decrypt time:"+(e-s)); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ki4so-core/.gitignore: -------------------------------------------------------------------------------- 1 | /bin 2 | -------------------------------------------------------------------------------- /ki4so-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | com.github.ki4so 5 | ki4so-parent 6 | 1.0.1-SNAPSHOT 7 | 8 | 4.0.0 9 | ki4so-core 10 | jar 11 | ki4so-core 12 | 13 | 简约单点登录系统核心模块,定义了最核心的一些接口,抽象类以及一些默认的实现类,该模块是最核心的模块,其他模块均依赖本模块。 14 | 15 | 16 | 17 | 18 | 19 | com.github.ki4so 20 | ki4so-common 21 | ${ki4so.version} 22 | 23 | 24 | 25 | org.springframework 26 | spring-core 27 | 28 | 29 | 30 | org.springframework 31 | spring-beans 32 | 33 | 34 | 35 | org.springframework 36 | spring-context 37 | 38 | 39 | 40 | junit 41 | junit 42 | 43 | 44 | 45 | org.mockito 46 | mockito-core 47 | 48 | 49 | 50 | org.springframework 51 | spring-test 52 | 53 | 54 | 55 | org.apache.httpcomponents 56 | httpasyncclient 57 | 4.0.2 58 | 59 | 60 | 61 | org.apache.httpcomponents 62 | httpclient 63 | 4.3.5 64 | 65 | 66 | 67 | log4j 68 | log4j 69 | 70 | 71 | 72 | 73 | commons-io 74 | commons-io 75 | 2.4 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhenglu1989/web-sso/2747d3034599539ba92493dec53d7bff99e3cecd/ki4so-core/src/main/java/README.md -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/app/KnightAppService.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.app; 2 | 3 | /** 4 | * 应用信息的服务类 5 | * @author zhenglu 6 | * @since 15/4/26 7 | */ 8 | public interface KnightAppService { 9 | 10 | /** 11 | * 通过appid查找对应的应用信息 12 | * @param appId 13 | * @return 14 | */ 15 | 16 | public KnightApp findAppById(String appId); 17 | 18 | /** 19 | * 查找系统中Ki4so服务对应的应用信息 20 | * @return 21 | */ 22 | 23 | public KnightApp findKi4soServerApp(); 24 | 25 | /** 26 | * 通过host查找对应的应用信息 27 | * @param host 28 | * @return 29 | */ 30 | 31 | public KnightApp findAppByHost(String host); 32 | } 33 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/app/KnightAppServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.app; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.TypeReference; 5 | import com.github.ebnew.ki4so.common.utils.StringUtils; 6 | import com.github.ebnew.ki4so.core.dao.fs.KnightFileSystemDao; 7 | import org.apache.log4j.Logger; 8 | 9 | import java.util.Collection; 10 | import java.util.HashMap; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | /** 15 | * @author zhenglu 16 | * @since 15/4/26 17 | */ 18 | public class KnightAppServiceImpl extends KnightFileSystemDao implements KnightAppService { 19 | 20 | private static final Logger logger = Logger.getLogger(KnightAppServiceImpl.class); 21 | 22 | //外部文件,优先级最高 23 | private static final String DEFAULT_EXTERNAL_FILE = "/Users/zhenglu/Documents/study/ki4so/ki4so-core/src/main/resources/apps.js"; 24 | 25 | //默认的数据文件地址,在classpath下 26 | private static final String CLASS_PATH_FILE = "apps.js"; 27 | 28 | //应用的映射表,appid为key,value为应用信息 29 | 30 | private Map appMap = null; 31 | 32 | //服务本身应用信息 33 | private KnightApp knightApp = null; 34 | 35 | //在bean初始化init 36 | public void init(){ 37 | this.classPathData = CLASS_PATH_FILE; 38 | this.externalData = DEFAULT_EXTERNAL_FILE; 39 | loadAppData(); 40 | } 41 | 42 | 43 | 44 | @Override 45 | protected void loadAppData() { 46 | try{ 47 | if(appMap != null){ 48 | appMap.clear(); 49 | } 50 | appMap = null; 51 | String content = readDataFromFile(); 52 | List appList = JSON.parseObject(content, new TypeReference>(){}); 53 | appendSlashToHost(appList); 54 | if(appList != null && appList.size() > 0 ){ 55 | appMap = new HashMap(); 56 | for(KnightApp app : appList){ 57 | appMap.put(app.getAppId(),app); 58 | if(knightApp == null){ 59 | if(app.isKnightService()){ 60 | this.knightApp = app; 61 | } 62 | 63 | } 64 | } 65 | } 66 | 67 | }catch (Exception e){ 68 | logger.error("load app data error ::" + e.getMessage()); 69 | e.printStackTrace(); 70 | } 71 | 72 | } 73 | 74 | /** 75 | * 若主机host不以"/"结尾,则添加 "/" 否则不用处理 76 | * @param appList 77 | */ 78 | private void appendSlashToHost(List appList){ 79 | for(KnightApp app : appList){ 80 | if(app.getHost() != null && app.getHost().length() > 0 && !app.getHost().endsWith("/")){ 81 | app.setHost(app.getHost() + "/"); 82 | } 83 | } 84 | 85 | } 86 | 87 | @Override 88 | public KnightApp findAppById(String appId) { 89 | if(appMap != null){ 90 | appMap.get(appId); 91 | } 92 | return null; 93 | } 94 | 95 | @Override 96 | public KnightApp findKi4soServerApp() { 97 | return this.knightApp; 98 | } 99 | 100 | @Override 101 | public KnightApp findAppByHost(String host) { 102 | if(StringUtils.isEmpty(host)){ 103 | return null; 104 | } 105 | Collection apps = appMap.values(); 106 | KnightApp knightApp1 = findAppByUrl(apps,host); 107 | if(knightApp1 == null){ 108 | knightApp1 = findAppByUrl(apps,host+"/"); 109 | } 110 | 111 | return knightApp1; 112 | } 113 | private KnightApp findAppByUrl(Collection apps,String url){ 114 | if(apps == null || apps.size() == 0 || StringUtils.isEmpty(url)){ 115 | return null; 116 | } 117 | for(KnightApp app :apps){ 118 | if(!StringUtils.isEmpty(url) && url.startsWith(app.getHost())){ 119 | return app; 120 | } 121 | } 122 | return null; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/AbstractKnightUser.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * 抽象的用户主体实现类 7 | * @author zhenglu 8 | * @since 15/4/23 9 | */ 10 | public abstract class AbstractKnightUser implements KnightUser { 11 | /** 12 | * 用户主体的唯一标识 13 | */ 14 | protected String id; 15 | /** 16 | * 用户主体的其他属性 17 | */ 18 | protected Map attributes; 19 | 20 | public AbstractKnightUser(){ 21 | super(); 22 | } 23 | 24 | 25 | public AbstractKnightUser(String id, Map attributes) { 26 | super(); 27 | this.id = id; 28 | this.attributes = attributes; 29 | } 30 | 31 | public String getId() { 32 | return id; 33 | } 34 | 35 | public void setId(String id) { 36 | this.id = id; 37 | } 38 | 39 | public Map getAttributes() { 40 | return attributes; 41 | } 42 | 43 | public void setAttributes(Map attributes) { 44 | this.attributes = attributes; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/DefaultKnightUser.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication; 2 | 3 | 4 | import java.util.Map; 5 | 6 | /** 7 | * 默认的用户主体对象 8 | * @author zhenglu 9 | * @since 15/4/23 10 | */ 11 | public class DefaultKnightUser extends AbstractKnightUser { 12 | 13 | public DefaultKnightUser() { 14 | super(); 15 | } 16 | 17 | public DefaultKnightUser(String id, Map attributes) { 18 | super(id, attributes); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/KnightAuthentication.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication; 2 | 3 | import java.util.Date; 4 | import java.util.Map; 5 | 6 | /** 7 | * 验证结果 8 | * @author zhenglu 9 | * @since 15/4/23 10 | */ 11 | public interface KnightAuthentication { 12 | 13 | public Map getAttrbutes(); 14 | 15 | public Date getAuthenticateDate(); 16 | 17 | public KnightUser getUser(); 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/KnightAuthenticationImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication; 2 | 3 | import java.util.Date; 4 | import java.util.Map; 5 | 6 | /** 7 | * @author zhenglu 8 | * @since 15/4/23 9 | */ 10 | public class KnightAuthenticationImpl implements KnightAuthentication { 11 | 12 | private Date authenticatedDate; 13 | 14 | private Map attributes; 15 | 16 | private KnightUser user; 17 | 18 | @Override 19 | public Map getAttrbutes() { 20 | return attributes; 21 | } 22 | 23 | @Override 24 | public Date getAuthenticateDate() { 25 | return authenticatedDate; 26 | } 27 | 28 | @Override 29 | public KnightUser getUser() { 30 | return user; 31 | } 32 | 33 | public void setAuthenticatedDate(Date authenticatedDate) { 34 | this.authenticatedDate = authenticatedDate; 35 | } 36 | 37 | public void setAttributes(Map attributes) { 38 | this.attributes = attributes; 39 | } 40 | 41 | public void setUser(KnightUser user) { 42 | this.user = user; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/KnightAuthenticationManager.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication; 2 | 3 | /** 4 | * 认证管理器,负责对用户凭证进行有效性 5 | * @author zhenglu 6 | * @since 15/4/23 7 | */ 8 | public interface KnightAuthenticationManager { 9 | 10 | /** 11 | * fixedby zhenglu 失败可以返回null,不必抛出异常。保证系统可用性 12 | * 对用户凭证进行认证,若失败则抛出异常,若成功则放回认证结果 13 | * @return 14 | */ 15 | public KnightAuthentication authentication(KnightCredential credential); 16 | } 17 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/KnightAuthenticationManagerImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication; 2 | 3 | import com.github.ebnew.ki4so.core.authentication.handlers.AuthenticationHandler; 4 | import com.github.ebnew.ki4so.core.authentication.resolvers.CredentialToPrincipalResolver; 5 | import com.github.ebnew.ki4so.core.exception.UnsupportedCredentialsException; 6 | import org.apache.log4j.Logger; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * @author zhenglu 12 | * @since 15/4/23 13 | */ 14 | public class KnightAuthenticationManagerImpl implements KnightAuthenticationManager { 15 | 16 | public static final Logger logger = Logger.getLogger(KnightAuthenticationManagerImpl.class); 17 | 18 | 19 | /** 20 | * 认证处理器集合,使用多个认证处理器对凭证逐一认证,只要有一个通过即可 21 | */ 22 | private List authenticationHandlers; 23 | 24 | private List credentialToPrincipalResolvers; 25 | /** 26 | * 认证成功后处理对象。 27 | */ 28 | private KnightAuthenticationPostHandler authenticationPostHandler; 29 | 30 | 31 | 32 | @Override 33 | public KnightAuthentication authentication(KnightCredential credential) { 34 | //是否找到支持的凭据认证处理器 35 | boolean foundSupported = false; 36 | //是否认证通过 37 | boolean authenticated = false; 38 | if(credential == null){ 39 | logger.info("credential is null"); 40 | return null; 41 | } 42 | for(AuthenticationHandler handler : authenticationHandlers){ 43 | if(handler.supports(credential)){ 44 | foundSupported = true; 45 | authenticated = handler.authenticate(credential); 46 | if(authenticated){ 47 | break; 48 | } 49 | } 50 | } 51 | // 52 | boolean foundCrentialResolve = false; 53 | KnightUser user = null; 54 | if(foundSupported && authenticated){ 55 | 56 | for(CredentialToPrincipalResolver resolver:credentialToPrincipalResolvers){ 57 | //用户凭据解析器是否支持该凭据 58 | if(resolver.supports(credential)){ 59 | foundCrentialResolve = true; 60 | user = resolver.resolvePrincipal(credential); 61 | //若解析成功,则跳出循环 62 | if(user != null){ 63 | break; 64 | } 65 | } 66 | } 67 | 68 | } 69 | if(!foundCrentialResolve){ 70 | logger.error("not found any supported credentials resolvers"); 71 | throw new UnsupportedCredentialsException(); 72 | } 73 | 74 | 75 | return authenticationPostHandler.postAuthentication(credential,user); 76 | } 77 | 78 | public void setAuthenticationHandlers(List authenticationHandlers) { 79 | this.authenticationHandlers = authenticationHandlers; 80 | } 81 | 82 | public void setCredentialToPrincipalResolvers(List credentialToPrincipalResolvers) { 83 | this.credentialToPrincipalResolvers = credentialToPrincipalResolvers; 84 | } 85 | 86 | public void setAuthenticationPostHandler(KnightAuthenticationPostHandler authenticationPostHandler) { 87 | this.authenticationPostHandler = authenticationPostHandler; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/KnightAuthenticationPostHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication; 2 | 3 | /** 4 | * 认证成功后的处理器,该接口的职责是将用户认证主体,用户凭据转换为一个合适的认证结果对象 5 | * 根据用户凭据中的信息和参数进行合适的转换 6 | * @author zhenglu 7 | * @since 15/4/23 8 | */ 9 | public interface KnightAuthenticationPostHandler { 10 | 11 | 12 | /** 13 | * 服务本身的加密凭据信息存储在验证结果对象 服务端attrbutes动态属性key 14 | */ 15 | public static final String KNIGHT_SERVER_EC_KEY = "knight_ser_ec_key"; 16 | 17 | /** 18 | * 服务本身的加密凭据信息存储在验证结果对象 客户端attrbutes动态属性key 19 | */ 20 | public static final String KNIGHT_CLIENT_EC_KEY = "knight_client_ec_key"; 21 | 22 | /** 23 | * 认证后的处理方法,将用户的凭据和主体转换为一个认证的结果对象 24 | * @param credential 25 | * @param user 26 | * @return 27 | */ 28 | 29 | public KnightAuthentication postAuthentication(KnightCredential credential,KnightUser user); 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/KnightNamePasswordCredential.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication; 2 | 3 | /** 4 | * 用户名和密码形式的未经过认证的原始用户凭证 5 | * @author zhenglu 6 | * @since 15/4/27 7 | */ 8 | public class KnightNamePasswordCredential extends KnightAbstractParameter implements KnightCredential{ 9 | /** 10 | * 用户名 11 | */ 12 | private String username; 13 | 14 | /** 15 | * 密码 16 | */ 17 | 18 | private String password; 19 | 20 | public String getUsername() { 21 | return username; 22 | } 23 | 24 | public void setUsername(String username) { 25 | this.username = username; 26 | } 27 | 28 | public String getPassword() { 29 | return password; 30 | } 31 | 32 | public void setPassword(String password) { 33 | this.password = password; 34 | } 35 | 36 | @Override 37 | public boolean isOriginal() { 38 | return false; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/KnightUser.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication; 2 | 3 | import java.util.Map; 4 | /** 5 | * 用户主体,代表一个用户 6 | * @author zhenglu 7 | * @since 15/4/23 8 | */ 9 | public interface KnightUser { 10 | 11 | public Map getAttributes(); 12 | 13 | public String getId(); 14 | } 15 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/handlers/AbstractPreAndPostProcessingAuthenticationHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication.handlers; 2 | 3 | import com.github.ebnew.ki4so.core.authentication.KnightCredential; 4 | import com.github.ebnew.ki4so.core.exception.AuthenticationException; 5 | import com.github.ebnew.ki4so.core.exception.InvalidCredentialException; 6 | 7 | /** 8 | * 抽象的认证处理器实现,提供了具体实现类可以在认证之前和认证之后执行一些任务。 9 | * 10 | * @author burgess yang 11 | * 12 | */ 13 | public abstract class AbstractPreAndPostProcessingAuthenticationHandler 14 | implements AuthenticationHandler { 15 | /** 16 | * Method to execute before authentication occurs. 17 | * 18 | * @param credentials 19 | * the Credentials supplied 20 | * @return true if authentication should continue, false otherwise. 21 | */ 22 | protected boolean preAuthenticate(final KnightCredential credential) { 23 | return true; 24 | } 25 | 26 | /** 27 | * Method to execute after authentication occurs. 28 | * 29 | * @param credentials 30 | * the supplied credentials 31 | * @param authenticated 32 | * the result of the authentication attempt. 33 | * @return true if the handler should return true, false otherwise. 34 | */ 35 | protected boolean postAuthenticate(final KnightCredential credential, 36 | final boolean authenticated) { 37 | return authenticated; 38 | } 39 | 40 | public final boolean authenticate(final KnightCredential credential) 41 | throws AuthenticationException { 42 | 43 | if (!preAuthenticate(credential)) { 44 | return false; 45 | } 46 | 47 | final boolean authenticated = doAuthentication(credential); 48 | 49 | return postAuthenticate(credential, authenticated); 50 | } 51 | 52 | 53 | /** 54 | * 执行真正的认证方法。 55 | * @param credential 用户凭据。 56 | * @return 认证结果。 57 | * @throws InvalidCredentialException 58 | */ 59 | protected abstract boolean doAuthentication(final KnightCredential credential) 60 | throws AuthenticationException; 61 | 62 | } 63 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/handlers/AbstractUsernamePasswordAuthenticationHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication.handlers; 2 | 3 | import com.github.ebnew.ki4so.core.authentication.KnightCredential; 4 | import com.github.ebnew.ki4so.core.authentication.KnightNamePasswordCredential; 5 | import com.github.ebnew.ki4so.core.exception.AuthenticationException; 6 | 7 | /** 8 | * Abstract class to override supports so that we don't need to duplicate the 9 | * check for UsernamePasswordCredential. 用户名密码认证处理器的抽象实现类,复用了检查用户名密码凭据 10 | * 11 | * @author Scott Battaglia 12 | * @version $Revision$ $Date$ 13 | * @since 3.0 14 | *

15 | * This is a published and supported CAS Server 3 API. 16 | *

17 | */ 18 | public abstract class AbstractUsernamePasswordAuthenticationHandler extends 19 | AbstractPreAndPostProcessingAuthenticationHandler { 20 | 21 | /** Default class to support if one is not supplied. */ 22 | private static final Class DEFAULT_CLASS = KnightNamePasswordCredential.class; 23 | 24 | /** Class that this instance will support. */ 25 | private Class classToSupport = DEFAULT_CLASS; 26 | 27 | /** 28 | * Boolean to determine whether to support subclasses of the class to 29 | * support. 30 | */ 31 | private boolean supportSubClasses = true; 32 | 33 | /** 34 | * PasswordEncoder to be used by subclasses to encode passwords for 35 | * comparing against a resource. 36 | */ 37 | private PasswordEncoder passwordEncoder = new PlainTextPasswordEncoder(); 38 | 39 | /** 40 | * Method automatically handles conversion to UsernamePasswordCredentials 41 | * and delegates to abstract authenticateUsernamePasswordInternal so 42 | * subclasses do not need to cast. 43 | */ 44 | protected final boolean doAuthentication(final KnightCredential credential) 45 | throws AuthenticationException { 46 | return authenticateUsernamePasswordInternal((KnightNamePasswordCredential) credential); 47 | } 48 | 49 | /** 50 | * Abstract convenience method that assumes the credentials passed in are a 51 | * subclass of UsernamePasswordCredentials. 52 | * 53 | * @param credentials 54 | * the credentials representing the Username and Password 55 | * presented to CAS 56 | * @return true if the credentials are authentic, false otherwise. 57 | * @throws AuthenticationException 58 | * if authenticity cannot be determined. 59 | */ 60 | protected abstract boolean authenticateUsernamePasswordInternal( 61 | final KnightNamePasswordCredential credential) 62 | throws AuthenticationException; 63 | 64 | /** 65 | * Method to return the PasswordEncoder to be used to encode passwords. 66 | * 67 | * @return the PasswordEncoder associated with this class. 68 | */ 69 | protected final PasswordEncoder getPasswordEncoder() { 70 | return this.passwordEncoder; 71 | } 72 | 73 | /** 74 | * Method to set the class to support. 75 | * 76 | * @param classToSupport 77 | * the class we want this handler to support explicitly. 78 | */ 79 | public final void setClassToSupport(final Class classToSupport) { 80 | this.classToSupport = classToSupport; 81 | } 82 | 83 | /** 84 | * Method to set whether this handler will support subclasses of the 85 | * supported class. 86 | * 87 | * @param supportSubClasses 88 | * boolean of whether to support subclasses or not. 89 | */ 90 | public final void setSupportSubClasses(final boolean supportSubClasses) { 91 | this.supportSubClasses = supportSubClasses; 92 | } 93 | 94 | /** 95 | * Sets the PasswordEncoder to be used with this class. 96 | * 97 | * @param passwordEncoder 98 | * the PasswordEncoder to use when encoding passwords. 99 | */ 100 | public final void setPasswordEncoder(final PasswordEncoder passwordEncoder) { 101 | this.passwordEncoder = passwordEncoder; 102 | } 103 | 104 | /** 105 | * @return true if the credentials are not null and the credentials class is 106 | * equal to the class defined in classToSupport. 107 | */ 108 | public final boolean supports(final KnightCredential credential) { 109 | return credential != null 110 | && (this.classToSupport.equals(credential.getClass()) || (this.classToSupport 111 | .isAssignableFrom(credential.getClass())) 112 | && this.supportSubClasses); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/handlers/AuthenticationHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication.handlers; 2 | 3 | import com.github.ebnew.ki4so.core.authentication.KnightCredential; 4 | import com.github.ebnew.ki4so.core.exception.AuthenticationException; 5 | 6 | /** 7 | * 认证处理器类,该类检查用户的凭证是否合法。 8 | * @author Administrator 9 | * @version 1.0 10 | * @created 08-六月-2013 9:56:10 11 | */ 12 | public interface AuthenticationHandler { 13 | 14 | /** 15 | * 认证方法,返回true表示认证成功,false表示认证失败 16 | * 17 | * @param credential 用户凭据 18 | * @return 是否认证通过。 19 | * @throws ,则抛出合适的认证错误异常对象。 20 | */ 21 | public boolean authenticate(KnightCredential credential) throws AuthenticationException; 22 | 23 | /** 24 | * 是否支持用户凭证credential的认证处理,返回值true表示支持, 25 | * false表示不支持,若不支持该凭证,则忽略。 26 | * 27 | * @param credential 用户凭据 28 | */ 29 | public boolean supports(KnightCredential credential); 30 | 31 | } -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/handlers/DefaultPasswordEncoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Jasig under one or more contributor license 3 | * agreements. See the NOTICE file distributed with this work 4 | * for additional information regarding copyright ownership. 5 | * Jasig licenses this file to you under the Apache License, 6 | * Version 2.0 (the "License"); you may not use this file 7 | * except in compliance with the License. You may obtain a 8 | * copy of the License at the following location: 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.github.ebnew.ki4so.core.authentication.handlers; 20 | 21 | import java.io.UnsupportedEncodingException; 22 | import java.security.MessageDigest; 23 | import java.security.NoSuchAlgorithmException; 24 | 25 | import org.springframework.util.StringUtils; 26 | 27 | /** 28 | * Implementation of PasswordEncoder using message digest. Can accept any 29 | * message digest that the JDK can accept, including MD5 and SHA1. Returns the 30 | * equivalent Hash you would get from a Perl digest. 31 | * 32 | * @author Scott Battaglia 33 | * @author Stephen More 34 | * @version $Revision$ $Date$ 35 | * @since 3.1 36 | */ 37 | public final class DefaultPasswordEncoder implements PasswordEncoder { 38 | 39 | private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 40 | 41 | private final String encodingAlgorithm; 42 | 43 | private String characterEncoding; 44 | 45 | public DefaultPasswordEncoder(final String encodingAlgorithm) { 46 | this.encodingAlgorithm = encodingAlgorithm; 47 | } 48 | 49 | public String encode(final String password) { 50 | if (password == null) { 51 | return null; 52 | } 53 | 54 | try { 55 | MessageDigest messageDigest = MessageDigest 56 | .getInstance(this.encodingAlgorithm); 57 | 58 | if (StringUtils.hasText(this.characterEncoding)) { 59 | messageDigest.update(password.getBytes(this.characterEncoding)); 60 | } else { 61 | messageDigest.update(password.getBytes()); 62 | } 63 | 64 | 65 | final byte[] digest = messageDigest.digest(); 66 | 67 | return getFormattedText(digest); 68 | } catch (final NoSuchAlgorithmException e) { 69 | throw new SecurityException(e); 70 | } catch (final UnsupportedEncodingException e) { 71 | throw new RuntimeException(e); 72 | } 73 | } 74 | 75 | /** 76 | * Takes the raw bytes from the digest and formats them correct. 77 | * 78 | * @param bytes the raw bytes from the digest. 79 | * @return the formatted bytes. 80 | */ 81 | private String getFormattedText(byte[] bytes) { 82 | final StringBuilder buf = new StringBuilder(bytes.length * 2); 83 | 84 | for (int j = 0; j < bytes.length; j++) { 85 | buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]); 86 | buf.append(HEX_DIGITS[bytes[j] & 0x0f]); 87 | } 88 | return buf.toString(); 89 | } 90 | 91 | public final void setCharacterEncoding(final String characterEncoding) { 92 | this.characterEncoding = characterEncoding; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/handlers/EncryCredentialAuthenticationHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication.handlers; 2 | 3 | import com.github.ebnew.ki4so.core.authentication.KnightCredential; 4 | import com.github.ebnew.ki4so.core.authentication.KnightEncryCredential; 5 | import com.github.ebnew.ki4so.core.authentication.KnightEncryCredentialManager; 6 | import com.github.ebnew.ki4so.core.model.KnightCredentialInfo; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | 9 | import com.github.ebnew.ki4so.core.exception.AuthenticationException; 10 | import com.github.ebnew.ki4so.core.exception.InvalidEncryCredentialException; 11 | 12 | /** 13 | * 认证后的凭据认证处理器实现类,需要验证认证后的凭据是否有效,凭据是否过期等等其它 14 | * 合法性验证。 15 | * @author burgess yang 16 | * 17 | */ 18 | public class EncryCredentialAuthenticationHandler extends 19 | AbstractPreAndPostProcessingAuthenticationHandler { 20 | 21 | @Autowired 22 | private KnightEncryCredentialManager encryCredentialManager; 23 | 24 | public void setEncryCredentialManager( 25 | KnightEncryCredentialManager encryCredentialManager) { 26 | this.encryCredentialManager = encryCredentialManager; 27 | } 28 | 29 | /** Default class to support if one is not supplied. */ 30 | private static final Class DEFAULT_CLASS = KnightEncryCredential.class; 31 | 32 | 33 | 34 | 35 | @Override 36 | protected boolean doAuthentication(KnightCredential credential) throws AuthenticationException { 37 | //不支持的凭据直接返回false. 38 | if(!this.supports(credential)){ 39 | return false; 40 | } 41 | if(credential!=null && credential instanceof KnightEncryCredential){ 42 | KnightEncryCredential encryCredential = (KnightEncryCredential)credential; 43 | try{ 44 | //解密凭据信息。 45 | KnightCredentialInfo encryCredentialInfo = this.encryCredentialManager.decrypt(encryCredential); 46 | //设置凭据信息的关联性。 47 | if(encryCredentialInfo!=null){ 48 | encryCredential.setCredentialInfo(encryCredentialInfo); 49 | //检查加密凭据的合法性。 50 | return this.encryCredentialManager.checkEncryCredentialInfo(encryCredentialInfo); 51 | } 52 | }catch (InvalidEncryCredentialException e) { 53 | return false; 54 | } 55 | } 56 | return false; 57 | } 58 | 59 | /** 60 | * @return true if the credentials are not null and the credentials class is 61 | * equal to the class defined in classToSupport. 62 | */ 63 | @Override 64 | public boolean supports(KnightCredential credential) { 65 | return credential != null 66 | && (DEFAULT_CLASS.equals(credential.getClass()) || (DEFAULT_CLASS 67 | .isAssignableFrom(credential.getClass()))); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/handlers/PasswordEncoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Jasig under one or more contributor license 3 | * agreements. See the NOTICE file distributed with this work 4 | * for additional information regarding copyright ownership. 5 | * Jasig licenses this file to you under the Apache License, 6 | * Version 2.0 (the "License"); you may not use this file 7 | * except in compliance with the License. You may obtain a 8 | * copy of the License at the following location: 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.github.ebnew.ki4so.core.authentication.handlers; 20 | 21 | /** 22 | * Interface to provide a standard way to translate a plaintext password into a 23 | * different representation of that password so that the password may be 24 | * compared with the stored encrypted password without having to decode the 25 | * encrypted password. 26 | *

27 | * PasswordEncoders are useful because often the stored passwords are encoded 28 | * with a one way hash function which makes them almost impossible to decode. 29 | * 30 | * @author Scott Battaglia 31 | * @version $Revision$ $Date$ 32 | * @since 3.0 33 | *

34 | * This is a published and supported CAS Server 3 API. 35 | *

36 | */ 37 | public interface PasswordEncoder { 38 | 39 | /** 40 | * Method that actually performs the transformation of the plaintext 41 | * password into the encrypted password. 42 | * 43 | * @param password the password to translate 44 | * @return the transformed version of the password 45 | */ 46 | String encode(String password); 47 | } 48 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/handlers/PlainTextPasswordEncoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Jasig under one or more contributor license 3 | * agreements. See the NOTICE file distributed with this work 4 | * for additional information regarding copyright ownership. 5 | * Jasig licenses this file to you under the Apache License, 6 | * Version 2.0 (the "License"); you may not use this file 7 | * except in compliance with the License. You may obtain a 8 | * copy of the License at the following location: 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.github.ebnew.ki4so.core.authentication.handlers; 20 | 21 | /** 22 | * Default password encoder for the case where no password encoder is needed. 23 | * Encoding results in the same password that was passed in. 24 | * 25 | * @author Scott Battaglia 26 | * @version $Revision$ $Date$ 27 | * @since 3.0 28 | */ 29 | public final class PlainTextPasswordEncoder implements PasswordEncoder { 30 | 31 | public String encode(final String password) { 32 | return password; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/handlers/SimpleTestUsernamePasswordAuthenticationHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Jasig under one or more contributor license 3 | * agreements. See the NOTICE file distributed with this work 4 | * for additional information regarding copyright ownership. 5 | * Jasig licenses this file to you under the Apache License, 6 | * Version 2.0 (the "License"); you may not use this file 7 | * except in compliance with the License. You may obtain a 8 | * copy of the License at the following location: 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.github.ebnew.ki4so.core.authentication.handlers; 20 | 21 | import com.github.ebnew.ki4so.core.authentication.KnightNamePasswordCredential; 22 | import org.springframework.util.StringUtils; 23 | import com.github.ebnew.ki4so.core.exception.UsernameOrPasswordInvalidException; 24 | 25 | /** 26 | * Simple test implementation of a AuthenticationHandler that returns true if 27 | * the username and password match. This class should never be enabled in a 28 | * production environment and is only designed to facilitate unit testing and 29 | * load testing. 30 | * 31 | * @author Scott Battaglia 32 | * @version $Revision$ $Date$ 33 | * @since 3.0 34 | */ 35 | public final class SimpleTestUsernamePasswordAuthenticationHandler extends 36 | AbstractUsernamePasswordAuthenticationHandler { 37 | 38 | public SimpleTestUsernamePasswordAuthenticationHandler() { 39 | 40 | } 41 | 42 | @Override 43 | public boolean authenticateUsernamePasswordInternal( 44 | final KnightNamePasswordCredential credential) { 45 | final String username = credential.getUsername(); 46 | final String password = credential.getPassword(); 47 | 48 | if (StringUtils.hasText(username) && StringUtils.hasText(password) 49 | && username.equals(getPasswordEncoder().encode(password))) { 50 | return true; 51 | } 52 | throw UsernameOrPasswordInvalidException.INSTANCE; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/resolvers/CredentialToPrincipalResolver.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication.resolvers; 2 | 3 | import com.github.ebnew.ki4so.core.authentication.KnightCredential; 4 | import com.github.ebnew.ki4so.core.authentication.KnightUser; 5 | 6 | /** 7 | * 用户认证凭据转换为用户主体对象的解析器接口。 8 | * @author burgess yang 9 | * 10 | */ 11 | public interface CredentialToPrincipalResolver { 12 | 13 | /** 14 | * 将用户凭据转换为对应的用户主体对象。 15 | * @param 要转成用户主体的用户凭据对象。 16 | * @return 转换后的用户主体对象。 17 | */ 18 | KnightUser resolvePrincipal(KnightCredential credential); 19 | 20 | /** 21 | * 判断是否支持该用户凭据。 22 | * 23 | * @param 要检查的用户凭据。 24 | * @return true表示支持,false表示不支持。 25 | */ 26 | boolean supports(KnightCredential credential); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/resolvers/EncryCredentialToPrincipalResolver.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication.resolvers; 2 | 3 | import com.github.ebnew.ki4so.core.authentication.*; 4 | import com.github.ebnew.ki4so.core.model.KnightCredentialInfo; 5 | 6 | /** 7 | * 实现了加密后的凭据转换为对应的用户主体对象的解析器 8 | * 9 | * @author Administrator 10 | * 11 | */ 12 | public class EncryCredentialToPrincipalResolver implements CredentialToPrincipalResolver { 13 | 14 | /** 15 | * Default class to support if one is not supplied. 16 | */ 17 | private static final Class DEFAULT_CLASS = KnightCredential.class; 18 | 19 | /** 20 | * Class that this instance will support. 21 | */ 22 | private Class classToSupport = DEFAULT_CLASS; 23 | 24 | /** 25 | * Boolean to determine whether to support subclasses of the class to 26 | * support. 27 | */ 28 | private boolean supportSubClasses = true; 29 | 30 | public void setSupportSubClasses(boolean supportSubClasses) { 31 | this.supportSubClasses = supportSubClasses; 32 | } 33 | 34 | public KnightUser resolvePrincipal(KnightCredential credential) { 35 | //若类型匹配,则进行转换。 36 | if (credential != null && this.supports(credential)) { 37 | KnightEncryCredential encryCredential = (KnightEncryCredential) credential; 38 | DefaultKnightUser principal = new DefaultKnightUser(); 39 | //解析加密后凭据信息。 40 | KnightCredentialInfo encryCredentialInfo = encryCredential.getCredentialInfo(); 41 | //设置用户名为唯一标识。 42 | if (encryCredentialInfo != null) { 43 | principal.setId(encryCredentialInfo.getUserId()); 44 | //设置参数表为用户属性。 45 | principal.setAttributes(encryCredential.getParameters()); 46 | } 47 | return principal; 48 | } 49 | return null; 50 | } 51 | 52 | public boolean supports(KnightCredential credential) { 53 | return credential != null 54 | && (this.classToSupport.equals(credential.getClass()) || (this.classToSupport 55 | .isAssignableFrom(credential.getClass())) 56 | && this.supportSubClasses); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/resolvers/UsernamePasswordCredentialToPrincipalResolver.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication.resolvers; 2 | 3 | import com.github.ebnew.ki4so.core.authentication.DefaultKnightUser; 4 | import com.github.ebnew.ki4so.core.authentication.KnightCredential; 5 | import com.github.ebnew.ki4so.core.authentication.KnightNamePasswordCredential; 6 | import com.github.ebnew.ki4so.core.authentication.KnightUser; 7 | 8 | public class UsernamePasswordCredentialToPrincipalResolver implements CredentialToPrincipalResolver{ 9 | 10 | /** Default class to support if one is not supplied. */ 11 | private static final Class DEFAULT_CLASS = KnightNamePasswordCredential.class; 12 | 13 | /** Class that this instance will support. */ 14 | private Class classToSupport = DEFAULT_CLASS; 15 | 16 | /** 17 | * Boolean to determine whether to support subclasses of the class to 18 | * support. 19 | */ 20 | private boolean supportSubClasses = true; 21 | 22 | public void setSupportSubClasses(boolean supportSubClasses) { 23 | this.supportSubClasses = supportSubClasses; 24 | } 25 | 26 | @Override 27 | public KnightUser resolvePrincipal(KnightCredential credential) { 28 | //若类型匹配,则进行转换。 29 | if(credential!=null && this.supports(credential)){ 30 | KnightNamePasswordCredential usernamePasswordCredential = (KnightNamePasswordCredential)credential; 31 | DefaultKnightUser principal = new DefaultKnightUser(); 32 | //设置用户名为唯一标识。 33 | principal.setId(usernamePasswordCredential.getUsername()); 34 | //设置参数表为用户属性。 35 | principal.setAttributes(usernamePasswordCredential.getParameters()); 36 | return principal; 37 | } 38 | return null; 39 | } 40 | 41 | @Override 42 | public boolean supports(KnightCredential credential) { 43 | return credential != null 44 | && (this.classToSupport.equals(credential.getClass()) || (this.classToSupport 45 | .isAssignableFrom(credential.getClass())) 46 | && this.supportSubClasses); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/status/KnightDefaultUserLoginStatusStore.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication.status; 2 | 3 | import com.github.ebnew.ki4so.common.utils.StringUtils; 4 | 5 | import java.util.*; 6 | 7 | /** 8 | * 用户登录状态存储器 默认实现类 9 | * @author zhenglu 10 | * @since 15/4/28 11 | */ 12 | public class KnightDefaultUserLoginStatusStore implements KnightUserLoggedStatusStore { 13 | 14 | 15 | /** 16 | * 用户登录状态,不允许重复状态值 17 | */ 18 | private Set loginStatuses = new HashSet(); 19 | 20 | 21 | /** 22 | * 用户标识和用户状态列表质检的映射表,相当于一个索引,方便根据用户标识查询所有的登录状态标。 23 | * 其中map中key为用户标识,value是该用户所有的登录状态列表 24 | */ 25 | private Map> userIndexMap = new HashMap>(); 26 | 27 | public Set getLoginStatuses() { 28 | return loginStatuses; 29 | } 30 | 31 | public Map> getUserIndexMap() { 32 | return userIndexMap; 33 | } 34 | 35 | @Override 36 | public synchronized void addUserLoggerStatus(KnightUserLoginStatus userLoginStatus) { 37 | 38 | if(userLoginStatus != null && !StringUtils.isEmpty(userLoginStatus.getUserId()) && !StringUtils.isEmpty(userLoginStatus.getAppId())){ 39 | if(userLoginStatus.getLoginDate() == null){ 40 | userLoginStatus.setLoginDate(new Date()); 41 | } 42 | this.loginStatuses.add(userLoginStatus); 43 | List list = this.userIndexMap.get(userLoginStatus.getUserId()); 44 | if(list == null){ 45 | list = new ArrayList(); 46 | this.userIndexMap.put(userLoginStatus.getUserId(),list); 47 | } 48 | list.add(userLoginStatus); 49 | } 50 | 51 | } 52 | 53 | @Override 54 | public synchronized void deleteUserLoginStatus(String userId, String appId) { 55 | //验证数据合法性 56 | if(!StringUtils.isEmpty(userId) && !StringUtils.isEmpty(appId)){ 57 | KnightUserLoginStatus status = new KnightUserLoginStatus(); 58 | status.setUserId(userId); 59 | status.setAppId(appId); 60 | this.loginStatuses.remove(status); 61 | List list = this.userIndexMap.get(userId); 62 | if(list != null){ 63 | list.remove(status); 64 | } 65 | } 66 | 67 | } 68 | 69 | @Override 70 | public synchronized void clearUpUserLoginStatus(String userId) { 71 | if(!StringUtils.isEmpty(userId)){ 72 | List list = this.userIndexMap.get(userId); 73 | if(list != null){ 74 | list.clear(); 75 | this.userIndexMap.put(userId,null); 76 | } 77 | } 78 | 79 | } 80 | 81 | @Override 82 | public List findUserLoginStatus(String userId) { 83 | if(!StringUtils.isEmpty(userId)){ 84 | return this.userIndexMap.get(userId); 85 | } 86 | return null; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/status/KnightUserLoggedStatusStore.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication.status; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 用户登录状态存储器,实现了用户登录状态的存取方法 7 | * @author zhenglu 8 | * @since 15/4/28 9 | */ 10 | public interface KnightUserLoggedStatusStore { 11 | 12 | 13 | /** 14 | * 增加新的用户登录状态 15 | * @param userLoginStatus 16 | */ 17 | public void addUserLoggerStatus(KnightUserLoginStatus userLoginStatus); 18 | 19 | /** 20 | * 删除用户登录状态 21 | * @param userId 22 | * @param appId 23 | */ 24 | public void deleteUserLoginStatus(String userId,String appId); 25 | 26 | 27 | /** 28 | * 清楚某个用户所有的登录状态 29 | * @param userId 30 | */ 31 | public void clearUpUserLoginStatus(String userId); 32 | 33 | 34 | /** 35 | * 根据用户标识查询所有的登录状态 36 | * @param userId 37 | * @return 38 | */ 39 | public List findUserLoginStatus(String userId); 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/authentication/status/KnightUserLoginStatus.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication.status; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | /** 7 | * 用户登录状态 8 | * @author zhenglu 9 | * @since 15/4/28 10 | */ 11 | public class KnightUserLoginStatus implements Serializable{ 12 | 13 | 14 | private static final long serialVersionUID = 8453108828607661563L; 15 | /** 16 | * 登录用户的标识 17 | */ 18 | private String userId; 19 | 20 | /** 21 | * 用户登录的应用标识 22 | */ 23 | 24 | private String appId; 25 | 26 | /** 27 | * 登录应用的时间 28 | */ 29 | 30 | private Date loginDate; 31 | 32 | 33 | public String getUserId() { 34 | return userId; 35 | } 36 | 37 | public void setUserId(String userId) { 38 | this.userId = userId; 39 | } 40 | 41 | public String getAppId() { 42 | return appId; 43 | } 44 | 45 | public void setAppId(String appId) { 46 | this.appId = appId; 47 | } 48 | 49 | public Date getLoginDate() { 50 | return loginDate; 51 | } 52 | 53 | public void setLoginDate(Date loginDate) { 54 | this.loginDate = loginDate; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/dao/fs/KnightFileSystemDao.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.dao.fs; 2 | 3 | import com.github.ebnew.ki4so.common.utils.StringUtils; 4 | import org.apache.log4j.Logger; 5 | import org.springframework.core.io.ClassPathResource; 6 | import org.springframework.core.io.Resource; 7 | 8 | import java.io.ByteArrayOutputStream; 9 | import java.io.FileInputStream; 10 | import java.io.InputStream; 11 | 12 | /** 13 | * @author zhenglu 14 | * @since 15/4/24 15 | */ 16 | public abstract class KnightFileSystemDao { 17 | 18 | private static final Logger logger = Logger.getLogger(KnightFileSystemDao.class); 19 | /** 20 | * 外部数据文件地址,优先级更高 21 | */ 22 | protected String externalData = null; 23 | 24 | /** 25 | * 默认的数据文件地址,在classpath下 26 | */ 27 | 28 | protected String classPathData = null; 29 | 30 | public String getClassPathData() { 31 | return classPathData; 32 | } 33 | 34 | public String getExternalData() { 35 | return externalData; 36 | } 37 | 38 | /** 39 | * 重新设置外部数据路径 40 | * 设置成功后,需要触发重新假装数据内容 41 | * @param externalData 42 | */ 43 | public void setExternalData(String externalData){ 44 | if(externalData != null && externalData.length() > 0 ){ 45 | //外部数据文件路径不同,需要重新加载 46 | if(!externalData.equals(this.externalData)){ 47 | this.externalData = externalData; 48 | 49 | loadAppData(); 50 | } 51 | }else { 52 | if(this.externalData != null && this.externalData.length() > 0 ){ 53 | this.loadAppData(); 54 | } 55 | } 56 | } 57 | 58 | /** 59 | * 从数据文件中加载数据,抽象方法,具体子类实现逻辑 60 | */ 61 | protected abstract void loadAppData(); 62 | 63 | public String readDataFromFile(){ 64 | 65 | try{ 66 | InputStream inputStream = null; 67 | //优先使用外部数据文件 68 | if(!StringUtils.isEmpty(this.getExternalData())){ 69 | inputStream = new FileInputStream(this.getExternalData()); 70 | } 71 | if(inputStream == null){ 72 | if(!StringUtils.isEmpty(this.getClassPathData())){ 73 | Resource resource = new ClassPathResource(this.getClassPathData()); 74 | inputStream = resource.getInputStream(); 75 | } 76 | } 77 | if(inputStream != null){ 78 | return new String(readStream(inputStream)); 79 | } 80 | 81 | 82 | }catch (Exception e){ 83 | logger.error("readDataFromFile has error :" + e.getMessage()); 84 | } 85 | 86 | return null; 87 | 88 | 89 | } 90 | 91 | public static byte[] readStream(InputStream inputStream){ 92 | try{ 93 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 94 | byte[] buffer = new byte[1024]; 95 | int len = -1; 96 | while((len = inputStream.read(buffer)) != -1){ 97 | outputStream.write(buffer,0,len); 98 | } 99 | outputStream.close(); 100 | inputStream.close(); 101 | return outputStream.toByteArray(); 102 | 103 | }catch (Exception e){ 104 | logger.error("readStream has error::" +e.getMessage()); 105 | } 106 | return null; 107 | } 108 | 109 | 110 | } 111 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/message/MessageUtils.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.message; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import com.github.ebnew.ki4so.core.exception.EmptyCredentialException; 7 | import com.github.ebnew.ki4so.core.exception.InvalidCredentialException; 8 | import com.github.ebnew.ki4so.core.exception.InvalidEncryCredentialException; 9 | import com.github.ebnew.ki4so.core.exception.NoAuthenticationPostHandlerException; 10 | import com.github.ebnew.ki4so.core.exception.NoKi4soKeyException; 11 | import com.github.ebnew.ki4so.core.exception.PasswordInvalidException; 12 | import com.github.ebnew.ki4so.core.exception.UnsupportedCredentialsException; 13 | import com.github.ebnew.ki4so.core.exception.UsernameOrPasswordEmptyException; 14 | import com.github.ebnew.ki4so.core.exception.UsernameOrPasswordInvalidException; 15 | 16 | /** 17 | * 使用简单的国际化策略,只支持中文,以后可以改成更加灵活的 18 | * 能够支持多种语言的消息提示。 19 | * @author burgess yang 20 | * 21 | */ 22 | public class MessageUtils { 23 | 24 | /** 25 | * 信息表,其中key是消息键,value是具体对应的中文的消息内容。 26 | */ 27 | private static Map msgMap = null; 28 | 29 | static{ 30 | //初始化消息表。 31 | msgMap = new HashMap(); 32 | msgMap.put(InvalidCredentialException.MSG_KEY, "不合法的凭据"); 33 | msgMap.put(InvalidEncryCredentialException.MSG_KEY, "不合法的加密凭据"); 34 | msgMap.put(UsernameOrPasswordEmptyException.MSG_KEY, "用户名或者密码为空"); 35 | msgMap.put(UsernameOrPasswordInvalidException.MSG_KEY, "用户名或者密码不正确"); 36 | msgMap.put(PasswordInvalidException.MSG_KEY, "密码错误"); 37 | msgMap.put(EmptyCredentialException.MSG_KEY, "凭据为空"); 38 | msgMap.put(UnsupportedCredentialsException.MSG_KEY, "不支持的用户凭据"); 39 | msgMap.put(NoAuthenticationPostHandlerException.MSG_KEY, "无合法的认证后处理器"); 40 | msgMap.put(NoKi4soKeyException.MSG_KEY, "系统没有配置ki4so服务器本身的key信息,请检查配置。"); 41 | } 42 | 43 | 44 | /** 45 | * 查询消息键对应的消息提示内容。 46 | * @param key 消息键 47 | * @return 消息内容。 48 | */ 49 | public static String getMessage(String key){ 50 | return msgMap.get(key); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/service/KnightService.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.service; 2 | 3 | import com.github.ebnew.ki4so.core.app.KnightApp; 4 | import com.github.ebnew.ki4so.core.authentication.KnightCredential; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * 核心服务接口,定义了所有的核心方法 10 | * 该接口是一个门面类,也定义了对外提供的方法 11 | * @author zhenglu 12 | * @since 15/4/29 13 | */ 14 | public interface KnightService { 15 | 16 | /** 17 | * 利用用户凭据登录knight中心服务 18 | * @param credential 19 | * @return 20 | */ 21 | public LoginResult login(KnightCredential credential); 22 | 23 | /** 24 | * 获得 25 | * @param credential 26 | * @return 27 | */ 28 | 29 | public List getAppList(KnightCredential credential); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/service/KnightServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.service; 2 | 3 | import com.github.ebnew.ki4so.core.app.KnightApp; 4 | import com.github.ebnew.ki4so.core.app.KnightAppService; 5 | import com.github.ebnew.ki4so.core.authentication.KnightAuthentication; 6 | import com.github.ebnew.ki4so.core.authentication.KnightAuthenticationManager; 7 | import com.github.ebnew.ki4so.core.authentication.KnightCredential; 8 | import com.github.ebnew.ki4so.core.authentication.status.KnightUserLoggedStatusStore; 9 | import com.github.ebnew.ki4so.core.authentication.status.KnightUserLoginStatus; 10 | import org.apache.log4j.Logger; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | /** 16 | * @author zhenglu 17 | * @since 15/4/29 18 | */ 19 | public class KnightServiceImpl implements KnightService { 20 | private Logger logger = Logger.getLogger(KnightServiceImpl.class); 21 | 22 | private KnightAuthenticationManager authenticationManager; 23 | 24 | private KnightAppService appService; 25 | 26 | private KnightUserLoggedStatusStore userLoggedStatusStore; 27 | 28 | @Override 29 | public LoginResult login(KnightCredential credential) { 30 | //若没有凭据,则返回空 31 | if(credential == null){ 32 | return null; 33 | } 34 | LoginResult result = new LoginResult(); 35 | result.setSuccess(false); 36 | //调用认证处理器进行认证 37 | try{ 38 | KnightAuthentication authentication = authenticationManager.authentication(credential); 39 | result.setSuccess(authentication != null?true :false); 40 | result.setAuthentication(authentication); 41 | 42 | }catch (Exception e){ 43 | result.setCode("authentication failure"); 44 | result.setMsgKey("authentiaction key"); 45 | logger.error("authentication failure ::" + e.getMessage()); 46 | 47 | } 48 | 49 | return result; 50 | } 51 | 52 | @Override 53 | public List getAppList(KnightCredential credential) { 54 | List apps = new ArrayList(); 55 | if(credential == null){ 56 | return null; 57 | } 58 | try{ 59 | KnightAuthentication authentication = authenticationManager.authentication(credential); 60 | if(authentication != null && authentication.getUser() != null){ 61 | List statusList = this.userLoggedStatusStore.findUserLoginStatus(authentication.getUser().getId()); 62 | //批量查询对应的应用信息 63 | if(statusList != null && statusList.size() >0){ 64 | for(KnightUserLoginStatus status :statusList){ 65 | KnightApp app = appService.findAppById(status.getAppId()); 66 | if(app != null){ 67 | apps.add(app); 68 | } 69 | } 70 | } 71 | } 72 | 73 | }catch (Exception e){ 74 | logger.error("when find knightApp has error::"+e.getMessage()); 75 | } 76 | 77 | return apps; 78 | } 79 | 80 | public void setAuthenticationManager(KnightAuthenticationManager authenticationManager) { 81 | this.authenticationManager = authenticationManager; 82 | } 83 | 84 | public void setAppService(KnightAppService appService) { 85 | this.appService = appService; 86 | } 87 | 88 | public void setUserLoggedStatusStore(KnightUserLoggedStatusStore userLoggedStatusStore) { 89 | this.userLoggedStatusStore = userLoggedStatusStore; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/service/LoginResult.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.service; 2 | 3 | import java.io.Serializable; 4 | 5 | import com.github.ebnew.ki4so.core.authentication.KnightAuthentication; 6 | 7 | /** 8 | * 登录结果对象。 9 | * @author burgess yang 10 | * 11 | */ 12 | public class LoginResult implements Serializable{ 13 | 14 | /** 15 | * 16 | */ 17 | private static final long serialVersionUID = 2497393519640031346L; 18 | 19 | /** 20 | * 认证是否成功, 21 | */ 22 | private boolean success; 23 | 24 | /** 25 | * 认证失败的错误代码。 26 | */ 27 | private String code; 28 | 29 | 30 | /** 31 | * 认证失败的错误提示信息键值。 32 | */ 33 | private String msgKey; 34 | 35 | /** 36 | * 认证结果信息对象。 37 | */ 38 | private KnightAuthentication authentication; 39 | 40 | 41 | public boolean isSuccess() { 42 | return success; 43 | } 44 | 45 | 46 | public void setSuccess(boolean success) { 47 | this.success = success; 48 | } 49 | 50 | 51 | public String getCode() { 52 | return code; 53 | } 54 | 55 | 56 | public void setCode(String code) { 57 | this.code = code; 58 | } 59 | 60 | 61 | public String getMsgKey() { 62 | return msgKey; 63 | } 64 | 65 | 66 | public void setMsgKey(String msgKey) { 67 | this.msgKey = msgKey; 68 | } 69 | 70 | public KnightAuthentication getAuthentication() { 71 | return authentication; 72 | } 73 | 74 | public void setAuthentication(KnightAuthentication authentication) { 75 | this.authentication = authentication; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/service/LogoutAppService.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.service; 2 | 3 | public interface LogoutAppService { 4 | 5 | /** 6 | * 登出用户ID为userId的用户,登出该用户已经登录过的所有用户。 7 | * 而service值对应的应用应该优先登出。 8 | * @param userId 用户ID。 9 | * @param service 用户优先登出的URL地址。 10 | */ 11 | public void logoutApp(final String userId, final String service); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /ki4so-core/src/main/java/com/github/ebnew/ki4so/core/service/LogoutService.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.service; 2 | 3 | 4 | /** 5 | * 统一登出接口,该接口主要负责服务端统一登出sso登录的所有业务应用。 6 | * 7 | * @author ywbrj042 8 | */ 9 | public interface LogoutService { 10 | 11 | /** 12 | * 统一退出所有登录的业务应用接口。 13 | * @param userId 用户ID. 14 | * @param servcie 登出之后要跳转的URL地址,要同步登出该URL对应的应用。 15 | */ 16 | public void logout(String userId, String servcie); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /ki4so-core/src/main/resources/apps.js: -------------------------------------------------------------------------------- 1 | [ 2 | {appId:"1", appName:"ki4so", ki4soServer:true}, 3 | {appId:"1001", appName:"ki4so-app", host:"http://localhost:8080/ki4so-app", logoutUrl:"http://localhost:8080/ki4so-app/logout.do"} 4 | ] -------------------------------------------------------------------------------- /ki4so-core/src/main/resources/keys.js: -------------------------------------------------------------------------------- 1 | [ 2 | {keyId:"1", appId:"1", value:"d#@$%Dfdsadadf", keyPath:""}, 3 | {keyId:"2", appId:"1001", value:"a4323##@0D#@", keyPath:"E:/"} 4 | ] -------------------------------------------------------------------------------- /ki4so-core/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=DEBUG, stdout 2 | 3 | # Direct log messages to stdout 4 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 5 | log4j.appender.stdout.Target=System.out 6 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n -------------------------------------------------------------------------------- /ki4so-core/src/test/java/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /ki4so-core/src/test/java/README.md: -------------------------------------------------------------------------------- 1 | ki4so-core的测试包。 -------------------------------------------------------------------------------- /ki4so-core/src/test/java/com/github/ebnew/ki4so/core/TestUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Jasig under one or more contributor license 3 | * agreements. See the NOTICE file distributed with this work 4 | * for additional information regarding copyright ownership. 5 | * Jasig licenses this file to you under the Apache License, 6 | * Version 2.0 (the "License"); you may not use this file 7 | * except in compliance with the License. You may obtain a 8 | * copy of the License at the following location: 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.github.ebnew.ki4so.core; 20 | 21 | import com.github.ebnew.ki4so.core.authentication.UsernamePasswordCredential; 22 | 23 | /** 24 | * @author Scott Battaglia 25 | * @version $Revision$ $Date$ 26 | * @since 3.0.2 27 | */ 28 | public final class TestUtils { 29 | 30 | public static final String CONST_USERNAME = "test"; 31 | 32 | private static final String CONST_PASSWORD = "test1"; 33 | 34 | public static final String CONST_EXCEPTION_EXPECTED = "Exception expected."; 35 | 36 | public static final String CONST_EXCEPTION_NON_EXPECTED = "Exception not expected."; 37 | 38 | public static final String CONST_GOOD_URL = "https://github.com/"; 39 | 40 | private TestUtils() { 41 | // do not instanciate 42 | } 43 | 44 | public static UsernamePasswordCredential getCredentialsWithSameUsernameAndPassword() { 45 | return getCredentialsWithSameUsernameAndPassword(CONST_USERNAME); 46 | } 47 | 48 | public static UsernamePasswordCredential getCredentialsWithSameUsernameAndPassword( 49 | final String username) { 50 | return getCredentialsWithDifferentUsernameAndPassword(username, 51 | username); 52 | } 53 | 54 | public static UsernamePasswordCredential getCredentialsWithDifferentUsernameAndPassword() { 55 | return getCredentialsWithDifferentUsernameAndPassword(CONST_USERNAME, 56 | CONST_PASSWORD); 57 | } 58 | 59 | public static UsernamePasswordCredential getCredentialsWithDifferentUsernameAndPassword( 60 | final String username, final String password) { 61 | // noinspection LocalVariableOfConcreteClass 62 | final UsernamePasswordCredential usernamePasswordCredentials = new UsernamePasswordCredential(); 63 | usernamePasswordCredentials.setUsername(username); 64 | usernamePasswordCredentials.setPassword(password); 65 | 66 | return usernamePasswordCredentials; 67 | } 68 | 69 | 70 | 71 | } 72 | -------------------------------------------------------------------------------- /ki4so-core/src/test/java/com/github/ebnew/ki4so/core/authentication/EncryCredentialManagerImplTest.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication; 2 | 3 | import java.util.Date; 4 | 5 | import junit.framework.Assert; 6 | 7 | import org.junit.After; 8 | import org.junit.Before; 9 | import org.junit.Test; 10 | 11 | import com.github.ebnew.ki4so.core.exception.InvalidEncryCredentialException; 12 | import com.github.ebnew.ki4so.core.model.EncryCredentialInfo; 13 | 14 | public class EncryCredentialManagerImplTest { 15 | 16 | EncryCredentialManagerImpl encryCredentialManager; 17 | 18 | @Before 19 | public void setUp() throws Exception { 20 | encryCredentialManager = new EncryCredentialManagerImpl(); 21 | } 22 | 23 | @After 24 | public void tearDown() throws Exception { 25 | encryCredentialManager = null; 26 | } 27 | 28 | /** 29 | * 测试解密方法。 30 | */ 31 | @Test 32 | public void testDecrypt(){ 33 | //测试异常输入情况。 34 | Assert.assertNull(encryCredentialManager.decrypt(null)); 35 | 36 | EncryCredential encryCredential = new EncryCredential(""); 37 | Assert.assertNull(encryCredentialManager.decrypt(encryCredential)); 38 | 39 | //错误的凭据格式。 40 | encryCredential = new EncryCredential("error"); 41 | try{ 42 | encryCredentialManager.decrypt(encryCredential); 43 | Assert.fail("should throw excption"); 44 | }catch (InvalidEncryCredentialException e) { 45 | // TODO: handle exception 46 | } 47 | 48 | //测试正常情况。 49 | EncryCredentialInfo encryCredentialInfo = buildTextEncryCredentialInfo(); 50 | String result = encryCredentialManager.encrypt(encryCredentialInfo); 51 | encryCredentialManager.decrypt(new EncryCredential(result)); 52 | } 53 | 54 | /** 55 | * 测试加密方法。 56 | */ 57 | @Test 58 | public void testEncrypt(){ 59 | //测试对null加密的情况,返回''。 60 | Assert.assertEquals(0, encryCredentialManager.encrypt(null).length()); 61 | 62 | //测试正确情况。 63 | String result = encryCredentialManager.encrypt(buildTextEncryCredentialInfo()); 64 | Assert.assertNotNull(result); 65 | } 66 | 67 | private EncryCredentialInfo buildTextEncryCredentialInfo(){ 68 | EncryCredentialInfo encryCredentialInfo = new EncryCredentialInfo(); 69 | encryCredentialInfo.setAppId("1"); 70 | Date createTime = new Date(); 71 | encryCredentialInfo.setCreateTime(createTime); 72 | Date expiredTime = new Date(); 73 | encryCredentialInfo.setExpiredTime(expiredTime); 74 | encryCredentialInfo.setKeyId("333"); 75 | encryCredentialInfo.setUserId("wubingyang"); 76 | return encryCredentialInfo; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /ki4so-core/src/test/java/com/github/ebnew/ki4so/core/authentication/app/AppServiceImplTest.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication.app; 2 | 3 | import junit.framework.Assert; 4 | 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | import com.github.ebnew.ki4so.core.app.App; 10 | import com.github.ebnew.ki4so.core.app.AppServiceImpl; 11 | 12 | public class AppServiceImplTest { 13 | 14 | private AppServiceImpl appServiceImpl; 15 | 16 | @Before 17 | public void setUp() throws Exception { 18 | appServiceImpl = new AppServiceImpl(); 19 | } 20 | 21 | @After 22 | public void tearDown() throws Exception { 23 | } 24 | 25 | @Test 26 | public void testFindAppById() { 27 | Assert.assertNull(appServiceImpl.findAppById("")); 28 | Assert.assertNull(appServiceImpl.findAppById(null)); 29 | 30 | Assert.assertNull(appServiceImpl.findAppById("not exsited")); 31 | 32 | App app = appServiceImpl.findAppById("1001"); 33 | Assert.assertNotNull(app); 34 | Assert.assertEquals("http://localhost:8080/ki4so-app/", app.getHost()); 35 | System.out.println(app); 36 | } 37 | 38 | @Test 39 | public void testFindKi4soServerApp() { 40 | App app = appServiceImpl.findKi4soServerApp(); 41 | Assert.assertNotNull(app); 42 | System.out.println(app); 43 | } 44 | 45 | @Test 46 | public void testFindAppByHost() { 47 | //查询异常情况。 48 | Assert.assertNull(appServiceImpl.findAppByHost("")); 49 | Assert.assertNull(appServiceImpl.findAppByHost(null)); 50 | 51 | Assert.assertNull(appServiceImpl.findAppByHost("ddddddddddd")); 52 | 53 | //查询带斜线和不带斜线的情况。 54 | App app = appServiceImpl.findAppByHost("http://localhost:8080/ki4so-app/"); 55 | Assert.assertNotNull(app); 56 | Assert.assertEquals("1001", app.getAppId()); 57 | 58 | app = appServiceImpl.findAppByHost("http://localhost:8080/ki4so-app"); 59 | Assert.assertNotNull(app); 60 | Assert.assertEquals("1001", app.getAppId()); 61 | 62 | app = appServiceImpl.findAppByHost("http://localhost:8080/ki4so-app/dafdasfdas"); 63 | Assert.assertNotNull(app); 64 | Assert.assertEquals("1001", app.getAppId()); 65 | 66 | app = appServiceImpl.findAppByHost("http://localhost:8080/ki4so-app/hell/w3d.htm?a=b"); 67 | Assert.assertNotNull(app); 68 | Assert.assertEquals("1001", app.getAppId()); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /ki4so-core/src/test/java/com/github/ebnew/ki4so/core/authentication/handlers/DefaultPasswordEncoderTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Jasig under one or more contributor license 3 | * agreements. See the NOTICE file distributed with this work 4 | * for additional information regarding copyright ownership. 5 | * Jasig licenses this file to you under the Apache License, 6 | * Version 2.0 (the "License"); you may not use this file 7 | * except in compliance with the License. You may obtain a 8 | * copy of the License at the following location: 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.github.ebnew.ki4so.core.authentication.handlers; 20 | 21 | import junit.framework.TestCase; 22 | 23 | /** 24 | * @author Scott Battaglia 25 | * @version $Revision$ $Date$ 26 | * @since 3.0 27 | */ 28 | public final class DefaultPasswordEncoderTests extends TestCase { 29 | 30 | private final PasswordEncoder passwordEncoder = new DefaultPasswordEncoder("MD5"); 31 | 32 | public void testNullPassword() { 33 | assertEquals(null, this.passwordEncoder.encode(null)); 34 | } 35 | 36 | public void testMd5Hash() { 37 | assertEquals("1f3870be274f6c49b3e31a0c6728957f", this.passwordEncoder 38 | .encode("apple")); 39 | } 40 | 41 | public void testSha1Hash() { 42 | final PasswordEncoder pe = new DefaultPasswordEncoder("SHA1"); 43 | 44 | final String hash = pe.encode("this is a test"); 45 | 46 | assertEquals("fa26be19de6bff93f70bc2308434e4a440bbad02", hash); 47 | 48 | } 49 | 50 | public void testSha1Hash2() { 51 | final PasswordEncoder pe = new DefaultPasswordEncoder("SHA1"); 52 | 53 | final String hash = pe.encode("TEST of the SYSTEM"); 54 | 55 | assertEquals("82ae28dfad565dd9882b94498a271caa29025d5f", hash); 56 | 57 | } 58 | 59 | public void testInvalidEncodingType() { 60 | final PasswordEncoder pe = new DefaultPasswordEncoder("scott"); 61 | try { 62 | pe.encode("test"); 63 | fail("exception expected."); 64 | } catch (final Exception e) { 65 | return; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /ki4so-core/src/test/java/com/github/ebnew/ki4so/core/authentication/handlers/EncryCredentialAuthenticationHandlerTest.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication.handlers; 2 | 3 | import junit.framework.Assert; 4 | 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | import org.mockito.Mockito; 9 | 10 | import com.github.ebnew.ki4so.core.authentication.Credential; 11 | import com.github.ebnew.ki4so.core.authentication.EncryCredential; 12 | import com.github.ebnew.ki4so.core.authentication.EncryCredentialManager; 13 | import com.github.ebnew.ki4so.core.exception.InvalidEncryCredentialException; 14 | import com.github.ebnew.ki4so.core.model.EncryCredentialInfo; 15 | 16 | /** 17 | * 测试加密后凭据认证处理器对象。 18 | * @author burgess yang 19 | * 20 | */ 21 | public class EncryCredentialAuthenticationHandlerTest { 22 | 23 | private EncryCredentialAuthenticationHandler handler; 24 | 25 | @Before 26 | public void setUp() throws Exception { 27 | handler = new EncryCredentialAuthenticationHandler(); 28 | } 29 | 30 | @After 31 | public void tearDown() throws Exception { 32 | } 33 | 34 | @Test 35 | public void testDoAuthentication() { 36 | 37 | /** 38 | * 测试异常输入情况。 39 | */ 40 | Assert.assertFalse(handler.authenticate(null)); 41 | Credential credential = Mockito.mock(Credential.class); 42 | Assert.assertFalse(handler.authenticate(credential)); 43 | 44 | /** 45 | * 测试解密失败抛出异常的情况。 46 | */ 47 | EncryCredential encryCredential = new EncryCredential("sssddaf"); 48 | EncryCredentialManager encryCredentialManager = Mockito.mock(EncryCredentialManager.class); 49 | this.handler.setEncryCredentialManager(encryCredentialManager); 50 | Mockito.when(encryCredentialManager.decrypt(encryCredential)).thenThrow(InvalidEncryCredentialException.INSTANCE); 51 | Assert.assertFalse(handler.authenticate(encryCredential)); 52 | 53 | /** 54 | * 测试解密返回null的情况。 55 | */ 56 | Mockito.reset(encryCredentialManager); 57 | Mockito.when(encryCredentialManager.decrypt(encryCredential)).thenReturn(null); 58 | Assert.assertFalse(handler.authenticate(encryCredential)); 59 | 60 | /** 61 | * 测试解密成功,但是凭据不合法的情况。 62 | */ 63 | Mockito.reset(encryCredentialManager); 64 | EncryCredentialInfo encryCredentialInfo = new EncryCredentialInfo(); 65 | Mockito.when(encryCredentialManager.decrypt(encryCredential)).thenReturn(encryCredentialInfo); 66 | Assert.assertFalse(handler.authenticate(encryCredential)); 67 | 68 | 69 | /** 70 | * 测试解密成功,但是凭据合法的情况。 71 | */ 72 | Mockito.reset(encryCredentialManager); 73 | encryCredentialInfo = new EncryCredentialInfo(); 74 | Mockito.when(encryCredentialManager.decrypt(encryCredential)).thenReturn(encryCredentialInfo); 75 | Mockito.when(encryCredentialManager.checkEncryCredentialInfo(encryCredentialInfo)).thenReturn(true); 76 | Assert.assertTrue(handler.authenticate(encryCredential)); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /ki4so-core/src/test/java/com/github/ebnew/ki4so/core/authentication/handlers/PlainTextPasswordEncoderTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Jasig under one or more contributor license 3 | * agreements. See the NOTICE file distributed with this work 4 | * for additional information regarding copyright ownership. 5 | * Jasig licenses this file to you under the Apache License, 6 | * Version 2.0 (the "License"); you may not use this file 7 | * except in compliance with the License. You may obtain a 8 | * copy of the License at the following location: 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.github.ebnew.ki4so.core.authentication.handlers; 20 | 21 | import junit.framework.TestCase; 22 | 23 | /** 24 | * @author Scott Battaglia 25 | * @version $Revision$ $Date$ 26 | * @since 3.0 27 | */ 28 | public final class PlainTextPasswordEncoderTests extends TestCase { 29 | 30 | private final PasswordEncoder passwordEncoder = new PlainTextPasswordEncoder(); 31 | 32 | private final static String CONST_TO_ENCODE = "ki4so is cool"; 33 | 34 | public void testNullValueToTranslate() { 35 | assertEquals(null, this.passwordEncoder.encode(null)); 36 | } 37 | 38 | public void testValueToTranslate() { 39 | assertEquals(CONST_TO_ENCODE, this.passwordEncoder 40 | .encode(CONST_TO_ENCODE)); 41 | } 42 | } -------------------------------------------------------------------------------- /ki4so-core/src/test/java/com/github/ebnew/ki4so/core/authentication/handlers/SimpleTestUsernamePasswordHandlerTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Jasig under one or more contributor license 3 | * agreements. See the NOTICE file distributed with this work 4 | * for additional information regarding copyright ownership. 5 | * Jasig licenses this file to you under the Apache License, 6 | * Version 2.0 (the "License"); you may not use this file 7 | * except in compliance with the License. You may obtain a 8 | * copy of the License at the following location: 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.github.ebnew.ki4so.core.authentication.handlers; 20 | 21 | import junit.framework.TestCase; 22 | 23 | import org.mockito.Mockito; 24 | 25 | import com.github.ebnew.ki4so.core.TestUtils; 26 | import com.github.ebnew.ki4so.core.authentication.Credential; 27 | import com.github.ebnew.ki4so.core.authentication.UsernamePasswordCredential; 28 | import com.github.ebnew.ki4so.core.exception.InvalidCredentialException; 29 | 30 | /** 31 | * Test of the simple username/password handler 32 | * 33 | * @author Scott Battaglia 34 | * @version $Revision$ $Date$ 35 | * @since 3.0 36 | */ 37 | public final class SimpleTestUsernamePasswordHandlerTests extends TestCase { 38 | 39 | private SimpleTestUsernamePasswordAuthenticationHandler authenticationHandler; 40 | 41 | protected void setUp() throws Exception { 42 | this.authenticationHandler = new SimpleTestUsernamePasswordAuthenticationHandler(); 43 | this.authenticationHandler 44 | .setPasswordEncoder(new PlainTextPasswordEncoder()); 45 | } 46 | 47 | public void testSupportsProperUserCredentials() { 48 | assertTrue(this.authenticationHandler.supports(TestUtils 49 | .getCredentialsWithSameUsernameAndPassword())); 50 | } 51 | 52 | public void testDoesntSupportBadUserCredentials() { 53 | Credential credential = Mockito.mock(Credential.class); 54 | assertFalse(this.authenticationHandler.supports(credential)); 55 | } 56 | 57 | public void testValidUsernamePassword() { 58 | assertTrue(this.authenticationHandler.authenticate(TestUtils 59 | .getCredentialsWithSameUsernameAndPassword())); 60 | } 61 | 62 | public void testInvalidUsernamePassword() { 63 | try { 64 | assertFalse(this.authenticationHandler.authenticate(TestUtils 65 | .getCredentialsWithDifferentUsernameAndPassword())); 66 | } catch (InvalidCredentialException ae) { 67 | // this is okay 68 | } 69 | } 70 | 71 | public void testNullUsernamePassword() { 72 | try { 73 | assertFalse(this.authenticationHandler.authenticate(TestUtils 74 | .getCredentialsWithSameUsernameAndPassword(null))); 75 | } catch (InvalidCredentialException ae) { 76 | // this is okay 77 | } 78 | } 79 | 80 | public void testAlternateClass() { 81 | this.authenticationHandler.setClassToSupport(UsernamePasswordCredential.class); 82 | assertTrue(this.authenticationHandler.supports(new UsernamePasswordCredential())); 83 | } 84 | 85 | public void testAlternateClassWithSubclassSupport() { 86 | this.authenticationHandler.setClassToSupport(UsernamePasswordCredential.class); 87 | this.authenticationHandler.setSupportSubClasses(true); 88 | assertTrue(this.authenticationHandler.supports(new ExtendedCredentials())); 89 | } 90 | 91 | public void testAlternateClassWithNoSubclassSupport() { 92 | this.authenticationHandler.setClassToSupport(UsernamePasswordCredential.class); 93 | this.authenticationHandler.setSupportSubClasses(false); 94 | assertFalse(this.authenticationHandler.supports(new ExtendedCredentials())); 95 | } 96 | 97 | protected class ExtendedCredentials extends UsernamePasswordCredential { 98 | 99 | private static final long serialVersionUID = 406992293105518363L; 100 | // nothing to see here 101 | } 102 | } -------------------------------------------------------------------------------- /ki4so-core/src/test/java/com/github/ebnew/ki4so/core/authentication/key/KeyServiceImplTest.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication.key; 2 | 3 | import junit.framework.Assert; 4 | 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | import com.github.ebnew.ki4so.core.exception.ParamsNotInitiatedCorrectly; 10 | import com.github.ebnew.ki4so.core.key.KeyServiceImpl; 11 | import com.github.ebnew.ki4so.core.key.Ki4soKey; 12 | 13 | public class KeyServiceImplTest { 14 | 15 | private KeyServiceImpl keyService; 16 | 17 | @Before 18 | public void setUp() throws Exception { 19 | keyService = new KeyServiceImpl(); 20 | } 21 | 22 | @After 23 | public void tearDown() throws Exception { 24 | } 25 | 26 | @Test 27 | public void testFindKeyByAppId() { 28 | //测试异常输入数据情况。 29 | //Assert.assertNull(keyService.findKeyByAppId(null)); 30 | //Assert.assertNull(keyService.findKeyByAppId("")); 31 | //Assert.assertNull(keyService.findKeyByAppId("not exsited")); 32 | 33 | //测试存在数据的情况。 34 | Ki4soKey key = keyService.findKeyByAppId("1001"); 35 | Assert.assertNotNull(key); 36 | System.out.println(key); 37 | } 38 | 39 | @Test 40 | public void testFindKeyByKeyId() { 41 | //测试异常输入数据情况。 42 | Assert.assertNull(keyService.findKeyByKeyId(null)); 43 | Assert.assertNull(keyService.findKeyByKeyId("")); 44 | Assert.assertNull(keyService.findKeyByKeyId("not exsited")); 45 | 46 | //测试存在数据的情况。 47 | Ki4soKey key = keyService.findKeyByKeyId("2"); 48 | Assert.assertNotNull(key); 49 | System.out.println(key); 50 | } 51 | 52 | /** 53 | * 测试读取文件数据方法。 54 | */ 55 | @Test 56 | public void testReadDataFromFile(){ 57 | 58 | KeyServiceImpl keyServiceImpl = new KeyServiceImpl(); 59 | //测试文件为空的情况。 60 | //设置文件路径空。 61 | keyServiceImpl.setClassPathData(null); 62 | keyServiceImpl.setExternalData(null); 63 | //读取文件。 64 | Assert.assertNull(keyServiceImpl.readDataFromFile()); 65 | 66 | //测试错误的文件路径的情况。 67 | keyServiceImpl.setExternalData("ssss"); 68 | //读取文件。 69 | Assert.assertNull(keyServiceImpl.readDataFromFile()); 70 | 71 | //测试错误的文件路径的情况。 72 | keyServiceImpl.setClassPathData("ssss"); 73 | //读取文件。 74 | Assert.assertNull(keyServiceImpl.readDataFromFile()); 75 | } 76 | 77 | 78 | /** 79 | * 测试生成公钥文件 80 | */ 81 | @Test 82 | public void testGenerateKeyFile(){ 83 | try { 84 | keyService.generateKeyFile("1002"); 85 | } catch (ParamsNotInitiatedCorrectly e) { 86 | // TODO Auto-generated catch block 87 | e.printStackTrace(); 88 | } catch (Exception e) { 89 | // TODO Auto-generated catch block 90 | e.printStackTrace(); 91 | } 92 | } 93 | @Test 94 | public void testEncryptKey(){ 95 | KeyServiceImpl keyServiceImpl = new KeyServiceImpl(); 96 | try { 97 | Assert.assertEquals("jswFzQWd0MKn3tXCvRBr+EY1KxbUOl1VcgQL4LYuZTrcdhe88Y4YlN6IeyTnlWsPJCD+W1V9dzKrIpG5X98wIa7qL4gTX824R4GGomcU+iuPNWGIH0LJU2kwVddgBqeS4ANAON7P+BvQRGSh019de/uHQwNeR15v4TUR36mFSPc=", 98 | keyServiceImpl.encryptKey("1001", "恭喜发财!")); 99 | } catch (ParamsNotInitiatedCorrectly e) { 100 | // TODO Auto-generated catch block 101 | e.printStackTrace(); 102 | } catch (Exception e) { 103 | // TODO Auto-generated catch block 104 | e.printStackTrace(); 105 | } 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /ki4so-core/src/test/java/com/github/ebnew/ki4so/core/authentication/resolvers/EncryCredentialToPrincipalResolverTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.github.ebnew.ki4so.core.authentication.resolvers; 7 | 8 | import com.github.ebnew.ki4so.core.authentication.Credential; 9 | import com.github.ebnew.ki4so.core.authentication.EncryCredential; 10 | import com.github.ebnew.ki4so.core.authentication.Principal; 11 | import com.github.ebnew.ki4so.core.model.EncryCredentialInfo; 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | import org.junit.After; 15 | import org.junit.AfterClass; 16 | import org.junit.Before; 17 | import org.junit.BeforeClass; 18 | import org.junit.Test; 19 | import static org.junit.Assert.*; 20 | import org.mockito.Mockito; 21 | 22 | /** 23 | * 24 | * @author bidlink 25 | */ 26 | public class EncryCredentialToPrincipalResolverTest { 27 | 28 | private EncryCredentialToPrincipalResolver resolver; 29 | 30 | public EncryCredentialToPrincipalResolverTest() { 31 | } 32 | 33 | @BeforeClass 34 | public static void setUpClass() { 35 | } 36 | 37 | @AfterClass 38 | public static void tearDownClass() { 39 | } 40 | 41 | @Before 42 | public void setUp() { 43 | this.resolver = new EncryCredentialToPrincipalResolver(); 44 | } 45 | 46 | @After 47 | public void tearDown() { 48 | } 49 | 50 | // TODO add test methods here. 51 | // The methods must be annotated with annotation @Test. For example: 52 | // 53 | @Test 54 | public void testResolvePrincipal() { 55 | //测试null情况。 56 | assertNull(this.resolver.resolvePrincipal(null)); 57 | 58 | //测试不只是的用户凭据对象。 59 | Credential credential = Mockito.mock(Credential.class); 60 | assertNull(this.resolver.resolvePrincipal(credential)); 61 | 62 | //测试正常情况。 63 | String userId = "test"; 64 | EncryCredential encryCredential = new EncryCredential("ddd"); 65 | Map param = new HashMap(); 66 | encryCredential.setParameters(param); 67 | EncryCredentialInfo encryCredentialInfo = new EncryCredentialInfo(); 68 | encryCredentialInfo.setUserId(userId); 69 | encryCredential.setEncryCredentialInfo(encryCredentialInfo); 70 | Principal principal = this.resolver.resolvePrincipal(encryCredential); 71 | assertNotNull(principal); 72 | assertEquals(userId, principal.getId()); 73 | assertEquals(param, principal.getAttributes()); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /ki4so-core/src/test/java/com/github/ebnew/ki4so/core/authentication/resolvers/UsernamePasswordCredentialToPrincipalResolverTest.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.authentication.resolvers; 2 | 3 | import junit.framework.Assert; 4 | 5 | import org.junit.Test; 6 | import org.mockito.Mockito; 7 | 8 | import com.github.ebnew.ki4so.core.authentication.Credential; 9 | import com.github.ebnew.ki4so.core.authentication.DefaultUserPrincipal; 10 | import com.github.ebnew.ki4so.core.authentication.UsernamePasswordCredential; 11 | 12 | public class UsernamePasswordCredentialToPrincipalResolverTest { 13 | 14 | private UsernamePasswordCredentialToPrincipalResolver resolver = new UsernamePasswordCredentialToPrincipalResolver(); 15 | 16 | @Test 17 | public void testSupports(){ 18 | //测试凭据为空的情况。 19 | Assert.assertFalse(resolver.supports(null)); 20 | 21 | //测试不支持的凭据类型的情况。 22 | Credential credential = Mockito.mock(Credential.class); 23 | Assert.assertFalse(resolver.supports(credential)); 24 | 25 | //测试支持的凭据类型UsernamePasswordCredential的情况。 26 | credential = new UsernamePasswordCredential(); 27 | Assert.assertTrue(resolver.supports(credential)); 28 | 29 | 30 | //测试支持的凭据类型UsernamePasswordCredential的子类情况。 31 | credential = new SubUsernamePasswordCredential(); 32 | Assert.assertTrue(resolver.supports(credential)); 33 | } 34 | 35 | 36 | @Test 37 | public void testResolvePrincipal(){ 38 | //测试传入null的情况。 39 | Assert.assertNull(resolver.resolvePrincipal(null)); 40 | 41 | //测试传入不支持的凭据类型的情况。 42 | Credential credential = Mockito.mock(Credential.class); 43 | Assert.assertNull(resolver.resolvePrincipal(credential)); 44 | 45 | //测试传入正确的凭据对象的情况。 46 | String username = "admin"; 47 | UsernamePasswordCredential usernamePasswordCredential = new UsernamePasswordCredential(); 48 | usernamePasswordCredential.setUsername(username); 49 | DefaultUserPrincipal principal = (DefaultUserPrincipal)resolver.resolvePrincipal(usernamePasswordCredential); 50 | Assert.assertNotNull(principal); 51 | Assert.assertEquals(username, principal.getId()); 52 | 53 | 54 | } 55 | 56 | } 57 | 58 | class SubUsernamePasswordCredential extends UsernamePasswordCredential{ 59 | 60 | } 61 | -------------------------------------------------------------------------------- /ki4so-core/src/test/java/com/github/ebnew/ki4so/core/message/MessageUtilsTest.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.message; 2 | 3 | import junit.framework.Assert; 4 | 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | import com.github.ebnew.ki4so.core.exception.InvalidCredentialException; 10 | import com.github.ebnew.ki4so.core.exception.NoKi4soKeyException; 11 | 12 | public class MessageUtilsTest { 13 | 14 | @Before 15 | public void setUp() throws Exception { 16 | } 17 | 18 | @After 19 | public void tearDown() throws Exception { 20 | } 21 | 22 | @Test 23 | public void testGetMessage() { 24 | Assert.assertNull(MessageUtils.getMessage(null)); 25 | 26 | Assert.assertNull(MessageUtils.getMessage("")); 27 | 28 | Assert.assertNotNull(MessageUtils.getMessage(InvalidCredentialException.MSG_KEY)); 29 | Assert.assertNotNull(MessageUtils.getMessage(NoKi4soKeyException.MSG_KEY)); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /ki4so-core/src/test/java/com/github/ebnew/ki4so/core/service/Ki4soServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.service; 2 | 3 | import junit.framework.Assert; 4 | 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | import org.mockito.Mockito; 9 | 10 | import com.github.ebnew.ki4so.core.authentication.Authentication; 11 | import com.github.ebnew.ki4so.core.authentication.AuthenticationManager; 12 | import com.github.ebnew.ki4so.core.authentication.Credential; 13 | import com.github.ebnew.ki4so.core.exception.InvalidCredentialException; 14 | 15 | public class Ki4soServiceTest { 16 | 17 | private Ki4soServiceImpl ki4soService; 18 | 19 | @Before 20 | public void setUp() throws Exception { 21 | ki4soService = new Ki4soServiceImpl(); 22 | } 23 | 24 | @After 25 | public void tearDown() throws Exception { 26 | ki4soService = null; 27 | } 28 | 29 | @Test 30 | public void testLogin(){ 31 | //测试输入Null的情况。 32 | Assert.assertNull(ki4soService.login(null)); 33 | 34 | 35 | //测试认证失败的情况。 36 | Credential credential = Mockito.mock(Credential.class); 37 | //当调用认证方法则抛出异常信息。模拟测试数据。 38 | AuthenticationManager authenticationManager = Mockito.mock(AuthenticationManager.class); 39 | this.ki4soService.setAuthenticationManager(authenticationManager); 40 | InvalidCredentialException exception = Mockito.mock(InvalidCredentialException.class); 41 | String code = "message code"; 42 | String msgKey ="message key"; 43 | Mockito.when(exception.getCode()).thenReturn(code); 44 | Mockito.when(exception.getMsgKey()).thenReturn(msgKey); 45 | Mockito.when(authenticationManager.authenticate(credential)).thenThrow(exception); 46 | LoginResult loginResult = ki4soService.login(credential); 47 | LoginResult expected = new LoginResult(); 48 | expected.setSuccess(false); 49 | expected.setCode(code); 50 | expected.setMsgKey(msgKey); 51 | //比较结果。 52 | this.assertLoginResult(expected, loginResult); 53 | 54 | //测试认证成功。 55 | credential = Mockito.mock(Credential.class); 56 | //当调用认证方法则抛出异常信息。模拟测试数据。 57 | authenticationManager = Mockito.mock(AuthenticationManager.class); 58 | this.ki4soService.setAuthenticationManager(authenticationManager); 59 | 60 | 61 | Authentication authentication = Mockito.mock(Authentication.class); 62 | Mockito.when(exception.getCode()).thenReturn(msgKey); 63 | Mockito.when(exception.getCode()).thenReturn(code); 64 | Mockito.when(authenticationManager.authenticate(credential)).thenReturn(authentication); 65 | loginResult = ki4soService.login(credential); 66 | expected = new LoginResult(); 67 | expected.setSuccess(true); 68 | expected.setAuthentication(authentication); 69 | //比较结果。 70 | this.assertLoginResult(expected, loginResult); 71 | } 72 | 73 | /** 74 | * 测试登出的情况。 75 | */ 76 | @Test 77 | public void testLogout(){ 78 | 79 | } 80 | 81 | 82 | /** 83 | * 比较两个登录结果对象。 84 | * @param expected 预期结果。 85 | * @param aucual 实际结果。 86 | */ 87 | private void assertLoginResult(LoginResult expected, LoginResult aucual){ 88 | if(expected==null && aucual==null){ 89 | return; 90 | } 91 | else if(expected != null && aucual!=null){ 92 | Assert.assertEquals(expected.getCode(), aucual.getCode()); 93 | Assert.assertEquals(expected.getMsgKey(), aucual.getMsgKey()); 94 | Assert.assertEquals(expected.getAuthentication(), aucual.getAuthentication()); 95 | } 96 | else{ 97 | Assert.fail("预期和实际登录对象不等"); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /ki4so-core/src/test/java/com/github/ebnew/ki4so/core/service/LogoutAppServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.core.service; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | import org.mockito.Mockito; 9 | 10 | import com.github.ebnew.ki4so.core.app.App; 11 | import com.github.ebnew.ki4so.core.app.AppService; 12 | import com.github.ebnew.ki4so.core.authentication.status.UserLoggedStatus; 13 | import com.github.ebnew.ki4so.core.authentication.status.UserLoggedStatusStore; 14 | 15 | public class LogoutAppServiceTest { 16 | 17 | private LogoutAppServiceImpl logoutAppService; 18 | 19 | private AppService appService; 20 | 21 | private UserLoggedStatusStore userLoggedStatusStore; 22 | 23 | @Before 24 | public void setUp(){ 25 | logoutAppService = new LogoutAppServiceImpl(); 26 | appService = Mockito.mock(AppService.class); 27 | logoutAppService.setAppService(appService); 28 | userLoggedStatusStore = Mockito.mock(UserLoggedStatusStore.class); 29 | logoutAppService.setUserLoggedStatusStore(userLoggedStatusStore); 30 | } 31 | 32 | @Test 33 | public void testLogoutAppWithEmptyUserId(){ 34 | 35 | logoutAppService.logoutApp(null, null); 36 | 37 | logoutAppService.logoutApp("", null); 38 | 39 | } 40 | 41 | @Test 42 | public void testLogoutAppWithUserIdAndServiceJustLoginedServiceApp(){ 43 | 44 | String userId = "test"; 45 | String url = "http://www.yuecai.com/html/index/index.html"; 46 | 47 | App serivceApp = new App(); 48 | serivceApp.setLogoutUrl(url); 49 | 50 | Mockito.when(appService.findAppByHost(url)).thenReturn(serivceApp); 51 | Mockito.when(userLoggedStatusStore.findUserLoggedStatus(userId)).thenReturn(null); 52 | 53 | logoutAppService.logoutApp(userId, url); 54 | 55 | } 56 | 57 | @Test 58 | public void testLogoutAppWithUserIdAndServiceHasLoginedTwoApps(){ 59 | 60 | String userId = "test"; 61 | String url = "http://git.oschina.net/ywbrj042/ki4so"; 62 | 63 | App serivceApp = new App(); 64 | serivceApp.setLogoutUrl(url); 65 | serivceApp.setAppId("1"); 66 | 67 | App firstApp = new App(); 68 | firstApp.setLogoutUrl(url); 69 | firstApp.setAppId("1001"); 70 | 71 | App sencondApp = new App(); 72 | sencondApp.setLogoutUrl(url); 73 | sencondApp.setAppId("1002"); 74 | 75 | List list = new ArrayList(); 76 | UserLoggedStatus userLoggedStatus = new UserLoggedStatus(userId, "1001"); 77 | list.add(userLoggedStatus); 78 | userLoggedStatus = new UserLoggedStatus(userId, "1002"); 79 | list.add(userLoggedStatus); 80 | userLoggedStatus = new UserLoggedStatus(userId, "1"); 81 | list.add(userLoggedStatus); 82 | 83 | Mockito.when(appService.findAppByHost(url)).thenReturn(serivceApp); 84 | 85 | Mockito.when(appService.findAppById("1001")).thenReturn(serivceApp); 86 | Mockito.when(appService.findAppById("1001")).thenReturn(firstApp); 87 | Mockito.when(appService.findAppById("1002")).thenReturn(sencondApp); 88 | Mockito.when(userLoggedStatusStore.findUserLoggedStatus(userId)).thenReturn(list); 89 | 90 | logoutAppService.logoutApp(userId, url); 91 | 92 | } 93 | 94 | 95 | 96 | } 97 | -------------------------------------------------------------------------------- /ki4so-java-client/.gitignore: -------------------------------------------------------------------------------- 1 | /bin 2 | -------------------------------------------------------------------------------- /ki4so-java-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | com.github.ki4so 6 | ki4so-parent 7 | 1.0.1-SNAPSHOT 8 | 9 | 4.0.0 10 | ki4so-java-client 11 | jar 12 | ki4so-java-client 13 | 14 | 简约单点系统的java原生客户端。通过集成该jar包,能够非常方便得与java web应用进行单点登录集成。 15 | 简化了ki4so集成的难度,降低了成本,应用只需要通过简单的配置即可实现集成ki4so。并且遵循最小依赖和最小侵入的原则, 16 | 让应用尽可能简单方便得使用ki4so. 17 | 18 | 19 | 20 | 21 | 22 | com.github.ki4so 23 | ki4so-common 24 | ${ki4so.version} 25 | 26 | 27 | 28 | javax.servlet 29 | servlet-api 30 | 2.5 31 | provided 32 | 33 | 34 | 35 | junit 36 | junit 37 | 38 | 39 | 40 | org.mockito 41 | mockito-core 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ki4so-java-client/src/main/java/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /ki4so-java-client/src/main/java/com/github/ebnew/ki4so/client/handler/KnightAppClientLoginHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.client.handler; 2 | 3 | import com.github.ebnew.ki4so.core.model.KnightCredentialInfo; 4 | 5 | import javax.servlet.http.HttpServletRequest; 6 | import javax.servlet.http.HttpServletResponse; 7 | 8 | /** 9 | * 本应用登录处理器接口,请实现该处理器 10 | * 实现本接口,将本应用的登录逻辑写在这里 11 | * @author zhenglu 12 | * @since 15/4/30 13 | */ 14 | public interface KnightAppClientLoginHandler { 15 | 16 | 17 | /** 18 | * 登录本应用 19 | * @param credentialInfo 20 | * @param request 21 | * @param response 22 | */ 23 | public void loginClient(KnightCredentialInfo credentialInfo,HttpServletRequest request,HttpServletResponse response); 24 | } 25 | -------------------------------------------------------------------------------- /ki4so-java-client/src/main/java/com/github/ebnew/ki4so/client/handler/KnightAppClientLogoutHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.client.handler; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | 6 | /** 7 | * 本应用登出处理接口 8 | * @author zhenglu 9 | * @since 15/4/30 10 | */ 11 | public interface KnightAppClientLogoutHandler { 12 | /** 13 | * 退出本应用 14 | * @param request 15 | * @param response 16 | * @param userId 17 | */ 18 | 19 | public void logoutClient(HttpServletRequest request,HttpServletResponse response,String userId); 20 | } 21 | -------------------------------------------------------------------------------- /ki4so-java-client/src/main/java/com/github/ebnew/ki4so/client/session/SessionStorage.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.client.session; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import javax.servlet.http.HttpSession; 7 | 8 | 9 | /** 10 | * 在客户端保存session信息类 11 | * @author zpj 12 | * 13 | */ 14 | public class SessionStorage { 15 | 16 | /** 17 | * 以sessionId为key,session为value。在统一退出的时候获取并销毁session 18 | */ 19 | private static final Map SESSION_MAP 20 | = new HashMap(); 21 | 22 | /** 23 | * 保存session信息 24 | * @param sessionId 25 | * @param session 26 | */ 27 | public static void put(String sessionId, 28 | HttpSession session){ 29 | SESSION_MAP.put(sessionId, session); 30 | } 31 | 32 | /** 33 | * 获取session 34 | * @param sessionId 35 | */ 36 | public static HttpSession get(String sessionId){ 37 | return SESSION_MAP.get(sessionId); 38 | } 39 | 40 | /** 41 | * 是否存session信息 42 | * @param sessionId 43 | */ 44 | public static boolean containsKey(String sessionId){ 45 | return SESSION_MAP.containsKey(sessionId); 46 | } 47 | 48 | /** 49 | * 移除session信息 50 | * @param sessionId 51 | */ 52 | public static HttpSession remove(String sessionId){ 53 | return SESSION_MAP.remove(sessionId); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /ki4so-java-client/src/main/java/com/github/ebnew/ki4so/client/web/filters/BaseClientFilter.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.client.web.filters; 2 | 3 | import javax.servlet.*; 4 | import javax.servlet.http.Cookie; 5 | import javax.servlet.http.HttpServletRequest; 6 | 7 | import com.github.ebnew.ki4so.common.utils.StringUtils; 8 | 9 | import java.io.IOException; 10 | 11 | /** 12 | * 公共基础的客户端过滤器类,定义了一些公共的方法。 13 | * @author zhenglu 14 | * 15 | */ 16 | public abstract class BaseClientFilter implements Filter{ 17 | 18 | //服务器主机地址 19 | protected String knightServerHost = "http://localhost:8080/ki4so-web"; 20 | 21 | @Override 22 | public void init(FilterConfig filterConfig) throws ServletException { 23 | knightServerHost = getInitParamterWithDefaultValue(filterConfig,"knightServerHost",knightServerHost); 24 | doInit(filterConfig); 25 | } 26 | 27 | @Override 28 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 29 | 30 | } 31 | 32 | /** 33 | * 由子类实现的初始化方法 34 | * @param filterConfig 35 | * @throws ServletException 36 | */ 37 | protected abstract void doInit(FilterConfig filterConfig) throws ServletException; 38 | 39 | /** 40 | * 获取过滤器的参数值,带有默认值,如果没有配置,则试用默认值 41 | * @param filterConfig 42 | * @param paramName 43 | * @param defaultValue 44 | * @return 45 | */ 46 | protected String getInitParamterWithDefaultValue(FilterConfig filterConfig,String paramName,String defaultValue){ 47 | String value = filterConfig.getInitParameter(paramName); 48 | if(StringUtils.isEmpty(value)){ 49 | value = defaultValue; 50 | } 51 | return value; 52 | } 53 | public static Cookie getCookie(HttpServletRequest request,String cookieName){ 54 | Cookie[] cookies = request.getCookies(); 55 | if(cookies != null){ 56 | for(Cookie cookie : cookies){ 57 | if(cookieName.equals(cookie.getName())){ 58 | return cookie; 59 | } 60 | } 61 | } 62 | return null; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /ki4so-java-client/src/main/java/com/github/ebnew/ki4so/client/web/filters/KnightGeneratePrivateKeyFilter.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.client.web.filters; 2 | 3 | import com.github.ebnew.ki4so.common.utils.StringUtils; 4 | import com.github.ebnew.ki4so.core.key.KnightKeyService; 5 | import org.apache.log4j.Logger; 6 | 7 | import javax.servlet.*; 8 | import java.io.IOException; 9 | 10 | /** 11 | * 生成密钥的filter 12 | * @author zhenglu 13 | * @since 15/5/4 14 | */ 15 | public class KnightGeneratePrivateKeyFilter extends BaseClientFilter { 16 | 17 | private static final Logger logger = Logger.getLogger(KnightGeneratePrivateKeyFilter.class); 18 | 19 | private String serverFetchKeyUrl = null; 20 | 21 | //应用标识 22 | private String appId = null; 23 | 24 | //生成密钥文件类 25 | protected String GeneratePrivateKeyFileClass = "com.github.ebnew.ki4so.client.key.DefaultKeyServiceImpl"; 26 | 27 | protected KnightKeyService keyService; 28 | 29 | @Override 30 | protected void doInit(FilterConfig filterConfig) throws ServletException { 31 | 32 | // TODO Auto-generated method stub 33 | GeneratePrivateKeyFileClass = getInitParamterWithDefaultValue(filterConfig, "appClientDefaultKeyServiceClass", GeneratePrivateKeyFileClass); 34 | //获取appId参数值 35 | appId = getInitParamterWithDefaultValue(filterConfig, "appId", "1001"); 36 | //获取服务器访问路径参数值 37 | serverFetchKeyUrl = getInitParamterWithDefaultValue(filterConfig, "serverFetchKeyUrl", "http://localhost:8080/ki4so-web/fetchKey.do"); 38 | //构造登录本应用的处理器对象。 39 | if(!StringUtils.isEmpty(GeneratePrivateKeyFileClass)){ 40 | try{ 41 | //实例化 42 | this.keyService = (KnightKeyService) (Class.forName(GeneratePrivateKeyFileClass) 43 | .getConstructor(String.class,String.class)).newInstance(serverFetchKeyUrl,appId); //实现类需无参构造方法 44 | }catch (Exception e) { 45 | // TODO: handle exception 46 | logger.error("init failure::" + e.getMessage()); 47 | } 48 | } 49 | } 50 | 51 | 52 | @Override 53 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 54 | try{ 55 | 56 | keyService.generateKeyFile(appId); 57 | 58 | }catch (Exception e){ 59 | logger.error("密钥生成失败"); 60 | } 61 | filterChain.doFilter(servletRequest,servletResponse); 62 | 63 | } 64 | 65 | @Override 66 | public void destroy() { 67 | 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /ki4so-java-client/src/main/resources/keySecurity.properties: -------------------------------------------------------------------------------- 1 | keyPath=E:/ 2 | -------------------------------------------------------------------------------- /ki4so-jdbc/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | com.github.ki4so 6 | ki4so-parent 7 | 1.0.1-SNAPSHOT 8 | 9 | 4.0.0 10 | ki4so-jdbc 11 | jar 12 | ki4so-jdbc 13 | 14 | 使用JDBC连接数据库,实现与用户信息存储在数据库中的集成。 15 | 16 | 17 | 18 | 0.2.26 19 | 20 | 21 | 22 | 23 | com.github.ki4so 24 | ki4so-core 25 | ${ki4so.version} 26 | 27 | 28 | 29 | org.springframework 30 | spring-jdbc 31 | ${spring.version} 32 | 33 | 34 | 35 | org.springframework 36 | spring-jdbc 37 | ${spring.version} 38 | 39 | 40 | 41 | mysql 42 | mysql-connector-java 43 | 5.1.19 44 | 45 | 46 | 47 | junit 48 | junit 49 | 50 | 51 | 52 | org.mockito 53 | mockito-core 54 | 55 | 56 | 57 | org.springframework 58 | spring-test 59 | 60 | 61 | 62 | mysql 63 | mysql-connector-java 64 | 5.1.26 65 | 66 | 67 | 68 | com.alibaba 69 | druid 70 | ${druid-version} 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /ki4so-jdbc/src/main/java/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /ki4so-jdbc/src/main/java/com/github/ebnew/ki4so/core/authentication/handlers/jdbc/AbstractJdbcUsernamePasswordAuthenticationHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Jasig under one or more contributor license 3 | * agreements. See the NOTICE file distributed with this work 4 | * for additional information regarding copyright ownership. 5 | * Jasig licenses this file to you under the Apache License, 6 | * Version 2.0 (the "License"); you may not use this file 7 | * except in compliance with the License. You may obtain a 8 | * copy of the License at the following location: 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.github.ebnew.ki4so.core.authentication.handlers.jdbc; 20 | 21 | import javax.sql.DataSource; 22 | 23 | import org.springframework.jdbc.core.JdbcTemplate; 24 | 25 | import com.github.ebnew.ki4so.core.authentication.handlers.AbstractUsernamePasswordAuthenticationHandler; 26 | 27 | /** 28 | * Abstract class for database authentication handlers. 29 | * 30 | * @author Scott Battaglia 31 | * @since 3.0.3 32 | */ 33 | public abstract class AbstractJdbcUsernamePasswordAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler { 34 | 35 | private JdbcTemplate jdbcTemplate; 36 | 37 | private DataSource dataSource; 38 | 39 | /** 40 | * Method to set the datasource and generate a JdbcTemplate. 41 | * 42 | * @param dataSource the datasource to use. 43 | */ 44 | public final void setDataSource(final DataSource dataSource) { 45 | this.jdbcTemplate = new JdbcTemplate(dataSource); 46 | this.dataSource = dataSource; 47 | } 48 | 49 | /** 50 | * Method to return the jdbcTemplate 51 | * 52 | * @return a fully created JdbcTemplate. 53 | */ 54 | protected final JdbcTemplate getJdbcTemplate() { 55 | return this.jdbcTemplate; 56 | } 57 | 58 | protected final DataSource getDataSource() { 59 | return this.dataSource; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /ki4so-jdbc/src/main/java/com/github/ebnew/ki4so/core/authentication/handlers/jdbc/QueryDatabaseAuthenticationHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Jasig under one or more contributor license 3 | * agreements. See the NOTICE file distributed with this work 4 | * for additional information regarding copyright ownership. 5 | * Jasig licenses this file to you under the Apache License, 6 | * Version 2.0 (the "License"); you may not use this file 7 | * except in compliance with the License. You may obtain a 8 | * copy of the License at the following location: 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.github.ebnew.ki4so.core.authentication.handlers.jdbc; 20 | 21 | import org.springframework.dao.IncorrectResultSizeDataAccessException; 22 | import com.github.ebnew.ki4so.core.authentication.UsernamePasswordCredential; 23 | import com.github.ebnew.ki4so.core.exception.AuthenticationException; 24 | 25 | 26 | /** 27 | * Class that if provided a query that returns a password (parameter of query 28 | * must be username) will compare that password to a translated version of the 29 | * password provided by the user. If they match, then authentication succeeds. 30 | * Default password translator is plaintext translator. 31 | * 32 | * @author Scott Battaglia 33 | * @author Dmitriy Kopylenko 34 | * @version $Revision$ $Date$ 35 | * @since 3.0 36 | */ 37 | public class QueryDatabaseAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler { 38 | 39 | private String sql; 40 | 41 | protected final boolean authenticateUsernamePasswordInternal(final UsernamePasswordCredential credentials) throws AuthenticationException { 42 | final String username = credentials.getUsername(); 43 | final String password = credentials.getPassword(); 44 | final String encryptedPassword = this.getPasswordEncoder().encode( 45 | password); 46 | 47 | try { 48 | final String dbPassword = getJdbcTemplate().queryForObject(this.sql, String.class, username); 49 | return dbPassword.equals(encryptedPassword); 50 | } catch (final IncorrectResultSizeDataAccessException e) { 51 | // this means the username was not found. 52 | return false; 53 | } 54 | } 55 | 56 | /** 57 | * @param sql The sql to set. 58 | */ 59 | public void setSql(final String sql) { 60 | this.sql = sql; 61 | } 62 | } -------------------------------------------------------------------------------- /ki4so-jdbc/src/main/java/com/github/ebnew/ki4so/core/authentication/handlers/jdbc/SearchModeSearchDatabaseAuthenticationHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Jasig under one or more contributor license 3 | * agreements. See the NOTICE file distributed with this work 4 | * for additional information regarding copyright ownership. 5 | * Jasig licenses this file to you under the Apache License, 6 | * Version 2.0 (the "License"); you may not use this file 7 | * except in compliance with the License. You may obtain a 8 | * copy of the License at the following location: 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.github.ebnew.ki4so.core.authentication.handlers.jdbc; 20 | 21 | import org.springframework.beans.factory.InitializingBean; 22 | 23 | import com.github.ebnew.ki4so.core.authentication.UsernamePasswordCredential; 24 | import com.github.ebnew.ki4so.core.exception.AuthenticationException; 25 | 26 | 27 | /** 28 | * Class that given a table, username field and password field will query a 29 | * database table with the provided encryption technique to see if the user 30 | * exists. This class defaults to a PasswordTranslator of 31 | * PlainTextPasswordTranslator. 32 | * 33 | * @author Scott Battaglia 34 | * @author Dmitriy Kopylenko 35 | * @version $Revision$ $Date$ 36 | * @since 3.0 37 | */ 38 | 39 | public class SearchModeSearchDatabaseAuthenticationHandler extends 40 | AbstractJdbcUsernamePasswordAuthenticationHandler implements InitializingBean { 41 | 42 | private static final String SQL_PREFIX = "Select count('x') from "; 43 | 44 | private String fieldUser; 45 | 46 | private String fieldPassword; 47 | 48 | private String tableUsers; 49 | 50 | private String sql; 51 | 52 | protected final boolean authenticateUsernamePasswordInternal(final UsernamePasswordCredential credentials) throws AuthenticationException { 53 | final String transformedUsername = credentials.getUsername(); 54 | final String encyptedPassword = getPasswordEncoder().encode(credentials.getPassword()); 55 | 56 | final int count = getJdbcTemplate().queryForInt(this.sql, 57 | transformedUsername, encyptedPassword); 58 | 59 | return count > 0; 60 | } 61 | 62 | public void afterPropertiesSet() throws Exception { 63 | this.sql = SQL_PREFIX + this.tableUsers + " Where " + this.fieldUser 64 | + " = ? And " + this.fieldPassword + " = ?"; 65 | } 66 | 67 | /** 68 | * @param fieldPassword The fieldPassword to set. 69 | */ 70 | public final void setFieldPassword(final String fieldPassword) { 71 | this.fieldPassword = fieldPassword; 72 | } 73 | 74 | /** 75 | * @param fieldUser The fieldUser to set. 76 | */ 77 | public final void setFieldUser(final String fieldUser) { 78 | this.fieldUser = fieldUser; 79 | } 80 | 81 | /** 82 | * @param tableUsers The tableUsers to set. 83 | */ 84 | public final void setTableUsers(final String tableUsers) { 85 | this.tableUsers = tableUsers; 86 | } 87 | } -------------------------------------------------------------------------------- /ki4so-web/.gitignore: -------------------------------------------------------------------------------- 1 | /bin 2 | -------------------------------------------------------------------------------- /ki4so-web/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | com.github.ki4so 6 | ki4so-parent 7 | 1.0.1-SNAPSHOT 8 | 9 | 4.0.0 10 | ki4so-web 11 | war 12 | ki4so-web 13 | 14 | 简约单点登录系统web模块,该模块是ki4so服务端模块,定义并实现了处理各种外部接口的类,包括登录、登出和查询应用key值等接口。 15 | 16 | 17 | 18 | 19 | com.github.ki4so 20 | ki4so-core 21 | ${ki4so.version} 22 | 23 | 24 | 25 | com.github.ki4so 26 | ki4so-jdbc 27 | ${ki4so.version} 28 | 29 | 30 | 31 | com.github.ki4so 32 | ki4so-java-client 33 | ${ki4so.version} 34 | 35 | 36 | 37 | org.springframework 38 | spring-web 39 | ${spring.version} 40 | 41 | 42 | org.springframework 43 | spring-webmvc 44 | ${spring.version} 45 | 46 | 47 | javax.servlet 48 | servlet-api 49 | 2.5 50 | provided 51 | 52 | 53 | javax.servlet 54 | jstl 55 | 1.2 56 | 57 | 58 | taglibs 59 | standard 60 | 1.1.2 61 | 62 | 63 | org.springframework 64 | spring-core 65 | 66 | 67 | 68 | org.springframework 69 | spring-beans 70 | 71 | 72 | 73 | org.springframework 74 | spring-context 75 | 76 | 77 | 78 | org.codehaus.jackson 79 | jackson-core-asl 80 | 1.9.12 81 | 82 | 83 | 84 | org.codehaus.jackson 85 | jackson-mapper-asl 86 | 1.9.12 87 | 88 | 89 | 90 | com.fasterxml.jackson.core 91 | jackson-databind 92 | 2.0.1 93 | 94 | 95 | 96 | junit 97 | junit 98 | 99 | 100 | 101 | org.mockito 102 | mockito-core 103 | 104 | 105 | 106 | org.springframework 107 | spring-test 108 | 109 | 110 | 111 | log4j 112 | log4j 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /ki4so-web/src/main/java/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhenglu1989/web-sso/2747d3034599539ba92493dec53d7bff99e3cecd/ki4so-web/src/main/java/README.md -------------------------------------------------------------------------------- /ki4so-web/src/main/java/com/github/ebnew/ki4so/web/action/KeyAction.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.web.action; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Controller; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.ResponseBody; 7 | 8 | import com.github.ebnew.ki4so.core.key.KeyService; 9 | import com.github.ebnew.ki4so.core.key.Ki4soKey; 10 | 11 | /** 12 | * 与秘钥相关的web请求处理类,处理查询应用的秘钥等信息。 13 | * @author burgess yang 14 | * 15 | */ 16 | @Controller 17 | public class KeyAction { 18 | 19 | /** 20 | * 秘钥服务。 21 | */ 22 | @Autowired 23 | private KeyService keyService; 24 | 25 | public void setKeyService(KeyService keyService) { 26 | this.keyService = keyService; 27 | } 28 | 29 | /** 30 | * 根据应用ID,查询对应的秘钥信息,默认的实现是不加密的,未实现认证, 31 | * 请自行增加该服务的安全性。 32 | * @param appId 应用ID. 33 | * @return 对应的秘钥。 34 | */ 35 | @RequestMapping("/fetchKey") 36 | @ResponseBody 37 | public Ki4soKey fetchKey(String appId){ 38 | return keyService.findKeyByAppId(appId); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ki4so-web/src/main/java/com/github/ebnew/ki4so/web/action/KnightAbstractParameterCredentialResolver.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.web.action; 2 | 3 | import com.github.ebnew.ki4so.core.authentication.KnightCredential; 4 | import com.github.ebnew.ki4so.core.authentication.KnightParameter; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | 8 | /** 9 | * 该类提供了参数化的凭据类型的解析后处理方法,将请求中的所有参数全部转移到参数列表中,供相关处理 10 | * @author zhenglu 11 | * @since 15/4/29 12 | */ 13 | public abstract class KnightAbstractParameterCredentialResolver extends KnightAbstractPreAndPostProcessingCredentialResolver { 14 | @Override 15 | protected KnightCredential postResolveCredential(HttpServletRequest request, KnightCredential credential) { 16 | if(credential == null){ 17 | return null; 18 | } 19 | if(credential instanceof KnightParameter){ 20 | KnightParameter parameter = (KnightParameter)credential; 21 | parameter.setParameters(request.getParameterMap()); 22 | } 23 | 24 | return super.postResolveCredential(request, credential); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ki4so-web/src/main/java/com/github/ebnew/ki4so/web/action/KnightAbstractPreAndPostProcessingCredentialResolver.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.web.action; 2 | 3 | import com.github.ebnew.ki4so.core.authentication.KnightCredential; 4 | 5 | import javax.servlet.http.HttpServletRequest; 6 | 7 | /** 8 | * 提供凭据解析前和后处理方法的抽象解析器类 9 | * @author zhenglu 10 | * @since 15/4/29 11 | */ 12 | public abstract class KnightAbstractPreAndPostProcessingCredentialResolver implements KnightCredentialResolver{ 13 | 14 | @Override 15 | public KnightCredential resolveCredential(HttpServletRequest request) { 16 | this.preResolveCredential(request); 17 | KnightCredential credential = this.doResolveCredential(request); 18 | 19 | return this.postResolveCredential(request,credential); 20 | } 21 | 22 | /** 23 | * 凭据解析之前的处理 24 | * @param request 请求参数对象 25 | * 26 | */ 27 | protected void preResolveCredential(HttpServletRequest request){ 28 | } 29 | 30 | 31 | /** 32 | * 抽象方法,实现真正的凭据解析处理 33 | * @param request 请求参数对象 34 | * @return 解析后的凭据对象信息 35 | */ 36 | protected abstract KnightCredential doResolveCredential(HttpServletRequest request); 37 | 38 | /** 39 | * 凭据解析后处理 40 | * @param request 请求参数对象 41 | * @param credential 解析后的凭据信息,要基于该凭据上增加属性值 42 | * @return 处理后的凭据解析器 43 | */ 44 | protected KnightCredential postResolveCredential(HttpServletRequest request,KnightCredential credential){ 45 | return credential; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /ki4so-web/src/main/java/com/github/ebnew/ki4so/web/action/KnightCompositeCredentialResolver.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.web.action; 2 | 3 | import com.github.ebnew.ki4so.core.authentication.KnightAbstractParameter; 4 | import com.github.ebnew.ki4so.core.authentication.KnightCredential; 5 | import com.github.ebnew.ki4so.web.utils.WebConstants; 6 | import org.springframework.web.util.WebUtils; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | 10 | /** 11 | * 组合凭据解析器,组合两种解析器,按照优先级顺序,从http请求参数或者cookie中解析出优先级比较高的凭据,若无优先级高的凭据,则按照顺序解析 12 | * @author zhenglu 13 | * @since 15/4/29 14 | */ 15 | public class KnightCompositeCredentialResolver implements KnightCredentialResolver{ 16 | 17 | //加密后的凭据解析器 18 | private KnightCredentialResolver encryCredentialResolver; 19 | 20 | private KnightCredentialResolver usernamePasswordCredentialResolver; 21 | 22 | 23 | @Override 24 | public KnightCredential resolveCredential(HttpServletRequest request) { 25 | if(request == null){ 26 | return null; 27 | } 28 | KnightCredential credential = null; 29 | if(encryCredentialResolver != null){ 30 | //先解析加密后的凭证 31 | credential = encryCredentialResolver.resolveCredential(request); 32 | } 33 | //若返回为空,则用原始凭据解析 34 | if(credential == null){ 35 | credential = usernamePasswordCredentialResolver.resolveCredential(request); 36 | } 37 | if(credential instanceof KnightAbstractParameter){ 38 | KnightAbstractParameter parameter = (KnightAbstractParameter)credential; 39 | parameter.setParameters(WebUtils.getParametersStartingWith(request, null)); 40 | if(parameter.getParameterValue(WebConstants.SERVICE_PARAM_NAME) == null){ 41 | if(request.getSession().getAttribute(WebConstants.KI4SO_SERVICE_KEY_IN_SESSION) != null){ 42 | parameter.getParameters().put(WebConstants.SERVICE_PARAM_NAME,request.getSession().getAttribute(WebConstants.KI4SO_SERVICE_KEY_IN_SESSION)); 43 | 44 | } 45 | } 46 | } 47 | return credential; 48 | } 49 | 50 | public void setEncryCredentialResolver(KnightCredentialResolver encryCredentialResolver) { 51 | this.encryCredentialResolver = encryCredentialResolver; 52 | } 53 | 54 | public void setUsernamePasswordCredentialResolver(KnightCredentialResolver usernamePasswordCredentialResolver) { 55 | this.usernamePasswordCredentialResolver = usernamePasswordCredentialResolver; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ki4so-web/src/main/java/com/github/ebnew/ki4so/web/action/KnightCredentialResolver.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.web.action; 2 | 3 | import com.github.ebnew.ki4so.core.authentication.KnightCredential; 4 | 5 | import javax.servlet.http.HttpServletRequest; 6 | 7 | /** 8 | * 凭据解析,从http请求的cookie,参数等值中解析出各种类型的用户凭证,该接口由具体实现类具体解析凭据 9 | * @author zhenglu 10 | * @since 15/4/28 11 | */ 12 | public interface KnightCredentialResolver { 13 | 14 | /** 15 | * 从http请求参数的cookie或参数值中解析出凭据信息对象,返回解析后的凭据对象 16 | * @param request 17 | * @return 18 | */ 19 | 20 | public KnightCredential resolveCredential(HttpServletRequest request); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /ki4so-web/src/main/java/com/github/ebnew/ki4so/web/action/KnightEncryCredentialResolver.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.web.action; 2 | 3 | import com.github.ebnew.ki4so.common.utils.StringUtils; 4 | import com.github.ebnew.ki4so.core.authentication.KnightCredential; 5 | import com.github.ebnew.ki4so.core.authentication.KnightEncryCredential; 6 | import com.github.ebnew.ki4so.web.utils.WebConstants; 7 | import org.apache.log4j.Logger; 8 | 9 | import javax.servlet.http.Cookie; 10 | import javax.servlet.http.HttpServletRequest; 11 | 12 | /** 13 | * 经过认证加密后的凭据信息解析器,从http请求的cookie中解析出对应的加密后的凭据信息 14 | * @author zhenglu 15 | * @since 15/4/28 16 | */ 17 | public class KnightEncryCredentialResolver implements KnightCredentialResolver{ 18 | 19 | private static final Logger logger = Logger.getLogger(KnightEncryCredentialResolver.class); 20 | 21 | @Override 22 | public KnightCredential resolveCredential(HttpServletRequest request) { 23 | if(request != null){ 24 | Cookie[] cookies = request.getCookies(); 25 | if(cookies != null){ 26 | String value = null; 27 | for(Cookie cookie:cookies){ 28 | if(cookie != null && cookie.getName().equalsIgnoreCase(WebConstants.KI4SO_SERVER_ENCRYPTED_CREDENTIAL_COOKIE_KEY)); 29 | value = cookie.getValue(); 30 | break; 31 | } 32 | //如果cookie中没有凭据值,则从请求参数中获取凭据值 33 | if(StringUtils.isEmpty(value)){ 34 | logger.info("KI4SO_SERVER_EC value is empty" ); 35 | value = request.getParameter(WebConstants.KI4SO_SERVER_ENCRYPTED_CREDENTIAL_COOKIE_KEY); 36 | } 37 | //最终如果加密凭据有值,则直接返回凭据对象 38 | if(!StringUtils.isEmpty(value)){ 39 | return new KnightEncryCredential(); 40 | } 41 | } 42 | } 43 | 44 | return null; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ki4so-web/src/main/java/com/github/ebnew/ki4so/web/action/KnightLoginResultToView.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.web.action; 2 | 3 | import com.github.ebnew.ki4so.core.service.LoginResult; 4 | import org.springframework.web.servlet.ModelAndView; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | 9 | /** 10 | * 该接口实现了将登录结果转换为视图响应的功能 11 | * @author zhenglu 12 | * @since 15/4/30 13 | */ 14 | public interface KnightLoginResultToView { 15 | 16 | /** 17 | * 18 | * @param mav 19 | * @param result 20 | * @param request 21 | * @param response 22 | * @return 23 | */ 24 | public ModelAndView loginResultToView(ModelAndView mav,LoginResult result,HttpServletRequest request,HttpServletResponse response); 25 | } 26 | -------------------------------------------------------------------------------- /ki4so-web/src/main/java/com/github/ebnew/ki4so/web/action/KnightUsernamePasswordCredentialResolver.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.web.action; 2 | 3 | import com.github.ebnew.ki4so.common.utils.StringUtils; 4 | import com.github.ebnew.ki4so.core.authentication.KnightCredential; 5 | import com.github.ebnew.ki4so.core.authentication.KnightNamePasswordCredential; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | 9 | /** 10 | * 用户名和密码凭据解析器,从参数中解析出用户名和用户密码 11 | * @author zhenglu 12 | * @since 15/4/29 13 | */ 14 | public class KnightUsernamePasswordCredentialResolver extends KnightAbstractParameterCredentialResolver { 15 | /** 16 | * 用户名的参数名 17 | */ 18 | public static final String USERNAME_PARAM_NAME = "username"; 19 | 20 | /** 21 | * 密码的参数名 22 | */ 23 | public static final String PASSWORD_PARAM_NAME = "password"; 24 | 25 | @Override 26 | protected KnightCredential doResolveCredential(HttpServletRequest request) { 27 | String username = request.getParameter(USERNAME_PARAM_NAME); 28 | String password = request.getParameter(PASSWORD_PARAM_NAME); 29 | if(request != null && !StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)){ 30 | KnightNamePasswordCredential credential = new KnightNamePasswordCredential(); 31 | credential.setUsername(username); 32 | credential.setPassword(password); 33 | return credential; 34 | 35 | } 36 | return null; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ki4so-web/src/main/java/com/github/ebnew/ki4so/web/action/KnigtDefaultLoginResultToView.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.web.action; 2 | 3 | import com.github.ebnew.ki4so.common.utils.StringUtils; 4 | import com.github.ebnew.ki4so.core.authentication.KnightAuthentication; 5 | import com.github.ebnew.ki4so.core.authentication.KnightAuthenticationPostHandler; 6 | import com.github.ebnew.ki4so.core.authentication.handlers.AuthenticationHandler; 7 | import com.github.ebnew.ki4so.core.message.MessageUtils; 8 | import com.github.ebnew.ki4so.core.service.LoginResult; 9 | import com.github.ebnew.ki4so.web.utils.WebConstants; 10 | import org.springframework.web.servlet.ModelAndView; 11 | import org.springframework.web.servlet.view.RedirectView; 12 | 13 | import javax.servlet.http.Cookie; 14 | import javax.servlet.http.HttpServletRequest; 15 | import javax.servlet.http.HttpServletResponse; 16 | import java.util.Map; 17 | 18 | /** 19 | * 默认的实现类 20 | * @author zhenglu 21 | * @since 15/4/30 22 | */ 23 | public class KnigtDefaultLoginResultToView implements KnightLoginResultToView{ 24 | @Override 25 | public ModelAndView loginResultToView(ModelAndView mav, LoginResult result, HttpServletRequest request, HttpServletResponse response) { 26 | //若登录成功,则返回成功页面 27 | if(mav == null){ 28 | mav = new ModelAndView(); 29 | } 30 | if(result == null || request == null || response == null){ 31 | return mav; 32 | } 33 | if(result.isSuccess()){ 34 | //登录结果对象 35 | KnightAuthentication authentication = result.getAuthentication(); 36 | request.getSession().removeAttribute(WebConstants.KI4SO_SERVICE_KEY_IN_SESSION); 37 | //knight服务端加密的凭据存在,则写入cookie中 38 | if(authentication != null && authentication.getAttrbutes() != null){ 39 | Map attributes = authentication.getAttrbutes(); 40 | //knight服务端加密的凭据存在,则写入cookie 41 | if(attributes.get(KnightAuthenticationPostHandler.KNIGHT_SERVER_EC_KEY) != null){ 42 | response.addCookie(new Cookie(WebConstants.KI4SO_SERVER_ENCRYPTED_CREDENTIAL_COOKIE_KEY,attributes.get(KnightAuthenticationPostHandler.KNIGHT_SERVER_EC_KEY).toString())); 43 | } 44 | //knight客户端加密的凭据和参数service存在,则跳转到对应的页面中 45 | if(attributes.get(KnightAuthenticationPostHandler.KNIGHT_CLIENT_EC_KEY) != null && !StringUtils.isEmpty(attributes.get(WebConstants.SERVICE_PARAM_NAME).toString())){ 46 | mav.getModel().put("authentication",authentication); 47 | mav.setView(this.buildRedirectView(attributes.get(WebConstants.SERVICE_PARAM_NAME).toString(),attributes.get(KnightAuthenticationPostHandler.KNIGHT_CLIENT_EC_KEY).toString())); 48 | return mav; 49 | 50 | } 51 | } 52 | mav.getModel().put("authentication",authentication); 53 | mav.setViewName("loginSuccess"); 54 | 55 | }else{ 56 | //删除以前不合法的凭据信息 57 | //清除cookie值 58 | Cookie[] cookies = request.getCookies(); 59 | for (Cookie cookie:cookies){ 60 | if(WebConstants.KI4SO_SERVER_ENCRYPTED_CREDENTIAL_COOKIE_KEY.equals(cookie.getName())){ 61 | cookie.setMaxAge(0); 62 | response.addCookie(cookie); 63 | } 64 | } 65 | mav.getModel().put("code",result.getCode()); 66 | mav.getModel().put("msg", MessageUtils.getMessage(result.getMsgKey())); 67 | } 68 | 69 | return mav; 70 | } 71 | private RedirectView buildRedirectView(String service,String encryCredentital){ 72 | StringBuffer buffer = new StringBuffer(service); 73 | if(service.contains("?")){ 74 | buffer.append("&"); 75 | }else { 76 | buffer.append("?"); 77 | } 78 | buffer.append(WebConstants.KI4SO_CLIENT_ENCRYPTED_CREDENTIAL_COOKIE_KEY).append("=").append(encryCredentital); 79 | return new RedirectView(buffer.toString()); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /ki4so-web/src/main/java/com/github/ebnew/ki4so/web/action/LoginAction.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.web.action; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | 6 | import com.github.ebnew.ki4so.core.authentication.KnightCredential; 7 | import com.github.ebnew.ki4so.core.service.KnightService; 8 | import org.apache.log4j.Logger; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Controller; 11 | import org.springframework.util.StringUtils; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.servlet.ModelAndView; 14 | 15 | import com.github.ebnew.ki4so.core.service.LoginResult; 16 | import com.github.ebnew.ki4so.web.utils.WebConstants; 17 | 18 | /** 19 | * 登入web控制器类,处理登录的请求。 20 | * @author 不二 21 | * 22 | */ 23 | @Controller 24 | public class LoginAction { 25 | 26 | private static final Logger LOGGER = Logger.getLogger(LoginAction.class); 27 | 28 | @Autowired 29 | protected KnightCredentialResolver credentialResolver; 30 | 31 | @Autowired 32 | protected KnightService ki4soService; 33 | 34 | @Autowired 35 | protected LoginResultToView loginResultToView; 36 | 37 | 38 | 39 | /** 40 | * 登录接口,该接口处理所有与登录有关的请求。 41 | * 42 | * @param 43 | * @return 44 | */ 45 | @RequestMapping("/login") 46 | public ModelAndView login(HttpServletRequest request, 47 | HttpServletResponse response) { 48 | 49 | ModelAndView mv = new ModelAndView(); 50 | mv.setViewName("login"); 51 | LOGGER.debug("enter login action"); 52 | //解析用户凭据。 53 | KnightCredential credential = credentialResolver.resolveCredential(request); 54 | //没有提供任何认证凭据。 55 | if(credential==null){ 56 | //设置serivce地址到session中。 57 | String service = request.getParameter(WebConstants.SERVICE_PARAM_NAME); 58 | LOGGER.debug("the servcie is "+service); 59 | if(!StringUtils.isEmpty(service)){ 60 | request.getSession().setAttribute(WebConstants.KI4SO_SERVICE_KEY_IN_SESSION, service); 61 | } 62 | LOGGER.info("no credential, return login page"); 63 | //返回到登录页面,索取用户凭据。 64 | return mv; 65 | } 66 | //提供了用户凭据 67 | else{ 68 | //调用核心结果进行凭据认证。 69 | LoginResult result = ki4soService.login(credential); 70 | //将验证结果转换为视图输出结果。 71 | mv = loginResultToView.loginResultToView(mv, result, request, response); 72 | } 73 | return mv; 74 | } 75 | 76 | 77 | } 78 | -------------------------------------------------------------------------------- /ki4so-web/src/main/java/com/github/ebnew/ki4so/web/action/LoginResultToView.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.web.action; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | 6 | import org.springframework.web.servlet.ModelAndView; 7 | 8 | import com.github.ebnew.ki4so.core.service.LoginResult; 9 | 10 | /** 11 | * 该接口实现了将登录结果转换为视图响应的功能。 12 | * @author Administrator 13 | * 14 | */ 15 | public interface LoginResultToView { 16 | 17 | /** 18 | * 将登录结果对象相应到模型和视图中。 19 | * 所有参数均不允许输入null. 20 | * @param mv 模型视图对象。 21 | * @param result 登录结果信息。 22 | * @param request http请求对象。 23 | * @param response http响应对象。 24 | * @return 更新后的模型视图对象。 25 | */ 26 | public ModelAndView loginResultToView(ModelAndView mv, LoginResult result, HttpServletRequest request, HttpServletResponse response); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /ki4so-web/src/main/java/com/github/ebnew/ki4so/web/action/LogoutAction.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.web.action; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.http.Cookie; 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | import javax.servlet.http.HttpSession; 9 | 10 | import com.github.ebnew.ki4so.core.authentication.KnightCredential; 11 | import com.github.ebnew.ki4so.core.service.KnightService; 12 | import org.apache.log4j.Logger; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.stereotype.Controller; 15 | import org.springframework.util.StringUtils; 16 | import org.springframework.web.bind.annotation.RequestMapping; 17 | import org.springframework.web.servlet.ModelAndView; 18 | import org.springframework.web.servlet.view.RedirectView; 19 | 20 | import com.github.ebnew.ki4so.client.web.filters.Ki4soClientFilter; 21 | import com.github.ebnew.ki4so.core.authentication.Credential; 22 | import com.github.ebnew.ki4so.core.service.Ki4soService; 23 | import com.github.ebnew.ki4so.web.utils.WebConstants; 24 | 25 | /** 26 | * 登出web控制器,处理登出的请求。 27 | * @author burgess yang 28 | * 29 | */ 30 | @Controller 31 | public class LogoutAction { 32 | 33 | private static final Logger LOGGER = Logger.getLogger(LogoutAction.class); 34 | 35 | @Autowired 36 | protected KnightCredentialResolver credentialResolver; 37 | 38 | @Autowired 39 | protected KnightService ki4soService; 40 | 41 | public void setKi4soService(KnightService ki4soService) { 42 | this.ki4soService = ki4soService; 43 | } 44 | 45 | /** 46 | * 设置用户凭据解析器。 47 | * @param credentialResolver 48 | */ 49 | public void setCredentialResolver(KnightCredentialResolver credentialResolver) { 50 | this.credentialResolver = credentialResolver; 51 | } 52 | 53 | /** 54 | * 处理登出ki4so服务器的请求。 55 | * 1.清除用户登录的状态信息,即用户登录了那些应用。 56 | * 2.清除sso服务端的cookie。 57 | * 3.统一登出用户登出过的所有应用。 58 | * @param request 请求对象。 59 | * @param response 响应对象。 60 | * 如果参数servcie有合法的值,则跳转到该地址。否则返回到默认的登出成功页面。 61 | * @throws IOException 62 | */ 63 | @RequestMapping("/logout") 64 | public ModelAndView logout(HttpServletRequest request, 65 | HttpServletResponse response,HttpSession session) throws IOException { 66 | 67 | ModelAndView modelAndView = new ModelAndView(); 68 | 69 | //获得service. 70 | String service = request.getParameter(WebConstants.SERVICE_PARAM_NAME); 71 | LOGGER.info("the service of logout is "+service); 72 | //解析用户凭据。 73 | KnightCredential credential = credentialResolver.resolveCredential(request); 74 | //调用servie统一登出所有的应用。 75 | this.ki4soService.logout(credential, service); 76 | 77 | //清除cookie值。 78 | Cookie[] cookies = request.getCookies(); 79 | if(cookies!=null && cookies.length>0){ 80 | for(Cookie cookie:cookies){ 81 | if(WebConstants.KI4SO_SERVER_ENCRYPTED_CREDENTIAL_COOKIE_KEY.equals(cookie.getName())){ 82 | //设置过期时间为立即。 83 | cookie.setMaxAge(0); 84 | response.addCookie(cookie); 85 | LOGGER.info("clear up the cookie "+WebConstants.KI4SO_SERVER_ENCRYPTED_CREDENTIAL_COOKIE_KEY); 86 | } 87 | } 88 | } 89 | 90 | if(!StringUtils.isEmpty(service)){ 91 | //跳转到service对应的URL地址 92 | modelAndView.setView(new RedirectView(service)); 93 | session.setAttribute(Ki4soClientFilter.USER_STATE_IN_SESSION_KEY,null); 94 | } 95 | else{ 96 | //返回默认的登出成功页面。 97 | modelAndView.setViewName("logoutSucess"); 98 | } 99 | return modelAndView; 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /ki4so-web/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=DEBUG, stdout 2 | 3 | # Direct log messages to stdout 4 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 5 | log4j.appender.stdout.Target=System.out 6 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n -------------------------------------------------------------------------------- /ki4so-web/src/main/resources/spring/spring-beans.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /ki4so-web/src/main/resources/spring/springmvc-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | text/html;charset=UTF-8 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /ki4so-web/src/main/webapp/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /ki4so-web/src/main/webapp/META-INF/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /ki4so-web/src/main/webapp/WEB-INF/pages/login.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 4 | 5 | 6 | 7 | 8 | 9 | 默认登录界面 10 | 11 | 12 |

这是ki4so默认的登录界面,请替换为自己的页面

13 |

默认的demo示例是若用户名和密码完全相同则登录成功,比如用户名是test,密码是test则能够登录成功。

14 |
15 |
16 | 登录 17 |
18 |
19 | 20 |
21 |
22 | 23 |
24 |
25 | 26 | -------------------------------------------------------------------------------- /ki4so-web/src/main/webapp/WEB-INF/pages/loginSucess.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 4 | 5 | 6 | 7 | 8 | 登录成功 9 | 10 | 11 | 12 | 13 |

恭喜您,登录成功!

14 |

15 | 认证用户ID: ${authentication.principal.id} 16 |

17 |

18 | 认证时间:${authentication.authenticatedDate} 19 |

20 |

21 | 统一登出    22 | 返回登录 23 |

24 | 25 | -------------------------------------------------------------------------------- /ki4so-web/src/main/webapp/WEB-INF/pages/logoutSucess.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 4 | 5 | 6 | 7 | 8 | 登录成功 9 | 10 | 11 | 12 | 13 |

恭喜您,登出成功!

14 |

15 | 这是默认的登出成功页面 16 |

17 |

18 | 返回再次登录 19 |

20 | 21 | -------------------------------------------------------------------------------- /ki4so-web/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | ki4so-web 8 | 9 | 本项目是ki4so的web工程,提供了对外的http接口。 10 | 11 | 12 | 13 | 14 | springmvc 15 | org.springframework.web.servlet.DispatcherServlet 16 | 17 | contextConfigLocation 18 | classpath:spring/*.xml 19 | 20 | 0 21 | 22 | 23 | 24 | springmvc 25 | *.do 26 | 27 | 28 | 29 | 30 | /index.jsp 31 | 32 | 33 | -------------------------------------------------------------------------------- /ki4so-web/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | 4 | 5 | 6 | 7 | 首页 8 | 9 | 10 | 这是ki4so服务端的web工程,请访问默认登录页面。 11 |

12 | 登录页面 13 |

14 | 15 | -------------------------------------------------------------------------------- /ki4so-web/src/test/java/README.md: -------------------------------------------------------------------------------- 1 | 测试类,该文件夹下 存放了所有的测试类。 -------------------------------------------------------------------------------- /ki4so-web/src/test/java/com/github/ebnew/ki4so/web/action/EncryCredentialResolverTest.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.web.action; 2 | 3 | import javax.servlet.http.Cookie; 4 | 5 | import junit.framework.Assert; 6 | 7 | import org.junit.After; 8 | import org.junit.Before; 9 | import org.junit.Test; 10 | import org.springframework.mock.web.MockHttpServletRequest; 11 | 12 | import com.github.ebnew.ki4so.core.authentication.EncryCredential; 13 | import com.github.ebnew.ki4so.web.utils.WebConstants; 14 | 15 | public class EncryCredentialResolverTest { 16 | 17 | /** 18 | * 被测对象。 19 | */ 20 | private EncryCredentialResolver resolver; 21 | 22 | @Before 23 | public void setUp() throws Exception { 24 | resolver = new EncryCredentialResolver(); 25 | } 26 | 27 | @After 28 | public void tearDown() throws Exception { 29 | } 30 | 31 | @Test 32 | public void testResolveCredential(){ 33 | String cookie = "VS032SDAFDAFD"; 34 | 35 | //测试传入null的情况。 36 | Assert.assertNull(resolver.resolveCredential(null)); 37 | 38 | //测试不存在cookie的情况。 39 | MockHttpServletRequest request = new MockHttpServletRequest(); 40 | Assert.assertNull(resolver.resolveCredential(request)); 41 | 42 | //测试存在cookie,但是cookie中值是的元素为null的情况。 43 | request = new MockHttpServletRequest(); 44 | request.setCookies(null, null, null, null); 45 | Assert.assertNull(resolver.resolveCredential(request)); 46 | 47 | //测试存在cookie数组,但是有2个不为null的情况。 48 | request = new MockHttpServletRequest(); 49 | request.setCookies(new Cookie("C1", null), null, null, new Cookie("C2", "dafdafdada")); 50 | Assert.assertNull(resolver.resolveCredential(request)); 51 | 52 | 53 | //测试存在cookie数组,但是有1个不为null的情况,且cookie名称为KI4SO服务端写入的cookie值,但是cookie的值为Null. 54 | request = new MockHttpServletRequest(); 55 | request.setCookies(new Cookie("C1", null), null, null, new Cookie(WebConstants.KI4SO_SERVER_ENCRYPTED_CREDENTIAL_COOKIE_KEY, null)); 56 | Assert.assertNull(resolver.resolveCredential(request)); 57 | 58 | 59 | //测试存在cookie数组,但是有1个不为null的情况,且cookie名称为KI4SO服务端写入的cookie值,但是cookie的值不是Null. 60 | request = new MockHttpServletRequest(); 61 | request.setCookies(new Cookie("C1", null), null, null, new Cookie(WebConstants.KI4SO_SERVER_ENCRYPTED_CREDENTIAL_COOKIE_KEY, cookie)); 62 | EncryCredential credential = (EncryCredential)resolver.resolveCredential(request); 63 | Assert.assertNotNull(credential); 64 | Assert.assertEquals(cookie, credential.getCredential()); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /ki4so-web/src/test/java/com/github/ebnew/ki4so/web/action/KeyActionTest.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.web.action; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | 5 | import org.junit.After; 6 | import org.junit.Assert; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | import org.mockito.Mockito; 10 | 11 | import com.github.ebnew.ki4so.core.key.KeyService; 12 | import com.github.ebnew.ki4so.core.key.Ki4soKey; 13 | 14 | public class KeyActionTest { 15 | 16 | private KeyAction keyAction = new KeyAction(); 17 | 18 | @Before 19 | public void setUp() throws Exception { 20 | keyAction = new KeyAction(); 21 | } 22 | 23 | @After 24 | public void tearDown() throws Exception { 25 | } 26 | 27 | @Test 28 | public void testFetchKey() throws UnsupportedEncodingException { 29 | KeyService keyService = Mockito.mock(KeyService.class); 30 | Ki4soKey ki4soKey = Mockito.mock(Ki4soKey.class); 31 | Mockito.when(keyService.findKeyByAppId(Mockito.anyString())).thenReturn(ki4soKey); 32 | keyAction.setKeyService(keyService); 33 | Ki4soKey result = keyAction.fetchKey("100"); 34 | Assert.assertTrue(ki4soKey==result); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /ki4so-web/src/test/java/com/github/ebnew/ki4so/web/action/LogoutActionTest.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.web.action; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.http.Cookie; 6 | import javax.servlet.http.HttpSession; 7 | 8 | import junit.framework.Assert; 9 | 10 | import org.junit.After; 11 | import org.junit.Before; 12 | import org.junit.Test; 13 | import org.mockito.Mockito; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.mock.web.MockHttpServletRequest; 16 | import org.springframework.mock.web.MockHttpServletResponse; 17 | import org.springframework.web.servlet.ModelAndView; 18 | import org.springframework.web.servlet.view.RedirectView; 19 | 20 | import com.github.ebnew.ki4so.core.service.Ki4soService; 21 | import com.github.ebnew.ki4so.web.utils.WebConstants; 22 | 23 | /** 24 | * 登出测试类。 25 | * @author burgess yang 26 | * 27 | */ 28 | public class LogoutActionTest { 29 | 30 | @Autowired 31 | private LogoutAction logoutAction; 32 | 33 | @Before 34 | public void setUp() throws Exception { 35 | logoutAction = new LogoutAction(); 36 | } 37 | 38 | @After 39 | public void tearDown() throws Exception { 40 | } 41 | 42 | @Test 43 | public void testLogoutWithoutCredential() throws IOException { 44 | MockHttpServletRequest request = new MockHttpServletRequest(); 45 | MockHttpServletResponse response = new MockHttpServletResponse(); 46 | HttpSession session = request.getSession(); 47 | CredentialResolver credentialResolver = Mockito.mock(CredentialResolver.class); 48 | logoutAction.setCredentialResolver(credentialResolver); 49 | 50 | Ki4soService ki4soService = Mockito.mock(Ki4soService.class); 51 | logoutAction.setKi4soService(ki4soService); 52 | 53 | //测试没有cookie的情况。即要登出的凭据不存在的情况。则返回默认的登出成功页面。 54 | ModelAndView mv = logoutAction.logout(request, response, session); 55 | Assert.assertEquals(0, response.getCookies().length); 56 | Assert.assertEquals("logoutSucess", mv.getViewName()); 57 | } 58 | 59 | @Test 60 | public void testLogoutWithCredentialButNoService() throws IOException { 61 | MockHttpServletRequest request = new MockHttpServletRequest(); 62 | MockHttpServletResponse response = new MockHttpServletResponse(); 63 | HttpSession session = request.getSession(); 64 | CredentialResolver credentialResolver = Mockito.mock(CredentialResolver.class); 65 | logoutAction.setCredentialResolver(credentialResolver); 66 | Ki4soService ki4soService = Mockito.mock(Ki4soService.class); 67 | logoutAction.setKi4soService(ki4soService); 68 | 69 | //测试存在cookie,登出后要清除cookie值,但是service参数的值是null的情况。 70 | request.setCookies(new Cookie(WebConstants.KI4SO_SERVER_ENCRYPTED_CREDENTIAL_COOKIE_KEY, "dddsd")); 71 | ModelAndView mv = logoutAction.logout(request, response,session); 72 | Assert.assertEquals(1, response.getCookies().length); 73 | Assert.assertEquals(0, response.getCookies()[0].getMaxAge()); 74 | Assert.assertEquals("logoutSucess", mv.getViewName()); 75 | } 76 | 77 | 78 | @Test 79 | public void testLogoutWithCredentialAndService() throws IOException { 80 | String servce = "http://app.com/logoutSucess.do"; 81 | 82 | MockHttpServletRequest request = new MockHttpServletRequest(); 83 | request.setParameter(WebConstants.SERVICE_PARAM_NAME, servce); 84 | MockHttpServletResponse response = new MockHttpServletResponse(); 85 | HttpSession session = request.getSession(); 86 | CredentialResolver credentialResolver = Mockito.mock(CredentialResolver.class); 87 | logoutAction.setCredentialResolver(credentialResolver); 88 | Ki4soService ki4soService = Mockito.mock(Ki4soService.class); 89 | logoutAction.setKi4soService(ki4soService); 90 | 91 | //测试存在cookie,登出后要清除cookie值,但是service参数的值是null的情况。 92 | request.setCookies(new Cookie(WebConstants.KI4SO_SERVER_ENCRYPTED_CREDENTIAL_COOKIE_KEY, "dddsd")); 93 | 94 | ModelAndView mv = logoutAction.logout(request, response,session); 95 | Assert.assertEquals(1, response.getCookies().length); 96 | Assert.assertEquals(0, response.getCookies()[0].getMaxAge()); 97 | RedirectView view = (RedirectView) mv.getView(); 98 | Assert.assertEquals(servce, view.getUrl()); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /ki4so-web/src/test/java/com/github/ebnew/ki4so/web/action/UsernamePasswordCredentialResolverTest.java: -------------------------------------------------------------------------------- 1 | package com.github.ebnew.ki4so.web.action; 2 | 3 | import junit.framework.Assert; 4 | 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | import org.springframework.mock.web.MockHttpServletRequest; 9 | 10 | import com.github.ebnew.ki4so.core.authentication.UsernamePasswordCredential; 11 | 12 | public class UsernamePasswordCredentialResolverTest { 13 | 14 | /** 15 | * 被测对象。 16 | */ 17 | private UsernamePasswordCredentialResolver resolver; 18 | 19 | @Before 20 | public void setUp() throws Exception { 21 | resolver = new UsernamePasswordCredentialResolver(); 22 | } 23 | 24 | @After 25 | public void tearDown() throws Exception { 26 | } 27 | 28 | @Test 29 | public void testResolveCredential(){ 30 | String username = "admin"; 31 | String password = "sssss"; 32 | 33 | //测试传入null的情况。 34 | Assert.assertNull(resolver.resolveCredential(null)); 35 | //测试两个参数全部为null的情况。 36 | MockHttpServletRequest request = new MockHttpServletRequest(); 37 | Assert.assertNull(resolver.resolveCredential(request)); 38 | 39 | //测试用户名为null,密码不为null的情况。 40 | request = new MockHttpServletRequest(); 41 | request.setParameter(UsernamePasswordCredentialResolver.PASSWORD_PARAM_NAME, password); 42 | Assert.assertNull(resolver.resolveCredential(request)); 43 | 44 | //测试用户名不为null,密码为null的情况。 45 | request = new MockHttpServletRequest(); 46 | request.setParameter(UsernamePasswordCredentialResolver.USERNAME_PARAM_NAME, username); 47 | Assert.assertNull(resolver.resolveCredential(request)); 48 | 49 | //测试测试用户名密码都不为null的情况。 50 | request = new MockHttpServletRequest(); 51 | request.setParameter(UsernamePasswordCredentialResolver.USERNAME_PARAM_NAME, username); 52 | request.setParameter(UsernamePasswordCredentialResolver.PASSWORD_PARAM_NAME, password); 53 | UsernamePasswordCredential credential = (UsernamePasswordCredential)resolver.resolveCredential(request); 54 | Assert.assertNotNull(credential); 55 | Assert.assertEquals(username, credential.getUsername()); 56 | Assert.assertEquals(password, credential.getPassword()); 57 | 58 | Assert.assertEquals(2, credential.getParameters().size()); 59 | 60 | } 61 | 62 | } 63 | --------------------------------------------------------------------------------