🎨 Improving code

This commit is contained in:
yadong.zhang 2021-02-20 15:35:52 +08:00
parent 98755478d6
commit 1034a0957b
25 changed files with 152 additions and 283 deletions

3
.gitignore vendored
View File

@ -48,10 +48,7 @@ build/
.vscode/
### other ###
/jap-core/src/main/java/com/fujieid/jap/core/context/
/jap-simple/src/main/java/com/fujieid/jap/simple/SimpleAuthentication.java
/jap-simple/src/main/java/com/fujieid/jap/simple/SimpleCallback.java
/jap-core/src/main/java/com/fujieid/jap/core/Credential.java
/docs/bin/deploy.sh
/jap-core/pom.xml.versionsBackup
/jap-oauth2/pom.xml.versionsBackup

View File

@ -24,7 +24,7 @@ fi
# 替换README.md等文件中的版本
sed -i "s/${old_version}/${new_version}/g" $pwd/README.md
sed -i "s/${old_version}/${new_version}/g" $pwd/README.en-US.md
sed -i "s/${old_version}/${new_version}/g" $pwd/README.en.md
# 保留新版本号
echo "$new_version" > $pwd/docs/bin/version.txt

View File

@ -1 +1 @@
1.0.0
1.0.1

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.fujieid</groupId>
<artifactId>jap</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -51,11 +51,6 @@ public class JapConfig {
*/
private String successRedirect = "/";
/**
* Prompt message after successful login
*/
private String successMessage;
/**
* After logout, redirect to {@code logoutRedirect}. Default is `/`
*/
@ -66,11 +61,6 @@ public class JapConfig {
*/
private String failureRedirect = "/error";
/**
* Prompt message after login failed
*/
private String failureMessage;
public String getLoginUrl() {
return loginUrl;
}
@ -116,15 +106,6 @@ public class JapConfig {
return this;
}
public String getSuccessMessage() {
return successMessage;
}
public JapConfig setSuccessMessage(String successMessage) {
this.successMessage = successMessage;
return this;
}
public String getFailureRedirect() {
return failureRedirect;
}
@ -134,15 +115,6 @@ public class JapConfig {
return this;
}
public String getFailureMessage() {
return failureMessage;
}
public JapConfig setFailureMessage(String failureMessage) {
this.failureMessage = failureMessage;
return this;
}
public String getLogoutRedirect() {
return logoutRedirect;
}

View File

@ -1,41 +0,0 @@
/*
* Copyright (c) 2020-2040, 北京符节科技有限公司 (support@fujieid.com & https://www.fujieid.com).
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.fujieid.jap.core.cache;
/**
* Stores {@link com.fujieid.jap.core.cache.JapCache} for global calls
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public class JapCacheContextHolder {
private static JapCache currentJapCache;
public static void enable(JapCache japCache) {
currentJapCache = null == japCache ? new JapLocalCache() : japCache;
}
public static JapCache getCache() {
if (null == currentJapCache) {
JapCache japCache = new JapLocalCache();
enable(japCache);
return japCache;
}
return currentJapCache;
}
}

View File

@ -13,66 +13,60 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.fujieid.jap.core.store;
package com.fujieid.jap.core.context;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.fujieid.jap.core.JapConfig;
import com.fujieid.jap.core.JapUser;
import com.fujieid.jap.core.exception.JapException;
import com.fujieid.jap.core.JapUtil;
import com.fujieid.jap.core.store.JapUserStore;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.Map;
/**
* Store and obtain the {@code JapUserStore}, and provide simple operation for users.
* <p>
* Currently, Mixed scenarios of single sign on and non single sign on are not supported for the time being, such as:
* The system uses a variety of login methods, such as {@code jap-simple} and {@code jap-oauth2},
* but it requires that {@code jap-simple} support Single sign on of {@code jap-oauth2} does not support Single sign on.
* Manage the context of jap, after successful login,
* you can obtain the logged-in user information through jap authentication or execute logout events
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public class JapUserStoreContextHolder {
private static final Log log = LogFactory.get();
public class JapAuthentication implements Serializable {
private static JapContext context;
private static JapUserStore currentJapUserStore;
public static void enable(JapUserStore japUserStore) {
if (null == japUserStore) {
throw new JapException("JapUserStore cannot be null.");
}
currentJapUserStore = japUserStore;
private JapAuthentication() {
}
public static JapUserStore getUserStore() {
if (null == currentJapUserStore) {
log.warn("JapUserStore has not been initialized yet.");
public static JapContext getContext() {
return context;
}
public static void setContext(JapContext japContext) {
context = japContext;
}
public static JapUser getUser(HttpServletRequest request, HttpServletResponse response) {
if (null == context) {
return null;
}
return currentJapUserStore;
JapUserStore japUserStore = context.getUserStore();
if (null == japUserStore) {
return null;
}
return japUserStore.get(request, response);
}
public static JapUser getStoreUser(HttpServletRequest request, HttpServletResponse response) {
JapUserStore japUserStore = getUserStore();
return null == japUserStore ? null : japUserStore.get(request, response);
}
public static void removeStoreUser(HttpServletRequest request, HttpServletResponse response) {
JapUserStore japUserStore = getUserStore();
public static void logout(HttpServletRequest request, HttpServletResponse response) {
JapUserStore japUserStore = context.getUserStore();
if (null == japUserStore) {
return;
}
japUserStore.remove(request, response);
}
public static void logout(HttpServletRequest request, HttpServletResponse response) {
removeStoreUser(request, response);
// Clear all cookie information
Map<String, Cookie> cookieMap = ServletUtil.readCookieMap(request);
@ -83,5 +77,11 @@ public class JapUserStoreContextHolder {
cookie.setMaxAge(0);
response.addCookie(cookie);
});
JapConfig config = context.getConfig();
if (null != config) {
JapUtil.redirect(config.getLogoutRedirect(), response);
}
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2020-2040, 北京符节科技有限公司 (support@fujieid.com & https://www.fujieid.com).
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.fujieid.jap.core.context;
import com.fujieid.jap.core.JapConfig;
import com.fujieid.jap.core.cache.JapCache;
import com.fujieid.jap.core.store.JapUserStore;
/**
* The context of jap.
* <p>
* Persist jap user store, jap cache and jap config in memory to facilitate the management of jap user data.
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public class JapContext {
/**
* user store
*/
private JapUserStore userStore;
/**
* jap cache
*/
private JapCache cache;
/**
* Jap configuration.
*/
private JapConfig config;
public JapContext() {
}
public JapContext(JapUserStore userStore, JapCache cache, JapConfig config) {
this.userStore = userStore;
this.cache = cache;
this.config = config;
}
public JapUserStore getUserStore() {
return userStore;
}
public JapContext setUserStore(JapUserStore userStore) {
this.userStore = userStore;
return this;
}
public JapCache getCache() {
return cache;
}
public JapContext setCache(JapCache cache) {
this.cache = cache;
return this;
}
public JapConfig getConfig() {
return config;
}
public JapContext setConfig(JapConfig config) {
this.config = config;
return this;
}
}

View File

@ -19,11 +19,11 @@ import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ObjectUtil;
import com.fujieid.jap.core.*;
import com.fujieid.jap.core.cache.JapCache;
import com.fujieid.jap.core.cache.JapCacheContextHolder;
import com.fujieid.jap.core.cache.JapLocalCache;
import com.fujieid.jap.core.context.JapAuthentication;
import com.fujieid.jap.core.context.JapContext;
import com.fujieid.jap.core.exception.JapException;
import com.fujieid.jap.core.store.JapUserStore;
import com.fujieid.jap.core.store.JapUserStoreContextHolder;
import com.fujieid.jap.core.store.SessionJapUserStore;
import com.fujieid.jap.core.store.SsoJapUserStore;
import com.fujieid.jap.sso.JapSsoHelper;
@ -45,18 +45,10 @@ public abstract class AbstractJapStrategy implements JapStrategy {
* Abstract the user-related function interface, which is implemented by the caller business system.
*/
protected JapUserService japUserService;
/**
* user store
*/
protected JapUserStore japUserStore;
/**
* jap cache
*/
protected JapCache japCache;
/**
* Jap configuration.
*/
protected JapConfig japConfig;
protected JapContext japContext;
/**
* `Strategy` constructor.
@ -77,37 +69,36 @@ public abstract class AbstractJapStrategy implements JapStrategy {
*/
public AbstractJapStrategy(JapUserService japUserService, JapConfig japConfig, JapCache japCache) {
this.japUserService = japUserService;
this.japCache = japCache;
this.japConfig = japConfig;
this.japUserStore = japConfig.isSso() ? new SsoJapUserStore(japUserService, japConfig.getSsoConfig()) : new SessionJapUserStore();
if (japConfig.isSso()) {
// init Kisso config
JapSsoHelper.initKissoConfig(japConfig.getSsoConfig());
}
JapUserStore japUserStore = japConfig.isSso() ? new SsoJapUserStore(japUserService, japConfig.getSsoConfig()) : new SessionJapUserStore();
this.japContext = new JapContext(japUserStore, japCache, japConfig);
JapAuthentication.setContext(this.japContext);
JapUserStoreContextHolder.enable(this.japUserStore);
JapCacheContextHolder.enable(this.japCache);
}
/**
* Verify whether the user logs in. If so, jump to {@code japConfig.getSuccessRedirect()}. Otherwise, return {@code false}
*
* @param request Current Authentication Request
* @param request Current JapAuthentication Request
* @param response Current response
* @return boolean
*/
protected boolean checkSession(HttpServletRequest request, HttpServletResponse response) {
JapUser sessionUser = japUserStore.get(request, response);
JapUser sessionUser = japContext.getUserStore().get(request, response);
if (null != sessionUser) {
JapUtil.redirect(japConfig.getSuccessRedirect(), response);
JapUtil.redirect(japContext.getConfig().getSuccessRedirect(), response);
return true;
}
return false;
}
protected void loginSuccess(JapUser japUser, HttpServletRequest request, HttpServletResponse response) {
japUserStore.save(request, response, japUser);
JapUtil.redirect(japConfig.getSuccessRedirect(), response);
japContext.getUserStore().save(request, response, japUser);
JapUtil.redirect(japContext.getConfig().getSuccessRedirect(), response);
}
/**

View File

@ -1,99 +0,0 @@
/*
* Copyright (c) 2020-2040, 北京符节科技有限公司 (support@fujieid.com & https://www.fujieid.com).
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.fujieid.jap.core.cache;
import org.junit.Assert;
import org.junit.Test;
import java.io.Serializable;
/**
* unit test
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @version 1.0.0
* @since 1.0.0
*/
public class JapCacheContextHolderTest {
@Test
public void enableNull() {
JapCacheContextHolder.enable(null);
Assert.assertTrue(JapCacheContextHolder.getCache() instanceof JapLocalCache);
}
@Test
public void enableJapCache() {
JapCacheContextHolder.enable(new TestJapCacheImpl());
Assert.assertFalse(JapCacheContextHolder.getCache() instanceof JapLocalCache);
Assert.assertTrue(JapCacheContextHolder.getCache() instanceof TestJapCacheImpl);
}
@Test
public void getCache() {
JapCache japCache = JapCacheContextHolder.getCache();
Assert.assertTrue(japCache instanceof JapLocalCache);
JapCacheContextHolder.enable(new TestJapCacheImpl());
Assert.assertTrue(JapCacheContextHolder.getCache() instanceof TestJapCacheImpl);
}
public static class TestJapCacheImpl implements JapCache {
/**
* Set cache
*
* @param key Cache key
* @param value Cache value after serialization
*/
@Override
public void set(String key, Serializable value) {
}
/**
* Set the cache and specify the expiration time of the cache
*
* @param key Cache key
* @param value Cache value after serialization
* @param timeout The expiration time of the cache, in milliseconds
*/
@Override
public void set(String key, Serializable value, long timeout) {
}
/**
* Get cache value
*
* @param key Cache key
* @return Cache value
*/
@Override
public Serializable get(String key) {
return null;
}
/**
* Determine whether a key exists in the cache
*
* @param key Cache key
* @return boolean
*/
@Override
public boolean containsKey(String key) {
return false;
}
}
}

View File

@ -3,9 +3,9 @@
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jap</artifactId>
<groupId>com.fujieid</groupId>
<version>1.0.0</version>
<artifactId>jap</artifactId>
<version>1.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.fujieid</groupId>
<artifactId>jap</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -18,8 +18,7 @@ package com.fujieid.jap.oauth2;
import cn.hutool.core.util.*;
import com.fujieid.jap.core.*;
import com.fujieid.jap.core.cache.JapCache;
import com.fujieid.jap.core.cache.JapCacheContextHolder;
import com.fujieid.jap.core.exception.JapOauth2Exception;
import com.fujieid.jap.core.context.JapAuthentication;
import com.fujieid.jap.core.exception.JapUserException;
import com.fujieid.jap.core.strategy.AbstractJapStrategy;
import com.fujieid.jap.oauth2.pkce.PkceHelper;
@ -159,7 +158,7 @@ public class Oauth2Strategy extends AbstractJapStrategy {
state = RandomUtil.randomString(6);
}
params.put("state", oAuthConfig.getState());
JapCacheContextHolder.getCache().set(Oauth2Const.STATE_CACHE_KEY.concat(oAuthConfig.getClientId()), state);
JapAuthentication.getContext().getCache().set(Oauth2Const.STATE_CACHE_KEY.concat(oAuthConfig.getClientId()), state);
// Pkce is only applicable to authorization code mode
if (Oauth2ResponseType.code == oAuthConfig.getResponseType() && oAuthConfig.isEnablePkce()) {
params.putAll(PkceHelper.generatePkceParameters(oAuthConfig));

View File

@ -20,7 +20,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.fujieid.jap.core.cache.JapCacheContextHolder;
import com.fujieid.jap.core.context.JapAuthentication;
import com.fujieid.jap.core.exception.JapOauth2Exception;
import com.fujieid.jap.oauth2.pkce.PkceCodeChallengeMethod;
import com.xkcoding.json.util.Kv;
@ -95,7 +95,7 @@ public class Oauth2Util {
throw new JapOauth2Exception("Illegal state.");
}
Serializable cacheState = JapCacheContextHolder.getCache().get(Oauth2Const.STATE_CACHE_KEY.concat(clientId));
Serializable cacheState = JapAuthentication.getContext().getCache().get(Oauth2Const.STATE_CACHE_KEY.concat(clientId));
if (null == cacheState || !cacheState.equals(state)) {
throw new JapOauth2Exception("Illegal state.");
}

View File

@ -15,7 +15,7 @@
*/
package com.fujieid.jap.oauth2.pkce;
import com.fujieid.jap.core.cache.JapCacheContextHolder;
import com.fujieid.jap.core.context.JapAuthentication;
import com.fujieid.jap.oauth2.OAuthConfig;
import com.fujieid.jap.oauth2.Oauth2Util;
import com.google.common.collect.Maps;
@ -59,7 +59,7 @@ public class PkceHelper {
params.put(PkceParams.CODE_CHALLENGE, codeChallenge);
params.put(PkceParams.CODE_CHALLENGE_METHOD, pkceCodeChallengeMethod);
// The default cache is local map.
JapCacheContextHolder.getCache().set(oAuthConfig.getClientId(), codeVerifier, oAuthConfig.getCodeVerifierTimeout());
JapAuthentication.getContext().getCache().set(oAuthConfig.getClientId(), codeVerifier, oAuthConfig.getCodeVerifierTimeout());
return params;
}
@ -70,6 +70,6 @@ public class PkceHelper {
* @return {@code code_verifier}
*/
public static String getCacheCodeVerifier(String clientId) {
return (String) JapCacheContextHolder.getCache().get(clientId);
return (String) JapAuthentication.getContext().getCache().get(clientId);
}
}

View File

@ -16,8 +16,9 @@
package com.fujieid.jap.oauth2;
import com.fujieid.jap.core.cache.JapCache;
import com.fujieid.jap.core.cache.JapCacheContextHolder;
import com.fujieid.jap.core.cache.JapLocalCache;
import com.fujieid.jap.core.context.JapAuthentication;
import com.fujieid.jap.core.context.JapContext;
import com.fujieid.jap.core.exception.JapOauth2Exception;
import com.fujieid.jap.oauth2.pkce.PkceCodeChallengeMethod;
import com.xkcoding.json.util.Kv;
@ -158,7 +159,7 @@ public class Oauth2UtilTest {
boolean verifyState = true;
JapCache cache = new JapLocalCache();
cache.set(Oauth2Const.STATE_CACHE_KEY.concat(clientId), state);
JapCacheContextHolder.enable(cache);
JapAuthentication.setContext(new JapContext().setCache(cache));
Oauth2Util.checkState(state, clientId, verifyState);
}
@ -169,7 +170,7 @@ public class Oauth2UtilTest {
boolean verifyState = true;
JapCache cache = new JapLocalCache();
cache.set(Oauth2Const.STATE_CACHE_KEY.concat(clientId), "11");
JapCacheContextHolder.enable(cache);
JapAuthentication.setContext(new JapContext().setCache(cache));
Assert.assertThrows(JapOauth2Exception.class, () -> Oauth2Util.checkState(state, clientId, verifyState));
}

View File

@ -16,8 +16,9 @@
package com.fujieid.jap.oauth2.pkce;
import com.fujieid.jap.core.cache.JapCache;
import com.fujieid.jap.core.cache.JapCacheContextHolder;
import com.fujieid.jap.core.cache.JapLocalCache;
import com.fujieid.jap.core.context.JapAuthentication;
import com.fujieid.jap.core.context.JapContext;
import com.fujieid.jap.oauth2.OAuthConfig;
import org.junit.Assert;
import org.junit.Test;
@ -77,8 +78,8 @@ public class PkceHelperTest {
@Test
public void getCacheCodeVerifier() {
JapCache japCache = new JapLocalCache();
JapCacheContextHolder.enable(japCache);
JapCacheContextHolder.getCache().set("clientId", "111", 111111);
JapAuthentication.setContext(new JapContext().setCache(japCache));
JapAuthentication.getContext().getCache().set("clientId", "111", 111111);
String res = PkceHelper.getCacheCodeVerifier("clientId");
Assert.assertNotNull(res);
Assert.assertEquals("111", res);

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.fujieid</groupId>
<artifactId>jap</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.fujieid</groupId>
<artifactId>jap</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.fujieid</groupId>
<artifactId>jap</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.fujieid</groupId>
<artifactId>jap</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -81,8 +81,6 @@ public class JapSsoHelper {
ssoConfig.setCookieDomain(japSsoConfig.getCookieDomain());
ssoConfig.setCookieName(japSsoConfig.getCookieName());
ssoConfig.setParamReturnUrl(japSsoConfig.getParamReturnUrl());
ssoConfig.setLoginUrl(japSsoConfig.getLoginUrl());
ssoConfig.setLogoutUrl(japSsoConfig.getLogoutUrl());
ssoConfig.setCookieMaxAge(japSsoConfig.getCookieMaxAge());
KiSsoHelper.setSsoConfig(ssoConfig);
return ssoConfig;

View File

@ -41,18 +41,6 @@ public class JapSsoConfig {
*/
private String paramReturnUrl = "returnUrl";
/**
* Login Url. Default is `/login`
*/
@Deprecated
private String loginUrl = "/login";
/**
* Logout Url. Default is `/logout`
*/
@Deprecated
private String logoutUrl = "/logout";
public String getCookieName() {
return cookieName;
}
@ -80,15 +68,6 @@ public class JapSsoConfig {
return this;
}
public String getLoginUrl() {
return loginUrl;
}
public JapSsoConfig setLoginUrl(String loginUrl) {
this.loginUrl = loginUrl;
return this;
}
public int getCookieMaxAge() {
return cookieMaxAge;
}
@ -97,13 +76,4 @@ public class JapSsoConfig {
this.cookieMaxAge = cookieMaxAge;
return this;
}
public String getLogoutUrl() {
return logoutUrl;
}
public JapSsoConfig setLogoutUrl(String logoutUrl) {
this.logoutUrl = logoutUrl;
return this;
}
}

2
jap.sh
View File

@ -25,7 +25,7 @@ case "$1" in
docs/bin/deploy.sh
;;
'c')
docs/bin/codecov.sh
docs/bin/codecov.sh $2
;;
*)
help

View File

@ -5,7 +5,7 @@
<groupId>com.fujieid</groupId>
<artifactId>jap</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
<packaging>pom</packaging>
<name>jap</name>