RefreshToken

This commit is contained in:
MaxKey 2022-04-30 11:15:16 +08:00
parent 69aa4f27ad
commit eb748ac827
61 changed files with 542 additions and 342 deletions

View File

@ -41,7 +41,7 @@ public class KaptchaAutoConfiguration implements InitializingBean {
* @return Producer * @return Producer
* @throws IOException kaptcha.properties is null * @throws IOException kaptcha.properties is null
*/ */
@Bean (name = "captchaProducer") @Bean
public Producer captchaProducer() throws IOException { public Producer captchaProducer() throws IOException {
Resource resource = new ClassPathResource(kaptchaPropertySource); Resource resource = new ClassPathResource(kaptchaPropertySource);
_logger.debug("Kaptcha config file " + resource.getURL()); _logger.debug("Kaptcha config file " + resource.getURL());

View File

@ -17,7 +17,9 @@
package org.maxkey.web.contorller; package org.maxkey.web.contorller;
public class ImageCaptcha { public class ImageCaptcha {
String state; String state;
String image; String image;
public ImageCaptcha(String state, String image) { public ImageCaptcha(String state, String image) {

View File

@ -25,7 +25,7 @@ import java.util.Base64;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.maxkey.authn.jwt.AuthJwtService; import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.entity.Message; import org.maxkey.entity.Message;
import org.maxkey.persistence.MomentaryService; import org.maxkey.persistence.MomentaryService;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -54,7 +54,7 @@ public class ImageCaptchaEndpoint {
protected MomentaryService momentaryService; protected MomentaryService momentaryService;
@Autowired @Autowired
AuthJwtService authJwtService; AuthTokenService authTokenService;
/** /**
* captcha image Producer. * captcha image Producer.
@ -83,12 +83,12 @@ public class ImageCaptchaEndpoint {
String kaptchaKey = ""; String kaptchaKey = "";
if(StringUtils.isNotBlank(state) if(StringUtils.isNotBlank(state)
&& !state.equalsIgnoreCase("state") && !state.equalsIgnoreCase("state")
&& authJwtService.validateJwtToken(state)) { && authTokenService.validateJwtToken(state)) {
//just validate state Token //just validate state Token
}else { }else {
state = authJwtService.genJwt(); state = authTokenService.genRandomJwt();
} }
kaptchaKey = authJwtService.resolveJWTID(state); kaptchaKey = authTokenService.resolveJWTID(state);
_logger.trace("kaptchaKey {} , Captcha Text is {}" ,kaptchaKey, kaptchaValue); _logger.trace("kaptchaKey {} , Captcha Text is {}" ,kaptchaKey, kaptchaValue);
momentaryService.put("", kaptchaKey, kaptchaValue); momentaryService.put("", kaptchaKey, kaptchaValue);

View File

@ -19,7 +19,7 @@ package org.maxkey.authn;
import java.util.ArrayList; import java.util.ArrayList;
import org.maxkey.authn.jwt.AuthJwtService; import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.authn.realm.AbstractAuthenticationRealm; import org.maxkey.authn.realm.AbstractAuthenticationRealm;
import org.maxkey.authn.session.Session; import org.maxkey.authn.session.Session;
import org.maxkey.authn.session.SessionManager; import org.maxkey.authn.session.SessionManager;
@ -69,7 +69,7 @@ public abstract class AbstractAuthenticationProvider {
protected SessionManager sessionManager; protected SessionManager sessionManager;
protected AuthJwtService authJwtService; protected AuthTokenService authTokenService;
public static ArrayList<GrantedAuthority> grantedAdministratorsAuthoritys = new ArrayList<GrantedAuthority>(); public static ArrayList<GrantedAuthority> grantedAdministratorsAuthoritys = new ArrayList<GrantedAuthority>();

View File

@ -31,6 +31,7 @@ public class AuthJwt implements Serializable {
private String ticket; private String ticket;
private String token; private String token;
private String refreshToken;
private String type = "Bearer"; private String type = "Bearer";
private String remeberMe; private String remeberMe;
private String id; private String id;
@ -57,10 +58,11 @@ public class AuthJwt implements Serializable {
this.authorities = authorities; this.authorities = authorities;
} }
public AuthJwt(String token, Authentication authentication) { public AuthJwt(String token,String refreshToken, Authentication authentication) {
SignPrincipal principal = ((SignPrincipal)authentication.getPrincipal()); SignPrincipal principal = ((SignPrincipal)authentication.getPrincipal());
this.token = token; this.token = token;
this.refreshToken = refreshToken;
this.ticket = principal.getSession().getId(); this.ticket = principal.getSession().getId();
this.id = principal.getUserInfo().getId(); this.id = principal.getUserInfo().getId();
@ -166,6 +168,14 @@ public class AuthJwt implements Serializable {
this.remeberMe = remeberMe; this.remeberMe = remeberMe;
} }
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
@Override @Override
public String toString() { public String toString() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();

View File

@ -1,99 +1,42 @@
/*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.authn.jwt; package org.maxkey.authn.jwt;
import java.text.ParseException; import java.text.ParseException;
import java.util.Date; import java.util.Date;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.maxkey.authn.SignPrincipal; import org.maxkey.authn.SignPrincipal;
import org.maxkey.configuration.AuthJwkConfig;
import org.maxkey.crypto.jwt.HMAC512Service; import org.maxkey.crypto.jwt.HMAC512Service;
import org.maxkey.entity.UserInfo; import org.maxkey.entity.UserInfo;
import org.maxkey.persistence.MomentaryService;
import org.maxkey.web.WebContext; import org.maxkey.web.WebContext;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader; import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT; import com.nimbusds.jwt.SignedJWT;
public class AuthJwtService { public class AuthJwtService {
private static final Logger _logger = private static final Logger _logger = LoggerFactory.getLogger(AuthJwtService.class);
LoggerFactory.getLogger(AuthJwtService.class);
HMAC512Service hmac512Service; HMAC512Service hmac512Service;
AuthJwkConfig authJwkConfig;
CongressService congressService;
MomentaryService momentaryService;
public AuthJwtService(AuthJwkConfig authJwkConfig) throws JOSEException {
this.authJwkConfig = authJwkConfig;
this.hmac512Service = new HMAC512Service(authJwkConfig.getSecret());
}
public AuthJwtService(AuthJwkConfig authJwkConfig,CongressService congressService,MomentaryService momentaryService) throws JOSEException {
this.authJwkConfig = authJwkConfig;
this.congressService = congressService;
this.momentaryService = momentaryService;
this.hmac512Service = new HMAC512Service(authJwkConfig.getSecret());
}
/**
* create AuthJwt use Authentication JWT
* @param authentication
* @return AuthJwt
*/
public AuthJwt genAuthJwt(Authentication authentication) {
if(authentication != null) {
return new AuthJwt(genJwt(authentication), authentication);
}
return null;
}
/** /**
* JWT with Authentication * JWT with Authentication
* @param authentication * @param authentication
* @return * @return
*/ */
public String genJwt(Authentication authentication) { public String genJwt(Authentication authentication,String issuer,int expires) {
SignPrincipal principal = ((SignPrincipal)authentication.getPrincipal()); SignPrincipal principal = ((SignPrincipal)authentication.getPrincipal());
UserInfo userInfo = principal.getUserInfo(); UserInfo userInfo = principal.getUserInfo();
DateTime currentDateTime = DateTime.now(); DateTime currentDateTime = DateTime.now();
Date expirationTime = currentDateTime.plusSeconds(authJwkConfig.getExpires()).toDate();
_logger.debug("expiration Time : {}" , expirationTime);
String subject = principal.getUsername(); String subject = principal.getUsername();
_logger.trace("jwt subject : {}" , subject); Date expirationTime = currentDateTime.plusSeconds(expires).toDate();
_logger.debug("jwt subject : {} , expiration Time : {}" , subject,expirationTime);
JWTClaimsSet jwtClaims =new JWTClaimsSet.Builder() JWTClaimsSet jwtClaims =new JWTClaimsSet.Builder()
.issuer(authJwkConfig.getIssuer()) .issuer(issuer)
.subject(subject) .subject(subject)
.jwtID(principal.getSession().getId()) .jwtID(principal.getSession().getId())
.issueTime(currentDateTime.toDate()) .issueTime(currentDateTime.toDate())
@ -111,14 +54,13 @@ public class AuthJwtService {
* @param subject subject * @param subject subject
* @return * @return
*/ */
public String genJwt(String subject) { public String genJwt(String subject,String issuer,int expires) {
DateTime currentDateTime = DateTime.now(); DateTime currentDateTime = DateTime.now();
Date expirationTime = currentDateTime.plusSeconds(authJwkConfig.getExpires()).toDate(); Date expirationTime = currentDateTime.plusSeconds(expires).toDate();
_logger.debug("expiration Time : {}" , expirationTime); _logger.trace("jwt subject : {} , expiration Time : {}" , subject,expirationTime);
_logger.trace("jwt subject : {}" , subject);
JWTClaimsSet jwtClaims =new JWTClaimsSet.Builder() JWTClaimsSet jwtClaims =new JWTClaimsSet.Builder()
.issuer(authJwkConfig.getIssuer()) .issuer(issuer)
.subject(subject) .subject(subject)
.jwtID(WebContext.genId()) .jwtID(WebContext.genId())
.issueTime(currentDateTime.toDate()) .issueTime(currentDateTime.toDate())
@ -132,10 +74,9 @@ public class AuthJwtService {
* Random JWT * Random JWT
* @return * @return
*/ */
public String genJwt() { public String genRandomJwt(int expires) {
DateTime currentDateTime = DateTime.now(); Date expirationTime = DateTime.now().plusSeconds(expires).toDate();
Date expirationTime = currentDateTime.plusSeconds(authJwkConfig.getExpires()).toDate(); _logger.trace("expiration Time : {}" , expirationTime);
_logger.debug("expiration Time : {}" , expirationTime);
JWTClaimsSet jwtClaims =new JWTClaimsSet.Builder() JWTClaimsSet jwtClaims =new JWTClaimsSet.Builder()
.jwtID(WebContext.genId()) .jwtID(WebContext.genId())
@ -153,8 +94,25 @@ public class AuthJwtService {
return hmac512Service.sign(jwtToken.getPayload()); return hmac512Service.sign(jwtToken.getPayload());
} }
/**
* Verify with HMAC512 and check ExpirationTime
*
* @param authToken
* @return true or false
*/
public boolean validateJwtToken(String authToken) { public boolean validateJwtToken(String authToken) {
return hmac512Service.verify(authToken); try {
JWTClaimsSet claims = resolve(authToken);
boolean isExpiration = claims.getExpirationTime().after(DateTime.now().toDate());
boolean isVerify = hmac512Service.verify(authToken);
_logger.debug("JWT Verify {} , now {} , ExpirationTime {} , isExpiration : {}" ,
isVerify,DateTime.now().toDate(),claims.getExpirationTime(),isExpiration);
return isVerify && isExpiration;
} catch (ParseException e) {
_logger.error("authToken {}",authToken);
_logger.error("ParseException ",e);
}
return false;
} }
public JWTClaimsSet resolve(String authToken) throws ParseException { public JWTClaimsSet resolve(String authToken) throws ParseException {
@ -167,38 +125,4 @@ public class AuthJwtService {
JWTClaimsSet claims = resolve(authToken); JWTClaimsSet claims = resolve(authToken);
return claims.getJWTID(); return claims.getJWTID();
} }
public String createCongress(Authentication authentication) {
String congress = WebContext.genId();
congressService.store(
congress,
new AuthJwt(
genJwt(authentication),
authentication)
);
return congress;
}
public AuthJwt consumeCongress(String congress) {
AuthJwt authJwt = congressService.consume(congress);
return authJwt;
}
public boolean validateCaptcha(String state,String captcha) {
try {
String jwtId = resolveJWTID(state);
if(StringUtils.isNotBlank(jwtId) &&StringUtils.isNotBlank(captcha)) {
Object momentaryCaptcha = momentaryService.get("", jwtId);
_logger.debug("captcha : {}, momentary Captcha : {}" ,captcha, momentaryCaptcha);
if (!StringUtils.isBlank(captcha) && captcha.equals(momentaryCaptcha.toString())) {
momentaryService.remove("", jwtId);
return true;
}
}
} catch (ParseException e) {
_logger.debug("Exception ",e);
}
return false;
}
} }

View File

@ -0,0 +1,51 @@
/*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.authn.jwt;
import org.maxkey.configuration.AuthJwkConfig;
import org.maxkey.crypto.jwt.HMAC512Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import com.nimbusds.jose.JOSEException;
public class AuthRefreshTokenService extends AuthJwtService{
private static final Logger _logger = LoggerFactory.getLogger(AuthRefreshTokenService.class);
AuthJwkConfig authJwkConfig;
public AuthRefreshTokenService(AuthJwkConfig authJwkConfig) throws JOSEException {
this.authJwkConfig = authJwkConfig;
this.hmac512Service = new HMAC512Service(authJwkConfig.getRefreshSecret());
}
/**
* JWT Refresh Token with Authentication
* @param authentication
* @return
*/
public String genRefreshToken(Authentication authentication) {
_logger.trace("gen Refresh Token");
return genJwt(
authentication,
authJwkConfig.getIssuer(),
authJwkConfig.getRefreshExpires());
}
}

View File

@ -0,0 +1,132 @@
/*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.authn.jwt;
import java.text.ParseException;
import org.apache.commons.lang3.StringUtils;
import org.maxkey.configuration.AuthJwkConfig;
import org.maxkey.crypto.jwt.HMAC512Service;
import org.maxkey.persistence.MomentaryService;
import org.maxkey.web.WebContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import com.nimbusds.jose.JOSEException;
public class AuthTokenService extends AuthJwtService{
private static final Logger _logger = LoggerFactory.getLogger(AuthTokenService.class);
AuthJwkConfig authJwkConfig;
CongressService congressService;
MomentaryService momentaryService;
AuthRefreshTokenService refreshTokenService;
public AuthTokenService(
AuthJwkConfig authJwkConfig,
CongressService congressService,
MomentaryService momentaryService,
AuthRefreshTokenService refreshTokenService) throws JOSEException {
this.authJwkConfig = authJwkConfig;
this.congressService = congressService;
this.momentaryService = momentaryService;
this.refreshTokenService = refreshTokenService;
this.hmac512Service = new HMAC512Service(authJwkConfig.getSecret());
}
/**
* create AuthJwt use Authentication JWT
* @param authentication
* @return AuthJwt
*/
public AuthJwt genAuthJwt(Authentication authentication) {
if(authentication != null) {
String refreshToken = refreshTokenService.genRefreshToken(authentication);
return new AuthJwt(genJwt(authentication),refreshToken, authentication);
}
return null;
}
public String genJwt(Authentication authentication) {
return genJwt( authentication,authJwkConfig.getIssuer(),authJwkConfig.getExpires());
}
/**
* JWT with subject
* @param subject subject
* @return
*/
public String genJwt(String subject) {
return genJwt(subject,authJwkConfig.getIssuer(),authJwkConfig.getExpires());
}
/**
* Random JWT
* @return
*/
public String genRandomJwt() {
return genRandomJwt(authJwkConfig.getExpires());
}
public String createCongress(Authentication authentication) {
String congress = WebContext.genId();
String refreshToken = refreshTokenService.genRefreshToken(authentication);
congressService.store(
congress,
new AuthJwt(
genJwt(authentication),
refreshToken,
authentication)
);
return congress;
}
public AuthJwt consumeCongress(String congress) {
AuthJwt authJwt = congressService.consume(congress);
return authJwt;
}
public boolean validateCaptcha(String state,String captcha) {
try {
String jwtId = resolveJWTID(state);
if(StringUtils.isNotBlank(jwtId) &&StringUtils.isNotBlank(captcha)) {
Object momentaryCaptcha = momentaryService.get("", jwtId);
_logger.debug("captcha : {}, momentary Captcha : {}" ,captcha, momentaryCaptcha);
if (!StringUtils.isBlank(captcha) && captcha.equals(momentaryCaptcha.toString())) {
momentaryService.remove("", jwtId);
return true;
}
}
} catch (ParseException e) {
_logger.debug("Exception ",e);
}
return false;
}
}

View File

@ -19,7 +19,7 @@ package org.maxkey.authn.provider;
import org.maxkey.authn.AbstractAuthenticationProvider; import org.maxkey.authn.AbstractAuthenticationProvider;
import org.maxkey.authn.LoginCredential; import org.maxkey.authn.LoginCredential;
import org.maxkey.authn.jwt.AuthJwtService; import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.authn.realm.AbstractAuthenticationRealm; import org.maxkey.authn.realm.AbstractAuthenticationRealm;
import org.maxkey.authn.session.SessionManager; import org.maxkey.authn.session.SessionManager;
import org.maxkey.configuration.ApplicationConfig; import org.maxkey.configuration.ApplicationConfig;
@ -58,11 +58,11 @@ public class MfaAuthenticationProvider extends AbstractAuthenticationProvider {
AbstractAuthenticationRealm authenticationRealm, AbstractAuthenticationRealm authenticationRealm,
ApplicationConfig applicationConfig, ApplicationConfig applicationConfig,
SessionManager sessionManager, SessionManager sessionManager,
AuthJwtService authJwtService) { AuthTokenService authTokenService) {
this.authenticationRealm = authenticationRealm; this.authenticationRealm = authenticationRealm;
this.applicationConfig = applicationConfig; this.applicationConfig = applicationConfig;
this.sessionManager = sessionManager; this.sessionManager = sessionManager;
this.authJwtService = authJwtService; this.authTokenService = authTokenService;
} }
@Override @Override

View File

@ -20,7 +20,7 @@ package org.maxkey.authn.provider;
import java.text.ParseException; import java.text.ParseException;
import org.maxkey.authn.AbstractAuthenticationProvider; import org.maxkey.authn.AbstractAuthenticationProvider;
import org.maxkey.authn.LoginCredential; import org.maxkey.authn.LoginCredential;
import org.maxkey.authn.jwt.AuthJwtService; import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.authn.realm.AbstractAuthenticationRealm; import org.maxkey.authn.realm.AbstractAuthenticationRealm;
import org.maxkey.authn.session.SessionManager; import org.maxkey.authn.session.SessionManager;
import org.maxkey.configuration.ApplicationConfig; import org.maxkey.configuration.ApplicationConfig;
@ -58,11 +58,11 @@ public class NormalAuthenticationProvider extends AbstractAuthenticationProvider
AbstractAuthenticationRealm authenticationRealm, AbstractAuthenticationRealm authenticationRealm,
ApplicationConfig applicationConfig, ApplicationConfig applicationConfig,
SessionManager sessionManager, SessionManager sessionManager,
AuthJwtService authJwtService) { AuthTokenService authTokenService) {
this.authenticationRealm = authenticationRealm; this.authenticationRealm = authenticationRealm;
this.applicationConfig = applicationConfig; this.applicationConfig = applicationConfig;
this.sessionManager = sessionManager; this.sessionManager = sessionManager;
this.authJwtService = authJwtService; this.authTokenService = authTokenService;
} }
@Override @Override
@ -134,7 +134,7 @@ public class NormalAuthenticationProvider extends AbstractAuthenticationProvider
*/ */
protected void captchaValid(String state ,String captcha) throws ParseException { protected void captchaValid(String state ,String captcha) throws ParseException {
// for basic // for basic
if(!authJwtService.validateCaptcha(state,captcha)) { if(!authTokenService.validateCaptcha(state,captcha)) {
throw new BadCredentialsException(WebContext.getI18nValue("login.error.captcha")); throw new BadCredentialsException(WebContext.getI18nValue("login.error.captcha"));
} }
} }

View File

@ -110,13 +110,13 @@ public class AbstractSessionManager implements SessionManager{
} }
@Override @Override
public void refresh(String sessionId, LocalTime refreshTime) { public Session refresh(String sessionId, LocalTime refreshTime) {
return null;
} }
@Override @Override
public void refresh(String sessionId) { public Session refresh(String sessionId) {
return null;
} }
@Override @Override

View File

@ -78,14 +78,15 @@ public class InMemorySessionManager extends AbstractSessionManager{
} }
@Override @Override
public void refresh(String sessionId,LocalTime refreshTime) { public Session refresh(String sessionId,LocalTime refreshTime) {
Session session = get(sessionId); Session session = get(sessionId);
session.setLastAccessTime(refreshTime); session.setLastAccessTime(refreshTime);
create(sessionId , session); create(sessionId , session);
return session;
} }
@Override @Override
public void refresh(String sessionId) { public Session refresh(String sessionId) {
Session session = get(sessionId); Session session = get(sessionId);
LocalTime currentTime = LocalTime.now(); LocalTime currentTime = LocalTime.now();
@ -95,8 +96,9 @@ public class InMemorySessionManager extends AbstractSessionManager{
if(duration.getSeconds() > Session.MAX_EXPIRY_DURATION) { if(duration.getSeconds() > Session.MAX_EXPIRY_DURATION) {
session.setLastAccessTime(currentTime); session.setLastAccessTime(currentTime);
refresh(sessionId,currentTime); return refresh(sessionId,currentTime);
} }
return session;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -33,6 +33,11 @@ public class RedisSessionManager extends AbstractSessionManager {
RedisConnectionFactory connectionFactory; RedisConnectionFactory connectionFactory;
public static String PREFIX="REDIS_SESSION_"; public static String PREFIX="REDIS_SESSION_";
public String getKey(String sessionId) {
return PREFIX + sessionId;
}
/** /**
* @param connectionFactory * @param connectionFactory
*/ */
@ -59,15 +64,15 @@ public class RedisSessionManager extends AbstractSessionManager {
@Override @Override
public void create(String sessionId, Session session) { public void create(String sessionId, Session session) {
RedisConnection conn = connectionFactory.getConnection(); RedisConnection conn = connectionFactory.getConnection();
conn.setexObject(PREFIX + sessionId, validitySeconds, session); conn.setexObject( getKey(sessionId), validitySeconds, session);
conn.close(); conn.close();
} }
@Override @Override
public Session remove(String sessionId) { public Session remove(String sessionId) {
RedisConnection conn=connectionFactory.getConnection(); RedisConnection conn=connectionFactory.getConnection();
Session ticket = conn.getObject(PREFIX+sessionId); Session ticket = conn.getObject(getKey(sessionId));
conn.delete(PREFIX+sessionId); conn.delete(getKey(sessionId));
conn.close(); conn.close();
return ticket; return ticket;
} }
@ -75,7 +80,7 @@ public class RedisSessionManager extends AbstractSessionManager {
@Override @Override
public Session get(String sessionId) { public Session get(String sessionId) {
RedisConnection conn=connectionFactory.getConnection(); RedisConnection conn=connectionFactory.getConnection();
Session session = conn.getObject(PREFIX+sessionId); Session session = conn.getObject(getKey(sessionId));
conn.close(); conn.close();
return session; return session;
} }
@ -90,14 +95,15 @@ public class RedisSessionManager extends AbstractSessionManager {
} }
@Override @Override
public void refresh(String sessionId,LocalTime refreshTime) { public Session refresh(String sessionId,LocalTime refreshTime) {
Session session = get(sessionId); Session session = get(sessionId);
session.setLastAccessTime(refreshTime); session.setLastAccessTime(refreshTime);
create(sessionId , session); create(sessionId , session);
return session;
} }
@Override @Override
public void refresh(String sessionId) { public Session refresh(String sessionId) {
Session session = get(sessionId); Session session = get(sessionId);
LocalTime currentTime = LocalTime.now(); LocalTime currentTime = LocalTime.now();
@ -107,8 +113,9 @@ public class RedisSessionManager extends AbstractSessionManager {
if(duration.getSeconds() > Session.MAX_EXPIRY_DURATION) { if(duration.getSeconds() > Session.MAX_EXPIRY_DURATION) {
session.setLastAccessTime(currentTime); session.setLastAccessTime(currentTime);
refresh(sessionId,currentTime); return refresh(sessionId,currentTime);
} }
return session;
} }

View File

@ -30,7 +30,7 @@ public class Session implements Serializable{
public static final String SESSION_PREFIX = "OT"; public static final String SESSION_PREFIX = "OT";
public static final int MAX_EXPIRY_DURATION = 60 * 10; //default 10 minutes. public static final int MAX_EXPIRY_DURATION = 60 * 5; //default 5 minutes.
public String id; public String id;

View File

@ -30,9 +30,9 @@ public interface SessionManager {
public Session get(String sessionId); public Session get(String sessionId);
public void refresh(String sessionId ,LocalTime refreshTime); public Session refresh(String sessionId ,LocalTime refreshTime);
public void refresh(String sessionId); public Session refresh(String sessionId);
public void setValiditySeconds(int validitySeconds); public void setValiditySeconds(int validitySeconds);

View File

@ -24,7 +24,7 @@ import javax.servlet.http.HttpServletResponse;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.maxkey.authn.SignPrincipal; import org.maxkey.authn.SignPrincipal;
import org.maxkey.authn.jwt.AuthJwtService; import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.configuration.ApplicationConfig; import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.crypto.jwt.HMAC512Service; import org.maxkey.crypto.jwt.HMAC512Service;
import org.maxkey.entity.UserInfo; import org.maxkey.entity.UserInfo;
@ -36,14 +36,14 @@ import org.springframework.security.core.Authentication;
import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.JWTClaimsSet;
public abstract class AbstractRemeberMeService { public abstract class AbstractRemeberMeManager {
private static final Logger _logger = LoggerFactory.getLogger(AbstractRemeberMeService.class); private static final Logger _logger = LoggerFactory.getLogger(AbstractRemeberMeManager.class);
protected Integer validity = 7; protected Integer validity = 7;
protected ApplicationConfig applicationConfig; protected ApplicationConfig applicationConfig;
AuthJwtService authJwtService; AuthTokenService authTokenService;
// follow function is for persist // follow function is for persist
public abstract void save(RemeberMe remeberMe); public abstract void save(RemeberMe remeberMe);
@ -90,7 +90,7 @@ public abstract class AbstractRemeberMeService {
} }
public RemeberMe resolve(String rememberMeJwt) throws ParseException { public RemeberMe resolve(String rememberMeJwt) throws ParseException {
JWTClaimsSet claims = authJwtService.resolve(rememberMeJwt); JWTClaimsSet claims = authTokenService.resolve(rememberMeJwt);
RemeberMe remeberMe = new RemeberMe(); RemeberMe remeberMe = new RemeberMe();
remeberMe.setId(claims.getJWTID()); remeberMe.setId(claims.getJWTID());
remeberMe.setUsername(claims.getSubject()); remeberMe.setUsername(claims.getSubject());
@ -109,7 +109,7 @@ public abstract class AbstractRemeberMeService {
.claim("kid", HMAC512Service.MXK_AUTH_JWK) .claim("kid", HMAC512Service.MXK_AUTH_JWK)
.build(); .build();
return authJwtService.signedJWT(remeberMeJwtClaims); return authTokenService.signedJWT(remeberMeJwtClaims);
} }
public Integer getValidity() { public Integer getValidity() {

View File

@ -24,7 +24,7 @@ import org.maxkey.constants.ConstsTimeInterval;
import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;
public class InMemoryRemeberMeService extends AbstractRemeberMeService { public class InMemoryRemeberMeManager extends AbstractRemeberMeManager {
protected static final Cache<String, RemeberMe> remeberMeStore = protected static final Cache<String, RemeberMe> remeberMeStore =
Caffeine.newBuilder() Caffeine.newBuilder()

View File

@ -22,15 +22,15 @@ import java.sql.SQLException;
import java.sql.Types; import java.sql.Types;
import java.util.List; import java.util.List;
import org.maxkey.authn.jwt.AuthJwtService; import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.configuration.ApplicationConfig; import org.maxkey.configuration.ApplicationConfig;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.RowMapper;
public class JdbcRemeberMeService extends AbstractRemeberMeService { public class JdbcRemeberMeManager extends AbstractRemeberMeManager {
private static final Logger _logger = LoggerFactory.getLogger(JdbcRemeberMeService.class); private static final Logger _logger = LoggerFactory.getLogger(JdbcRemeberMeManager.class);
private static final String DEFAULT_DEFAULT_INSERT_STATEMENT = private static final String DEFAULT_DEFAULT_INSERT_STATEMENT =
"insert into mxk_remember_me(id, userid,username,lastlogintime,expirationtime)values( ? , ? , ? , ? , ?)"; "insert into mxk_remember_me(id, userid,username,lastlogintime,expirationtime)values( ? , ? , ? , ? , ?)";
@ -47,14 +47,14 @@ public class JdbcRemeberMeService extends AbstractRemeberMeService {
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
public JdbcRemeberMeService( public JdbcRemeberMeManager(
JdbcTemplate jdbcTemplate, JdbcTemplate jdbcTemplate,
ApplicationConfig applicationConfig, ApplicationConfig applicationConfig,
AuthJwtService authJwtService, AuthTokenService authTokenService,
int validity) { int validity) {
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
this.applicationConfig = applicationConfig; this.applicationConfig = applicationConfig;
this.authJwtService = authJwtService; this.authTokenService = authTokenService;
if(validity != 0) { if(validity != 0) {
this.validity = validity; this.validity = validity;
} }

View File

@ -23,18 +23,18 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
public class RemeberMeServiceFactory { public class RemeberMeManagerFactory {
private static final Logger _logger = private static final Logger _logger =
LoggerFactory.getLogger(RemeberMeServiceFactory.class); LoggerFactory.getLogger(RemeberMeManagerFactory.class);
public AbstractRemeberMeService getService( public AbstractRemeberMeManager getService(
int persistence, int persistence,
JdbcTemplate jdbcTemplate, JdbcTemplate jdbcTemplate,
RedisConnectionFactory redisConnFactory){ RedisConnectionFactory redisConnFactory){
AbstractRemeberMeService remeberMeService = null; AbstractRemeberMeManager remeberMeService = null;
if (persistence == ConstsPersistence.INMEMORY) { if (persistence == ConstsPersistence.INMEMORY) {
remeberMeService = new InMemoryRemeberMeService(); remeberMeService = new InMemoryRemeberMeManager();
_logger.debug("InMemoryRemeberMeService"); _logger.debug("InMemoryRemeberMeService");
} else if (persistence == ConstsPersistence.JDBC) { } else if (persistence == ConstsPersistence.JDBC) {
//remeberMeService = new JdbcRemeberMeService(jdbcTemplate); //remeberMeService = new JdbcRemeberMeService(jdbcTemplate);

View File

@ -23,7 +23,7 @@ import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.maxkey.authn.SignPrincipal; import org.maxkey.authn.SignPrincipal;
import org.maxkey.authn.jwt.AuthJwtService; import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.authn.session.Session; import org.maxkey.authn.session.Session;
import org.maxkey.authn.session.SessionManager; import org.maxkey.authn.session.SessionManager;
import org.maxkey.entity.UserInfo; import org.maxkey.entity.UserInfo;
@ -41,43 +41,46 @@ public class AuthorizationUtils {
public static void authenticateWithCookie( public static void authenticateWithCookie(
HttpServletRequest request, HttpServletRequest request,
AuthJwtService authJwtService, AuthTokenService authTokenService,
SessionManager sessionManager SessionManager sessionManager
) throws ParseException{ ) throws ParseException{
if(getAuthentication() == null) { Cookie authCookie = WebContext.getCookie(request, Authorization_Cookie);
Cookie authCookie = WebContext.getCookie(request, Authorization_Cookie); if(authCookie != null ) {
if(authCookie != null ) { String authorization = authCookie.getValue();
String authorization = authCookie.getValue(); doJwtAuthenticate(authorization,authTokenService,sessionManager);
doJwtAuthenticate(authorization,authJwtService,sessionManager); _logger.debug("congress automatic authenticated .");
_logger.debug("congress automatic authenticated ."); }
}
}
} }
public static void authenticate( public static void authenticate(
HttpServletRequest request, HttpServletRequest request,
AuthJwtService authJwtService, AuthTokenService authTokenService,
SessionManager sessionManager SessionManager sessionManager
) throws ParseException{ ) throws ParseException{
if(getAuthentication() == null) { String authorization = AuthorizationHeaderUtils.resolveBearer(request);
String authorization = AuthorizationHeaderUtils.resolveBearer(request); if(authorization != null ) {
if(authorization != null ) { doJwtAuthenticate(authorization,authTokenService,sessionManager);
doJwtAuthenticate(authorization,authJwtService,sessionManager); _logger.debug("Authorization automatic authenticated .");
_logger.debug("Authorization automatic authenticated ."); }
}
}
} }
public static void doJwtAuthenticate( public static void doJwtAuthenticate(
String authorization, String authorization,
AuthJwtService authJwtService, AuthTokenService authTokenService,
SessionManager sessionManager) throws ParseException { SessionManager sessionManager) throws ParseException {
if(authJwtService.validateJwtToken(authorization)) { if(authTokenService.validateJwtToken(authorization)) {
String sessionId = authJwtService.resolveJWTID(authorization); if(isNotAuthenticated()) {
Session session = sessionManager.get(sessionId); String sessionId = authTokenService.resolveJWTID(authorization);
if(session != null) { Session session = sessionManager.get(sessionId);
setAuthentication(session.getAuthentication()); if(session != null) {
setAuthentication(session.getAuthentication());
}else {
setAuthentication(null);
}
} }
}else {
setAuthentication(null);
} }
} }

View File

@ -0,0 +1,57 @@
package org.maxkey.authn.web;
import org.maxkey.authn.jwt.AuthJwt;
import org.maxkey.authn.jwt.AuthRefreshTokenService;
import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.authn.session.Session;
import org.maxkey.authn.session.SessionManager;
import org.maxkey.entity.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping(value = "/auth")
public class LoginRefreshPoint {
private static final Logger _logger = LoggerFactory.getLogger(LoginRefreshPoint.class);
@Autowired
AuthTokenService authTokenService;
@Autowired
AuthRefreshTokenService refreshTokenService;
@Autowired
SessionManager sessionManager;
@RequestMapping(value={"/token/refresh"}, produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<?> refresh(
@RequestHeader(name = "refresh_token", required = true) String refreshToken) {
_logger.trace("refresh token {} " , refreshToken);
try {
if(refreshTokenService.validateJwtToken(refreshToken)) {
String sessionId = refreshTokenService.resolveJWTID(refreshToken);
_logger.trace("Try to refresh sessionId [{}]" , sessionId);
Session session = sessionManager.refresh(sessionId);
if(session != null) {
AuthJwt authJwt = authTokenService.genAuthJwt(session.getAuthentication());
_logger.trace("Grant new token {}" , authJwt);
return new Message<AuthJwt>(authJwt).buildResponse();
}else {
_logger.debug("Session is timeout , sessionId [{}]" , sessionId);
}
}else {
_logger.trace("refresh token is not validate .");
}
}catch(Exception e) {
_logger.error("Refresh Exception !",e);
}
return new ResponseEntity<>("Refresh Token Fail !", HttpStatus.UNAUTHORIZED);
}
}

View File

@ -35,10 +35,11 @@ import com.fasterxml.jackson.databind.DatabindException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
@Controller @Controller
@RequestMapping(value = "/auth")
public class UnauthorizedEntryPoint { public class UnauthorizedEntryPoint {
private static final Logger _logger = LoggerFactory.getLogger(UnauthorizedEntryPoint.class); private static final Logger _logger = LoggerFactory.getLogger(UnauthorizedEntryPoint.class);
@RequestMapping(value={"/auth/entrypoint"}) @RequestMapping(value={"/entrypoint"})
public void entryPoint( public void entryPoint(
HttpServletRequest request, HttpServletResponse response) HttpServletRequest request, HttpServletResponse response)
throws StreamWriteException, DatabindException, IOException { throws StreamWriteException, DatabindException, IOException {

View File

@ -22,7 +22,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.maxkey.authn.SignPrincipal; import org.maxkey.authn.SignPrincipal;
import org.maxkey.authn.jwt.AuthJwtService; import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.authn.session.SessionManager; import org.maxkey.authn.session.SessionManager;
import org.maxkey.authn.web.AuthorizationUtils; import org.maxkey.authn.web.AuthorizationUtils;
import org.maxkey.configuration.ApplicationConfig; import org.maxkey.configuration.ApplicationConfig;
@ -47,7 +47,7 @@ public class PermissionInterceptor implements AsyncHandlerInterceptor {
SessionManager sessionManager; SessionManager sessionManager;
@Autowired @Autowired
AuthJwtService authJwtService ; AuthTokenService authTokenService ;
boolean mgmt = false; boolean mgmt = false;
@ -59,7 +59,7 @@ public class PermissionInterceptor implements AsyncHandlerInterceptor {
@Override @Override
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception { public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
_logger.trace("Permission Interceptor ."); _logger.trace("Permission Interceptor .");
AuthorizationUtils.authenticate(request, authJwtService, sessionManager); AuthorizationUtils.authenticate(request, authTokenService, sessionManager);
SignPrincipal principal = AuthorizationUtils.getPrincipal(); SignPrincipal principal = AuthorizationUtils.getPrincipal();
//判断用户是否登录,判断用户是否登录用户 //判断用户是否登录,判断用户是否登录用户
if(principal == null){ if(principal == null){

View File

@ -19,7 +19,8 @@ package org.maxkey.autoconfigure;
import org.maxkey.authn.AbstractAuthenticationProvider; import org.maxkey.authn.AbstractAuthenticationProvider;
import org.maxkey.authn.SavedRequestAwareAuthenticationSuccessHandler; import org.maxkey.authn.SavedRequestAwareAuthenticationSuccessHandler;
import org.maxkey.authn.jwt.AuthJwtService; import org.maxkey.authn.jwt.AuthRefreshTokenService;
import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.authn.jwt.CongressService; import org.maxkey.authn.jwt.CongressService;
import org.maxkey.authn.jwt.InMemoryCongressService; import org.maxkey.authn.jwt.InMemoryCongressService;
import org.maxkey.authn.jwt.RedisCongressService; import org.maxkey.authn.jwt.RedisCongressService;
@ -30,8 +31,8 @@ import org.maxkey.authn.provider.TrustedAuthenticationProvider;
import org.maxkey.authn.realm.AbstractAuthenticationRealm; import org.maxkey.authn.realm.AbstractAuthenticationRealm;
import org.maxkey.authn.session.SessionManager; import org.maxkey.authn.session.SessionManager;
import org.maxkey.authn.session.SessionManagerFactory; import org.maxkey.authn.session.SessionManagerFactory;
import org.maxkey.authn.support.rememberme.AbstractRemeberMeService; import org.maxkey.authn.support.rememberme.AbstractRemeberMeManager;
import org.maxkey.authn.support.rememberme.JdbcRemeberMeService; import org.maxkey.authn.support.rememberme.JdbcRemeberMeManager;
import org.maxkey.authn.web.HttpSessionListenerAdapter; import org.maxkey.authn.web.HttpSessionListenerAdapter;
import org.maxkey.configuration.ApplicationConfig; import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.configuration.AuthJwkConfig; import org.maxkey.configuration.AuthJwkConfig;
@ -89,14 +90,14 @@ public class AuthenticationAutoConfiguration implements InitializingBean {
AbstractAuthenticationRealm authenticationRealm, AbstractAuthenticationRealm authenticationRealm,
ApplicationConfig applicationConfig, ApplicationConfig applicationConfig,
SessionManager sessionManager, SessionManager sessionManager,
AuthJwtService authJwtService AuthTokenService authTokenService
) { ) {
_logger.debug("init authentication Provider ."); _logger.debug("init authentication Provider .");
return new NormalAuthenticationProvider( return new NormalAuthenticationProvider(
authenticationRealm, authenticationRealm,
applicationConfig, applicationConfig,
sessionManager, sessionManager,
authJwtService authTokenService
); );
} }
@ -131,10 +132,11 @@ public class AuthenticationAutoConfiguration implements InitializingBean {
} }
@Bean @Bean
public AuthJwtService authJwtService( public AuthTokenService authTokenService(
AuthJwkConfig authJwkConfig, AuthJwkConfig authJwkConfig,
RedisConnectionFactory redisConnFactory, RedisConnectionFactory redisConnFactory,
MomentaryService momentaryService, MomentaryService momentaryService,
AuthRefreshTokenService refreshTokenService,
@Value("${maxkey.server.persistence}") int persistence) throws JOSEException { @Value("${maxkey.server.persistence}") int persistence) throws JOSEException {
CongressService congressService; CongressService congressService;
if (persistence == ConstsPersistence.REDIS) { if (persistence == ConstsPersistence.REDIS) {
@ -143,9 +145,20 @@ public class AuthenticationAutoConfiguration implements InitializingBean {
congressService = new InMemoryCongressService(); congressService = new InMemoryCongressService();
} }
AuthJwtService authJwtService = new AuthJwtService(authJwkConfig,congressService,momentaryService); AuthTokenService authTokenService =
new AuthTokenService(
authJwkConfig,
congressService,
momentaryService,
refreshTokenService
);
return authJwtService; return authTokenService;
}
@Bean
public AuthRefreshTokenService refreshTokenService(AuthJwkConfig authJwkConfig) throws JOSEException {
return new AuthRefreshTokenService(authJwkConfig);
} }
@Bean(name = "otpAuthnService") @Bean(name = "otpAuthnService")
@ -196,21 +209,20 @@ public class AuthenticationAutoConfiguration implements InitializingBean {
return sessionManager; return sessionManager;
} }
/** /**
* remeberMeService . * remeberMeService .
* @return * @return
*/ */
@Bean @Bean
public AbstractRemeberMeService remeberMeService( public AbstractRemeberMeManager remeberMeManager(
@Value("${maxkey.server.persistence}") int persistence, @Value("${maxkey.server.persistence}") int persistence,
@Value("${maxkey.login.remeberme.validity}") int validity, @Value("${maxkey.login.remeberme.validity}") int validity,
ApplicationConfig applicationConfig, ApplicationConfig applicationConfig,
AuthJwtService authJwtService, AuthTokenService authTokenService,
JdbcTemplate jdbcTemplate) { JdbcTemplate jdbcTemplate) {
_logger.trace("init remeberMeService , validity {}." , validity); _logger.trace("init RemeberMeManager , validity {}." , validity);
return new JdbcRemeberMeService( return new JdbcRemeberMeManager(
jdbcTemplate,applicationConfig,authJwtService,validity); jdbcTemplate,applicationConfig,authTokenService,validity);
} }
@Bean @Bean

View File

@ -41,7 +41,7 @@ public class JwtAuthnAutoConfiguration implements InitializingBean {
* jwt Login JwkSetKeyStore. * jwt Login JwkSetKeyStore.
* @return * @return
*/ */
@Bean(name = "jwtLoginJwkSetKeyStore") @Bean
public JWKSetKeyStore jwtLoginJwkSetKeyStore() { public JWKSetKeyStore jwtLoginJwkSetKeyStore() {
JWKSetKeyStore jwkSetKeyStore = new JWKSetKeyStore(); JWKSetKeyStore jwkSetKeyStore = new JWKSetKeyStore();
ClassPathResource classPathResource = new ClassPathResource("/config/loginjwkkeystore.jwks"); ClassPathResource classPathResource = new ClassPathResource("/config/loginjwkkeystore.jwks");
@ -57,7 +57,7 @@ public class JwtAuthnAutoConfiguration implements InitializingBean {
* @throws InvalidKeySpecException * @throws InvalidKeySpecException
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
*/ */
@Bean(name = "jwtLoginValidationService") @Bean
public DefaultJwtSigningAndValidationService jwtLoginValidationService( public DefaultJwtSigningAndValidationService jwtLoginValidationService(
JWKSetKeyStore jwtLoginJwkSetKeyStore) JWKSetKeyStore jwtLoginJwkSetKeyStore)
throws NoSuchAlgorithmException, InvalidKeySpecException, JOSEException { throws NoSuchAlgorithmException, InvalidKeySpecException, JOSEException {
@ -73,7 +73,7 @@ public class JwtAuthnAutoConfiguration implements InitializingBean {
* Jwt LoginService. * Jwt LoginService.
* @return * @return
*/ */
@Bean(name = "jwtLoginService") @Bean
public JwtLoginService jwtLoginService( public JwtLoginService jwtLoginService(
@Value("${maxkey.login.jwt.issuer}") @Value("${maxkey.login.jwt.issuer}")
String issuer, String issuer,

View File

@ -21,7 +21,7 @@
package org.maxkey.authn.support.socialsignon; package org.maxkey.authn.support.socialsignon;
import org.maxkey.authn.AbstractAuthenticationProvider; import org.maxkey.authn.AbstractAuthenticationProvider;
import org.maxkey.authn.jwt.AuthJwtService; import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.authn.support.socialsignon.service.SocialSignOnProviderService; import org.maxkey.authn.support.socialsignon.service.SocialSignOnProviderService;
import org.maxkey.authn.support.socialsignon.service.SocialsAssociateService; import org.maxkey.authn.support.socialsignon.service.SocialsAssociateService;
import org.maxkey.configuration.ApplicationConfig; import org.maxkey.configuration.ApplicationConfig;
@ -59,7 +59,7 @@ public class AbstractSocialSignOnEndpoint {
AbstractAuthenticationProvider authenticationProvider ; AbstractAuthenticationProvider authenticationProvider ;
@Autowired @Autowired
AuthJwtService authJwtService; AuthTokenService authTokenService;
@Autowired @Autowired
ApplicationConfig applicationConfig; ApplicationConfig applicationConfig;

View File

@ -59,7 +59,7 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
) { ) {
_logger.trace("SocialSignOn provider : " + provider); _logger.trace("SocialSignOn provider : " + provider);
String instId = WebContext.getInst().getId(); String instId = WebContext.getInst().getId();
String authorizationUrl = buildAuthRequest(instId,provider).authorize(authJwtService.genJwt()); String authorizationUrl = buildAuthRequest(instId,provider).authorize(authTokenService.genRandomJwt());
_logger.trace("authorize SocialSignOn : " + authorizationUrl); _logger.trace("authorize SocialSignOn : " + authorizationUrl);
return new Message<Object>((Object)authorizationUrl).buildResponse(); return new Message<Object>((Object)authorizationUrl).buildResponse();
} }
@ -75,7 +75,7 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
if(authRequest == null ) { if(authRequest == null ) {
_logger.error("build authRequest fail ."); _logger.error("build authRequest fail .");
} }
String state = authJwtService.genJwt(); String state = authTokenService.genRandomJwt();
authRequest.authorize(state); authRequest.authorize(state);
SocialsProvider socialSignOnProvider = socialSignOnProviderService.get(instId,provider); SocialsProvider socialSignOnProvider = socialSignOnProviderService.get(instId,provider);
@ -139,7 +139,7 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
//socialsAssociate.setExAttribute(JsonUtils.object2Json(accessToken.getResponseObject())); //socialsAssociate.setExAttribute(JsonUtils.object2Json(accessToken.getResponseObject()));
this.socialsAssociateService.update(socialsAssociate); this.socialsAssociateService.update(socialsAssociate);
return new Message<AuthJwt>(authJwtService.genAuthJwt(authentication)).buildResponse(); return new Message<AuthJwt>(authTokenService.genAuthJwt(authentication)).buildResponse();
}catch(Exception e) { }catch(Exception e) {
_logger.error("callback Exception ",e); _logger.error("callback Exception ",e);
return new Message<AuthJwt>(Message.ERROR).buildResponse(); return new Message<AuthJwt>(Message.ERROR).buildResponse();

View File

@ -62,22 +62,22 @@ public class ApplicationAutoConfiguration implements InitializingBean {
private static final Logger _logger = private static final Logger _logger =
LoggerFactory.getLogger(ApplicationAutoConfiguration.class); LoggerFactory.getLogger(ApplicationAutoConfiguration.class);
@Bean(name = "passwordReciprocal") @Bean
public PasswordReciprocal passwordReciprocal() { public PasswordReciprocal passwordReciprocal() {
return new PasswordReciprocal(); return new PasswordReciprocal();
} }
@Bean(name = "transactionManager") @Bean
public DataSourceTransactionManager transactionManager(DataSource dataSource) { public DataSourceTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource); return new DataSourceTransactionManager(dataSource);
} }
@Bean(name = "institutionsRepository") @Bean
public InstitutionsRepository InstitutionsRepository(JdbcTemplate jdbcTemplate) { public InstitutionsRepository institutionsRepository(JdbcTemplate jdbcTemplate) {
return new InstitutionsRepository(jdbcTemplate); return new InstitutionsRepository(jdbcTemplate);
} }
@Bean(name = "localizationRepository") @Bean
public LocalizationRepository localizationRepository(JdbcTemplate jdbcTemplate, public LocalizationRepository localizationRepository(JdbcTemplate jdbcTemplate,
InstitutionsRepository institutionsRepository) { InstitutionsRepository institutionsRepository) {
return new LocalizationRepository(jdbcTemplate,institutionsRepository); return new LocalizationRepository(jdbcTemplate,institutionsRepository);
@ -87,7 +87,7 @@ public class ApplicationAutoConfiguration implements InitializingBean {
* Authentication Password Encoder . * Authentication Password Encoder .
* @return * @return
*/ */
@Bean(name = "passwordEncoder") @Bean
public PasswordEncoder passwordEncoder() { public PasswordEncoder passwordEncoder() {
String idForEncode = "bcrypt"; String idForEncode = "bcrypt";
Map<String ,PasswordEncoder > encoders = new HashMap<String ,PasswordEncoder>(); Map<String ,PasswordEncoder > encoders = new HashMap<String ,PasswordEncoder>();
@ -127,7 +127,7 @@ public class ApplicationAutoConfiguration implements InitializingBean {
* keyStoreLoader . * keyStoreLoader .
* @return * @return
*/ */
@Bean(name = "keyStoreLoader") @Bean
public KeyStoreLoader keyStoreLoader( public KeyStoreLoader keyStoreLoader(
@Value("${maxkey.saml.v20.idp.issuing.entity.id}") String entityName, @Value("${maxkey.saml.v20.idp.issuing.entity.id}") String entityName,
@Value("${maxkey.saml.v20.idp.keystore.password}") String keystorePassword, @Value("${maxkey.saml.v20.idp.keystore.password}") String keystorePassword,
@ -143,7 +143,7 @@ public class ApplicationAutoConfiguration implements InitializingBean {
* spKeyStoreLoader . * spKeyStoreLoader .
* @return * @return
*/ */
@Bean(name = "spKeyStoreLoader") @Bean
public KeyStoreLoader spKeyStoreLoader( public KeyStoreLoader spKeyStoreLoader(
@Value("${maxkey.saml.v20.sp.issuing.entity.id}") String entityName, @Value("${maxkey.saml.v20.sp.issuing.entity.id}") String entityName,
@Value("${maxkey.saml.v20.sp.keystore.password}") String keystorePassword, @Value("${maxkey.saml.v20.sp.keystore.password}") String keystorePassword,
@ -159,17 +159,17 @@ public class ApplicationAutoConfiguration implements InitializingBean {
* spKeyStoreLoader . * spKeyStoreLoader .
* @return * @return
*/ */
@Bean(name = "spIssuingEntityName") @Bean
public String spIssuingEntityName( public String spIssuingEntityName(
@Value("${maxkey.saml.v20.sp.issuing.entity.id}") String spIssuingEntityName) { @Value("${maxkey.saml.v20.sp.issuing.entity.id}") String spIssuingEntityName) {
return spIssuingEntityName; return spIssuingEntityName;
} }
/** /**
* spKeyStoreLoader . * Id Generator .
* @return * @return
*/ */
@Bean(name = "idGenerator") @Bean
public IdGenerator idGenerator( public IdGenerator idGenerator(
@Value("${maxkey.id.strategy:SnowFlake}") String strategy, @Value("${maxkey.id.strategy:SnowFlake}") String strategy,
@Value("${maxkey.id.datacenterId:0}") int datacenterId, @Value("${maxkey.id.datacenterId:0}") int datacenterId,
@ -182,7 +182,7 @@ public class ApplicationAutoConfiguration implements InitializingBean {
} }
@Bean(name = "momentaryService") @Bean
public MomentaryService momentaryService( public MomentaryService momentaryService(
RedisConnectionFactory redisConnFactory, RedisConnectionFactory redisConnFactory,
@Value("${maxkey.server.persistence}") int persistence) throws JOSEException { @Value("${maxkey.server.persistence}") int persistence) throws JOSEException {

View File

@ -37,16 +37,7 @@ import org.springframework.stereotype.Component;
@Configuration @Configuration
public class ApplicationConfig { public class ApplicationConfig {
@Autowired @Value("${maxkey.server.basedomain}")
EmailConfig emailConfig;
@Autowired
CharacterEncodingConfig characterEncodingConfig;
@Autowired
LoginConfig loginConfig;
@Value("${maxkey.server.basedomain}")
String baseDomainName; String baseDomainName;
@Value("${maxkey.server.domain}") @Value("${maxkey.server.domain}")
@ -83,6 +74,17 @@ public class ApplicationConfig {
private boolean noticesVisible; private boolean noticesVisible;
public static String databaseProduct = "MySQL"; public static String databaseProduct = "MySQL";
@Autowired
EmailConfig emailConfig;
@Autowired
CharacterEncodingConfig characterEncodingConfig;
@Autowired
LoginConfig loginConfig;
public int getPort() { public int getPort() {

View File

@ -25,9 +25,6 @@ import org.springframework.stereotype.Component;
@Configuration @Configuration
public class AuthJwkConfig { public class AuthJwkConfig {
@Value("${maxkey.auth.jwt.issuer:https://sso.maxkey.top/}")
String issuer;
@Value("${maxkey.auth.jwt.expires:86400}") @Value("${maxkey.auth.jwt.expires:86400}")
int expires; int expires;
@ -35,10 +32,13 @@ public class AuthJwkConfig {
String secret; String secret;
@Value("${maxkey.session.timeout}") @Value("${maxkey.session.timeout}")
String refreshExpire; int refreshExpires;
@Value("${maxkey.auth.jwt.refresh.secret}") @Value("${maxkey.auth.jwt.refresh.secret}")
String refreshSecret; String refreshSecret;
@Value("${maxkey.auth.jwt.issuer:https://sso.maxkey.top/}")
String issuer;
public AuthJwkConfig() { public AuthJwkConfig() {
super(); super();
@ -52,7 +52,6 @@ public class AuthJwkConfig {
this.issuer = issuer; this.issuer = issuer;
} }
public int getExpires() { public int getExpires() {
return expires; return expires;
@ -69,6 +68,22 @@ public class AuthJwkConfig {
public void setSecret(String secret) { public void setSecret(String secret) {
this.secret = secret; this.secret = secret;
} }
public int getRefreshExpires() {
return refreshExpires;
}
public void setRefreshExpires(int refreshExpires) {
this.refreshExpires = refreshExpires;
}
public String getRefreshSecret() {
return refreshSecret;
}
public void setRefreshSecret(String refreshSecret) {
this.refreshSecret = refreshSecret;
}
@Override @Override
public String toString() { public String toString() {

View File

@ -45,15 +45,12 @@ public class AuthorizeBaseEndpoint {
final static Logger _logger = LoggerFactory.getLogger(AuthorizeBaseEndpoint.class); final static Logger _logger = LoggerFactory.getLogger(AuthorizeBaseEndpoint.class);
@Autowired @Autowired
@Qualifier("applicationConfig")
protected ApplicationConfig applicationConfig; protected ApplicationConfig applicationConfig;
@Autowired @Autowired
@Qualifier("appsService")
protected AppsService appsService; protected AppsService appsService;
@Autowired @Autowired
@Qualifier("accountsService")
protected AccountsService accountsService; protected AccountsService accountsService;
protected Apps getApp(String id){ protected Apps getApp(String id){

View File

@ -33,11 +33,9 @@ public class CasBaseAuthorizeEndpoint extends AuthorizeBaseEndpoint{
final static Logger _logger = LoggerFactory.getLogger(CasBaseAuthorizeEndpoint.class); final static Logger _logger = LoggerFactory.getLogger(CasBaseAuthorizeEndpoint.class);
@Autowired @Autowired
@Qualifier("appsCasDetailsService")
protected AppsCasDetailsService casDetailsService; protected AppsCasDetailsService casDetailsService;
@Autowired @Autowired
@Qualifier("userInfoService")
protected UserInfoService userInfoService; protected UserInfoService userInfoService;
@Autowired @Autowired

View File

@ -33,7 +33,7 @@ import org.apache.commons.lang.Validate;
import org.maxkey.authn.AbstractAuthenticationProvider; import org.maxkey.authn.AbstractAuthenticationProvider;
import org.maxkey.authn.LoginCredential; import org.maxkey.authn.LoginCredential;
import org.maxkey.authn.jwt.AuthJwt; import org.maxkey.authn.jwt.AuthJwt;
import org.maxkey.authn.jwt.AuthJwtService; import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.authz.saml.common.EndpointGenerator; import org.maxkey.authz.saml.common.EndpointGenerator;
import org.maxkey.authz.saml.common.TrustResolver; import org.maxkey.authz.saml.common.TrustResolver;
import org.maxkey.authz.saml.service.IDService; import org.maxkey.authz.saml.service.IDService;
@ -120,7 +120,7 @@ public class ConsumerEndpoint {
private MessageReplayRule messageReplayRule; private MessageReplayRule messageReplayRule;
@Autowired @Autowired
AuthJwtService authJwtService; AuthTokenService authJwtService;
EndpointGenerator endpointGenerator; EndpointGenerator endpointGenerator;
AuthnRequestGenerator authnRequestGenerator; AuthnRequestGenerator authnRequestGenerator;

View File

@ -13,9 +13,12 @@ import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth';
import { ALAIN_I18N_TOKEN, _HttpClient } from '@delon/theme'; import { ALAIN_I18N_TOKEN, _HttpClient } from '@delon/theme';
import { environment } from '@env/environment'; import { environment } from '@env/environment';
import { NzNotificationService } from 'ng-zorro-antd/notification'; import { NzNotificationService } from 'ng-zorro-antd/notification';
import { CookieService } from 'ngx-cookie-service';
import { BehaviorSubject, Observable, of, throwError } from 'rxjs'; import { BehaviorSubject, Observable, of, throwError } from 'rxjs';
import { catchError, filter, mergeMap, switchMap, take } from 'rxjs/operators'; import { catchError, filter, mergeMap, switchMap, take } from 'rxjs/operators';
import { CONSTS } from '../../shared/consts';
const CODEMESSAGE: { [key: number]: string } = { const CODEMESSAGE: { [key: number]: string } = {
200: '服务器成功返回请求的数据。', 200: '服务器成功返回请求的数据。',
201: '新建或修改数据成功。', 201: '新建或修改数据成功。',
@ -54,6 +57,10 @@ export class DefaultInterceptor implements HttpInterceptor {
return this.injector.get(NzNotificationService); return this.injector.get(NzNotificationService);
} }
private get cookieService(): CookieService {
return this.injector.get(CookieService);
}
private get tokenSrv(): ITokenService { private get tokenSrv(): ITokenService {
return this.injector.get(DA_SERVICE_TOKEN); return this.injector.get(DA_SERVICE_TOKEN);
} }
@ -80,17 +87,18 @@ export class DefaultInterceptor implements HttpInterceptor {
*/ */
private refreshTokenRequest(): Observable<any> { private refreshTokenRequest(): Observable<any> {
const model = this.tokenSrv.get(); const model = this.tokenSrv.get();
return this.http.post(`/api/auth/refresh`, null, null, { headers: { refresh_token: model?.['refresh_token'] || '' } }); return this.http.post(`/auth/token/refresh`, null, null, { headers: { refresh_token: model?.['refreshToken'] || '' } });
} }
// #region 刷新Token方式一使用 401 重新刷新 Token // #region 刷新Token方式一使用 401 重新刷新 Token
private tryRefreshToken(ev: HttpResponseBase, req: HttpRequest<any>, next: HttpHandler): Observable<any> { private tryRefreshToken(ev: HttpResponseBase, req: HttpRequest<any>, next: HttpHandler): Observable<any> {
// 1、若请求为刷新Token请求表示来自刷新Token可以直接跳转登录页 // 1、若请求为刷新Token请求表示来自刷新Token可以直接跳转登录页
if ([`/api/auth/refresh`].some(url => req.url.includes(url))) { if ([`/auth/token/refresh`].some(url => req.url.includes(url))) {
this.toLogin(); this.toLogin();
return throwError(ev); return throwError(ev);
} }
// 2、如果 `refreshToking` 为 `true` 表示已经在请求刷新 Token 中,后续所有请求转入等待状态,直至结果返回后再重新发起请求 // 2、如果 `refreshToking` 为 `true` 表示已经在请求刷新 Token 中,后续所有请求转入等待状态,直至结果返回后再重新发起请求
if (this.refreshToking) { if (this.refreshToking) {
return this.refreshToken$.pipe( return this.refreshToken$.pipe(
@ -99,17 +107,20 @@ export class DefaultInterceptor implements HttpInterceptor {
switchMap(() => next.handle(this.reAttachToken(req))) switchMap(() => next.handle(this.reAttachToken(req)))
); );
} }
// 3、尝试调用刷新 Token // 3、尝试调用刷新 Token
this.refreshToking = true; this.refreshToking = true;
this.refreshToken$.next(null); this.refreshToken$.next(null);
return this.refreshTokenRequest().pipe( return this.refreshTokenRequest().pipe(
switchMap(res => { switchMap(res => {
console.log(res.data);
// 通知后续请求继续执行 // 通知后续请求继续执行
this.refreshToking = false; this.refreshToking = false;
this.refreshToken$.next(res); this.refreshToken$.next(res.data.refreshToken);
this.cookieService.set(CONSTS.CONGRESS, res.data.token);
// 重新保存新 token // 重新保存新 token
this.tokenSrv.set(res); this.tokenSrv.set(res.data);
// 重新发起请求 // 重新发起请求
return next.handle(this.reAttachToken(req)); return next.handle(this.reAttachToken(req));
}), }),
@ -127,6 +138,7 @@ export class DefaultInterceptor implements HttpInterceptor {
* > `@delon/auth` Token * > `@delon/auth` Token
*/ */
private reAttachToken(req: HttpRequest<any>): HttpRequest<any> { private reAttachToken(req: HttpRequest<any>): HttpRequest<any> {
//console.log('reAttachToken');
// 以下示例是以 NG-ALAIN 默认使用 `SimpleInterceptor` // 以下示例是以 NG-ALAIN 默认使用 `SimpleInterceptor`
const token = this.tokenSrv.get()?.token; const token = this.tokenSrv.get()?.token;
return req.clone({ return req.clone({

View File

@ -13,7 +13,7 @@ export const environment = {
api: { api: {
baseUrl: 'http://sso.maxkey.top:8080/maxkey', baseUrl: 'http://sso.maxkey.top:8080/maxkey',
refreshTokenEnabled: true, refreshTokenEnabled: true,
refreshTokenType: 'auth-refresh' refreshTokenType: 're-request'
}, },
modules: [DelonMockModule.forRoot({ data: MOCKDATA })] modules: [DelonMockModule.forRoot({ data: MOCKDATA })]
} as Environment; } as Environment;

View File

@ -80,14 +80,14 @@ export class DefaultInterceptor implements HttpInterceptor {
*/ */
private refreshTokenRequest(): Observable<any> { private refreshTokenRequest(): Observable<any> {
const model = this.tokenSrv.get(); const model = this.tokenSrv.get();
return this.http.post(`/api/auth/refresh`, null, null, { headers: { refresh_token: model?.['refresh_token'] || '' } }); return this.http.post(`/auth/token/refresh`, null, null, { headers: { refresh_token: model?.['refresh_token'] || '' } });
} }
// #region 刷新Token方式一使用 401 重新刷新 Token // #region 刷新Token方式一使用 401 重新刷新 Token
private tryRefreshToken(ev: HttpResponseBase, req: HttpRequest<any>, next: HttpHandler): Observable<any> { private tryRefreshToken(ev: HttpResponseBase, req: HttpRequest<any>, next: HttpHandler): Observable<any> {
// 1、若请求为刷新Token请求表示来自刷新Token可以直接跳转登录页 // 1、若请求为刷新Token请求表示来自刷新Token可以直接跳转登录页
if ([`/api/auth/refresh`].some(url => req.url.includes(url))) { if ([`/auth/token/refresh`].some(url => req.url.includes(url))) {
this.toLogin(); this.toLogin();
return throwError(ev); return throwError(ev);
} }

View File

@ -77,7 +77,7 @@ public class MaxKeyConfig implements InitializingBean {
private static final Logger _logger = LoggerFactory.getLogger(MaxKeyConfig.class); private static final Logger _logger = LoggerFactory.getLogger(MaxKeyConfig.class);
@Bean(name = "otpKeyUriFormat") @Bean
public OtpKeyUriFormat otpKeyUriFormat( public OtpKeyUriFormat otpKeyUriFormat(
@Value("${maxkey.otp.policy.type:totp}") @Value("${maxkey.otp.policy.type:totp}")
String type, String type,
@ -96,7 +96,7 @@ public class MaxKeyConfig implements InitializingBean {
} }
//可以在此实现其他的登陆认证方式请实现AbstractAuthenticationRealm //可以在此实现其他的登陆认证方式请实现AbstractAuthenticationRealm
@Bean(name = "authenticationRealm") @Bean
public JdbcAuthenticationRealm authenticationRealm( public JdbcAuthenticationRealm authenticationRealm(
PasswordEncoder passwordEncoder, PasswordEncoder passwordEncoder,
PasswordPolicyValidator passwordPolicyValidator, PasswordPolicyValidator passwordPolicyValidator,
@ -120,7 +120,7 @@ public class MaxKeyConfig implements InitializingBean {
return authenticationRealm; return authenticationRealm;
} }
@Bean(name = "timeBasedOtpAuthn") @Bean
public TimeBasedOtpAuthn timeBasedOtpAuthn( public TimeBasedOtpAuthn timeBasedOtpAuthn(
@Value("${maxkey.otp.policy.digits:6}") @Value("${maxkey.otp.policy.digits:6}")
int digits, int digits,
@ -131,8 +131,8 @@ public class MaxKeyConfig implements InitializingBean {
return tfaOtpAuthn; return tfaOtpAuthn;
} }
@Bean(name = "tfaOtpAuthn") @Bean
public AbstractOtpAuthn tfaOptAuthn( public AbstractOtpAuthn tfaOtpAuthn(
@Value("${maxkey.login.mfa.type}")String mfaType, @Value("${maxkey.login.mfa.type}")String mfaType,
@Value("${maxkey.otp.policy.digits:6}") @Value("${maxkey.otp.policy.digits:6}")
int digits, int digits,
@ -152,7 +152,7 @@ public class MaxKeyConfig implements InitializingBean {
return tfaOtpAuthn; return tfaOtpAuthn;
} }
@Bean(name = "mailOtpAuthn") @Bean
public MailOtpAuthn mailOtpAuthn( public MailOtpAuthn mailOtpAuthn(
EmailConfig emailConfig, EmailConfig emailConfig,
@Value("${spring.mail.properties.mailotp.message.subject}") @Value("${spring.mail.properties.mailotp.message.subject}")
@ -185,7 +185,7 @@ public class MaxKeyConfig implements InitializingBean {
} }
@Bean(name = "kerberosService") @Bean
public RemoteKerberosService kerberosService( public RemoteKerberosService kerberosService(
@Value("${maxkey.login.kerberos.default.userdomain}") @Value("${maxkey.login.kerberos.default.userdomain}")
String userDomain, String userDomain,

View File

@ -46,6 +46,15 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@EnableWebMvc @EnableWebMvc
public class MaxKeyMvcConfig implements WebMvcConfigurer { public class MaxKeyMvcConfig implements WebMvcConfigurer {
private static final Logger _logger = LoggerFactory.getLogger(MaxKeyMvcConfig.class); private static final Logger _logger = LoggerFactory.getLogger(MaxKeyMvcConfig.class);
@Value("${maxkey.login.basic.enable:false}")
private boolean basicEnable;
@Value("${maxkey.login.httpheader.enable:false}")
private boolean httpHeaderEnable;
@Value("${maxkey.login.httpheader.headername:iv-user}")
private String httpHeaderName;
@Autowired @Autowired
ApplicationConfig applicationConfig; ApplicationConfig applicationConfig;
@ -69,15 +78,6 @@ public class MaxKeyMvcConfig implements WebMvcConfigurer {
@Autowired @Autowired
HistorySignOnAppInterceptor historySignOnAppInterceptor; HistorySignOnAppInterceptor historySignOnAppInterceptor;
@Value("${maxkey.login.httpheader.enable:false}")
private boolean httpHeaderEnable;
@Value("${maxkey.login.httpheader.headername:iv-user}")
private String httpHeaderName;
@Value("${maxkey.login.basic.enable:false}")
private boolean basicEnable;
@Override @Override
public void addResourceHandlers(ResourceHandlerRegistry registry) { public void addResourceHandlers(ResourceHandlerRegistry registry) {
_logger.debug("addResourceHandlers"); _logger.debug("addResourceHandlers");

View File

@ -20,6 +20,7 @@ package org.maxkey.web.contorller;
import java.util.List; import java.util.List;
import org.maxkey.authn.annotation.CurrentUser; import org.maxkey.authn.annotation.CurrentUser;
import org.maxkey.authn.web.AuthorizationUtils;
import org.maxkey.constants.ConstsStatus; import org.maxkey.constants.ConstsStatus;
import org.maxkey.crypto.password.PasswordReciprocal; import org.maxkey.crypto.password.PasswordReciprocal;
import org.maxkey.entity.Accounts; import org.maxkey.entity.Accounts;
@ -78,6 +79,7 @@ public class AppListController {
for (UserApps app : appList) { for (UserApps app : appList) {
app.transIconBase64(); app.transIconBase64();
} }
//AuthorizationUtils.setAuthentication(null);
return new Message<List<UserApps>>(appList).buildResponse(); return new Message<List<UserApps>>(appList).buildResponse();
} }

View File

@ -20,7 +20,7 @@ package org.maxkey.web.contorller;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.maxkey.authn.jwt.AuthJwtService; import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.configuration.EmailConfig; import org.maxkey.configuration.EmailConfig;
import org.maxkey.entity.ChangePassword; import org.maxkey.entity.ChangePassword;
import org.maxkey.entity.Message; import org.maxkey.entity.Message;
@ -68,7 +68,7 @@ public class ForgotPasswordContorller {
} }
@Autowired @Autowired
AuthJwtService authJwtService; AuthTokenService authTokenService;
@Autowired @Autowired
UserInfoService userInfoService; UserInfoService userInfoService;
@ -88,7 +88,7 @@ public class ForgotPasswordContorller {
@RequestParam String captcha) { @RequestParam String captcha) {
_logger.debug("forgotpassword /forgotpassword/produceOtp."); _logger.debug("forgotpassword /forgotpassword/produceOtp.");
_logger.debug(" Mobile {}: " ,mobile); _logger.debug(" Mobile {}: " ,mobile);
if (!authJwtService.validateCaptcha(state,captcha)) { if (!authTokenService.validateCaptcha(state,captcha)) {
_logger.debug("login captcha valid error."); _logger.debug("login captcha valid error.");
return new Message<ChangePassword>(Message.FAIL).buildResponse(); return new Message<ChangePassword>(Message.FAIL).buildResponse();
} }
@ -116,7 +116,7 @@ public class ForgotPasswordContorller {
@RequestParam String state, @RequestParam String state,
@RequestParam String captcha) { @RequestParam String captcha) {
_logger.debug("/forgotpassword/produceEmailOtp Email {} : " , email); _logger.debug("/forgotpassword/produceEmailOtp Email {} : " , email);
if (!authJwtService.validateCaptcha(state,captcha)) { if (!authTokenService.validateCaptcha(state,captcha)) {
_logger.debug("captcha valid error."); _logger.debug("captcha valid error.");
return new Message<ChangePassword>(Message.FAIL).buildResponse(); return new Message<ChangePassword>(Message.FAIL).buildResponse();
} }

View File

@ -49,8 +49,8 @@ public class IndexEndpoint {
NoticesService noticesService; NoticesService noticesService;
@Autowired @Autowired
@Qualifier("applicationConfig")
ApplicationConfig applicationConfig; ApplicationConfig applicationConfig;
@RequestMapping(value={"/forwardindex"}) @RequestMapping(value={"/forwardindex"})
public ModelAndView forwardindex(HttpServletRequest request, public ModelAndView forwardindex(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException { HttpServletResponse response) throws ServletException, IOException {

View File

@ -28,9 +28,9 @@ import org.apache.commons.lang3.StringUtils;
import org.maxkey.authn.AbstractAuthenticationProvider; import org.maxkey.authn.AbstractAuthenticationProvider;
import org.maxkey.authn.LoginCredential; import org.maxkey.authn.LoginCredential;
import org.maxkey.authn.jwt.AuthJwt; import org.maxkey.authn.jwt.AuthJwt;
import org.maxkey.authn.jwt.AuthJwtService; import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.authn.support.kerberos.KerberosService; import org.maxkey.authn.support.kerberos.KerberosService;
import org.maxkey.authn.support.rememberme.AbstractRemeberMeService; import org.maxkey.authn.support.rememberme.AbstractRemeberMeManager;
import org.maxkey.authn.support.rememberme.RemeberMe; import org.maxkey.authn.support.rememberme.RemeberMe;
import org.maxkey.authn.support.socialsignon.service.SocialSignOnProviderService; import org.maxkey.authn.support.socialsignon.service.SocialSignOnProviderService;
import org.maxkey.configuration.ApplicationConfig; import org.maxkey.configuration.ApplicationConfig;
@ -45,7 +45,6 @@ import org.maxkey.web.WebContext;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
@ -71,17 +70,15 @@ public class LoginEntryPoint {
Pattern mobileRegex = Pattern.compile("^(13[4,5,6,7,8,9]|15[0,8,9,1,7]|188|187)\\\\d{8}$"); Pattern mobileRegex = Pattern.compile("^(13[4,5,6,7,8,9]|15[0,8,9,1,7]|188|187)\\\\d{8}$");
@Autowired @Autowired
AuthJwtService authJwtService; AuthTokenService authTokenService;
@Autowired @Autowired
ApplicationConfig applicationConfig; ApplicationConfig applicationConfig;
@Autowired @Autowired
@Qualifier("authenticationProvider")
AbstractAuthenticationProvider authenticationProvider ; AbstractAuthenticationProvider authenticationProvider ;
@Autowired @Autowired
@Qualifier("socialSignOnProviderService")
SocialSignOnProviderService socialSignOnProviderService; SocialSignOnProviderService socialSignOnProviderService;
@Autowired @Autowired
@ -91,15 +88,13 @@ public class LoginEntryPoint {
UserInfoService userInfoService; UserInfoService userInfoService;
@Autowired @Autowired
@Qualifier("tfaOtpAuthn") AbstractOtpAuthn tfaOtpAuthn;
protected AbstractOtpAuthn tfaOtpAuthn;
@Autowired @Autowired
@Qualifier("otpAuthnService") OtpAuthnService otpAuthnService;
protected OtpAuthnService otpAuthnService;
@Autowired @Autowired
AbstractRemeberMeService remeberMeService; AbstractRemeberMeManager remeberMeManager;
/** /**
* init login * init login
@ -112,16 +107,16 @@ public class LoginEntryPoint {
_logger.debug("/get."); _logger.debug("/get.");
//Remember Me //Remember Me
if(StringUtils.isNotBlank(rememberMeJwt) if(StringUtils.isNotBlank(rememberMeJwt)
&& authJwtService.validateJwtToken(rememberMeJwt)) { && authTokenService.validateJwtToken(rememberMeJwt)) {
try { try {
RemeberMe remeberMe = remeberMeService.resolve(rememberMeJwt); RemeberMe remeberMe = remeberMeManager.resolve(rememberMeJwt);
if(remeberMe != null) { if(remeberMe != null) {
LoginCredential credential = new LoginCredential(); LoginCredential credential = new LoginCredential();
String remeberMeJwt = remeberMeService.updateRemeberMe(remeberMe); String remeberMeJwt = remeberMeManager.updateRemeberMe(remeberMe);
credential.setUsername(remeberMe.getUsername()); credential.setUsername(remeberMe.getUsername());
Authentication authentication = authenticationProvider.authenticate(credential,true); Authentication authentication = authenticationProvider.authenticate(credential,true);
if(authentication != null) { if(authentication != null) {
AuthJwt authJwt = authJwtService.genAuthJwt(authentication); AuthJwt authJwt = authTokenService.genAuthJwt(authentication);
authJwt.setRemeberMe(remeberMeJwt); authJwt.setRemeberMe(remeberMeJwt);
return new Message<AuthJwt>(authJwt).buildResponse(); return new Message<AuthJwt>(authJwt).buildResponse();
} }
@ -150,7 +145,7 @@ public class LoginEntryPoint {
model.put("captcha", inst.getCaptchaSupport()); model.put("captcha", inst.getCaptchaSupport());
model.put("captchaType", inst.getCaptchaType()); model.put("captchaType", inst.getCaptchaType());
} }
model.put("state", authJwtService.genJwt()); model.put("state", authTokenService.genRandomJwt());
//load Social Sign On Providers //load Social Sign On Providers
model.put("socials", socialSignOnProviderService.loadSocials(inst.getId())); model.put("socials", socialSignOnProviderService.loadSocials(inst.getId()));
@ -178,16 +173,16 @@ public class LoginEntryPoint {
public ResponseEntity<?> signin( HttpServletRequest request, HttpServletResponse response, public ResponseEntity<?> signin( HttpServletRequest request, HttpServletResponse response,
@RequestBody LoginCredential credential) { @RequestBody LoginCredential credential) {
Message<AuthJwt> authJwtMessage = new Message<AuthJwt>(Message.FAIL); Message<AuthJwt> authJwtMessage = new Message<AuthJwt>(Message.FAIL);
if(authJwtService.validateJwtToken(credential.getState())){ if(authTokenService.validateJwtToken(credential.getState())){
String authType = credential.getAuthType(); String authType = credential.getAuthType();
_logger.debug("Login AuthN Type " + authType); _logger.debug("Login AuthN Type " + authType);
if (StringUtils.isNotBlank(authType)){ if (StringUtils.isNotBlank(authType)){
Authentication authentication = authenticationProvider.authenticate(credential); Authentication authentication = authenticationProvider.authenticate(credential);
if(authentication != null) { if(authentication != null) {
AuthJwt authJwt = authJwtService.genAuthJwt(authentication); AuthJwt authJwt = authTokenService.genAuthJwt(authentication);
if(StringUtils.isNotBlank(credential.getRemeberMe()) if(StringUtils.isNotBlank(credential.getRemeberMe())
&&credential.getRemeberMe().equalsIgnoreCase("true")) { &&credential.getRemeberMe().equalsIgnoreCase("true")) {
String remeberMe = remeberMeService.createRemeberMe(authentication, request, response); String remeberMe = remeberMeManager.createRemeberMe(authentication, request, response);
authJwt.setRemeberMe(remeberMe); authJwt.setRemeberMe(remeberMe);
} }
if(WebContext.getAttribute(WebConstants.CURRENT_USER_PASSWORD_SET_TYPE)!=null) if(WebContext.getAttribute(WebConstants.CURRENT_USER_PASSWORD_SET_TYPE)!=null)
@ -211,7 +206,7 @@ public class LoginEntryPoint {
@RequestMapping(value={"/congress"}, produces = {MediaType.APPLICATION_JSON_VALUE}) @RequestMapping(value={"/congress"}, produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<?> congress( @RequestBody LoginCredential credential) { public ResponseEntity<?> congress( @RequestBody LoginCredential credential) {
if(StringUtils.isNotBlank(credential.getCongress())){ if(StringUtils.isNotBlank(credential.getCongress())){
AuthJwt authJwt = authJwtService.consumeCongress(credential.getCongress()); AuthJwt authJwt = authTokenService.consumeCongress(credential.getCongress());
if(authJwt != null) { if(authJwt != null) {
return new Message<AuthJwt>(authJwt).buildResponse(); return new Message<AuthJwt>(authJwt).buildResponse();
} }

View File

@ -35,7 +35,6 @@ import org.maxkey.web.image.ImageEndpoint;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -54,11 +53,9 @@ public class OneTimePasswordController {
static final Logger _logger = LoggerFactory.getLogger(OneTimePasswordController.class); static final Logger _logger = LoggerFactory.getLogger(OneTimePasswordController.class);
@Autowired @Autowired
@Qualifier("userInfoService")
private UserInfoService userInfoService; private UserInfoService userInfoService;
@Autowired @Autowired
@Qualifier("otpKeyUriFormat")
OtpKeyUriFormat otpKeyUriFormat; OtpKeyUriFormat otpKeyUriFormat;
@RequestMapping(value = {"/timebased"}) @RequestMapping(value = {"/timebased"})

View File

@ -22,7 +22,7 @@ import java.util.regex.Pattern;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import org.maxkey.authn.jwt.AuthJwtService; import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.configuration.ApplicationConfig; import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.constants.ConstsStatus; import org.maxkey.constants.ConstsStatus;
import org.maxkey.crypto.password.PasswordReciprocal; import org.maxkey.crypto.password.PasswordReciprocal;
@ -55,7 +55,7 @@ public class RegisterController {
Pattern mobileRegex = Pattern.compile("^[1][3,4,5,7,8][0-9]{9}$"); Pattern mobileRegex = Pattern.compile("^[1][3,4,5,7,8][0-9]{9}$");
@Autowired @Autowired
AuthJwtService authJwtService; AuthTokenService authTokenService;
@Autowired @Autowired
protected ApplicationConfig applicationConfig; protected ApplicationConfig applicationConfig;

View File

@ -44,7 +44,6 @@ public class SocialSignOnListController {
@Autowired @Autowired
protected SocialsAssociatesService socialsAssociatesService; protected SocialsAssociatesService socialsAssociatesService;
@RequestMapping(value={"/fetch"}) @RequestMapping(value={"/fetch"})
@ResponseBody @ResponseBody
public ResponseEntity<?> fetch(@CurrentUser UserInfo currentUser){ public ResponseEntity<?> fetch(@CurrentUser UserInfo currentUser){

View File

@ -19,7 +19,7 @@ package org.maxkey.web.interceptor;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.maxkey.authn.jwt.AuthJwtService; import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.authn.session.SessionManager; import org.maxkey.authn.session.SessionManager;
import org.maxkey.authn.web.AuthorizationUtils; import org.maxkey.authn.web.AuthorizationUtils;
import org.maxkey.configuration.ApplicationConfig; import org.maxkey.configuration.ApplicationConfig;
@ -42,7 +42,7 @@ public class SingleSignOnInterceptor implements AsyncHandlerInterceptor {
SessionManager sessionManager; SessionManager sessionManager;
@Autowired @Autowired
AuthJwtService authJwtService ; AuthTokenService authTokenService ;
@Override @Override
public boolean preHandle(HttpServletRequest request, public boolean preHandle(HttpServletRequest request,
@ -51,7 +51,7 @@ public class SingleSignOnInterceptor implements AsyncHandlerInterceptor {
_logger.trace("Single Sign On Interceptor"); _logger.trace("Single Sign On Interceptor");
AuthorizationUtils.authenticateWithCookie( AuthorizationUtils.authenticateWithCookie(
request,authJwtService,sessionManager); request,authTokenService,sessionManager);
if(AuthorizationUtils.isNotAuthenticated()){ if(AuthorizationUtils.isNotAuthenticated()){
String loginUrl = applicationConfig.getFrontendUri() + "/#/passport/login?redirect_uri=%s"; String loginUrl = applicationConfig.getFrontendUri() + "/#/passport/login?redirect_uri=%s";

View File

@ -55,7 +55,7 @@ maxkey.app.issuer =CN=ConSec,CN=COM,CN=SH
maxkey.session.timeout =${SERVER_SESSION_TIMEOUT:1800} maxkey.session.timeout =${SERVER_SESSION_TIMEOUT:1800}
maxkey.auth.jwt.issuer =${maxkey.server.uri} maxkey.auth.jwt.issuer =${maxkey.server.uri}
maxkey.auth.jwt.expire =600 maxkey.auth.jwt.expires =60
maxkey.auth.jwt.secret =7heM-14BtxjyKPuH3ITIm7q2-ps5MuBirWCsrrdbzzSAOuSPrbQYiaJ54AeA0uH2XdkYy3hHAkTFIsieGkyqxOJZ_dQzrCbaYISH9rhUZAKYx8tUY0wkE4ArOC6LqHDJarR6UIcMsARakK9U4dhoOPO1cj74XytemI-w6ACYfzRUn_Rn4e-CQMcnD1C56oNEukwalf06xVgXl41h6K8IBEzLVod58y_VfvFn-NGWpNG0fy_Qxng6dg8Dgva2DobvzMN2eejHGLGB-x809MvC4zbG7CKNVlcrzMYDt2Gt2sOVDrt2l9YqJNfgaLFjrOEVw5cuXemGkX1MvHj6TAsbLg maxkey.auth.jwt.secret =7heM-14BtxjyKPuH3ITIm7q2-ps5MuBirWCsrrdbzzSAOuSPrbQYiaJ54AeA0uH2XdkYy3hHAkTFIsieGkyqxOJZ_dQzrCbaYISH9rhUZAKYx8tUY0wkE4ArOC6LqHDJarR6UIcMsARakK9U4dhoOPO1cj74XytemI-w6ACYfzRUn_Rn4e-CQMcnD1C56oNEukwalf06xVgXl41h6K8IBEzLVod58y_VfvFn-NGWpNG0fy_Qxng6dg8Dgva2DobvzMN2eejHGLGB-x809MvC4zbG7CKNVlcrzMYDt2Gt2sOVDrt2l9YqJNfgaLFjrOEVw5cuXemGkX1MvHj6TAsbLg
maxkey.auth.jwt.refresh.secret =7heM-14BtxjyKPuH3ITIm7q2-ps5MuBirWCsrrdbzzSAOuSPrbQYiaJ54AeA0uH2XdkYy3hHAkTFIsieGkyqxOJZ_dQzrCbaYISH9rhUZAKYx8tUY0wkE4ArOC6LqHDJarR6UIcMsARakK9U4dhoOPO1cj74XytemI-w6ACYfzRUn_Rn4e-CQMcnD1C56oNEukwalf06xVgXl41h6K8IBEzLVod58y_VfvFn-NGWpNG0fy_Qxng6dg8Dgva2DobvzMN2eejHGLGB-x809MvC4zbG7CKNVlcrzMYDt2Gt2sOVDrt2l9YqJNfgaLFjrOEVw5cuXemGkX1MvHj6TAsbLg maxkey.auth.jwt.refresh.secret =7heM-14BtxjyKPuH3ITIm7q2-ps5MuBirWCsrrdbzzSAOuSPrbQYiaJ54AeA0uH2XdkYy3hHAkTFIsieGkyqxOJZ_dQzrCbaYISH9rhUZAKYx8tUY0wkE4ArOC6LqHDJarR6UIcMsARakK9U4dhoOPO1cj74XytemI-w6ACYfzRUn_Rn4e-CQMcnD1C56oNEukwalf06xVgXl41h6K8IBEzLVod58y_VfvFn-NGWpNG0fy_Qxng6dg8Dgva2DobvzMN2eejHGLGB-x809MvC4zbG7CKNVlcrzMYDt2Gt2sOVDrt2l9YqJNfgaLFjrOEVw5cuXemGkX1MvHj6TAsbLg
############################################################################ ############################################################################

View File

@ -51,7 +51,7 @@ maxkey.app.issuer =CN=ConSec,CN=COM,CN=SH
maxkey.session.timeout =${SERVER_SESSION_TIMEOUT:1800} maxkey.session.timeout =${SERVER_SESSION_TIMEOUT:1800}
maxkey.auth.jwt.issuer =${maxkey.server.uri} maxkey.auth.jwt.issuer =${maxkey.server.uri}
maxkey.auth.jwt.expire =600 maxkey.auth.jwt.expires =600
maxkey.auth.jwt.secret =7heM-14BtxjyKPuH3ITIm7q2-ps5MuBirWCsrrdbzzSAOuSPrbQYiaJ54AeA0uH2XdkYy3hHAkTFIsieGkyqxOJZ_dQzrCbaYISH9rhUZAKYx8tUY0wkE4ArOC6LqHDJarR6UIcMsARakK9U4dhoOPO1cj74XytemI-w6ACYfzRUn_Rn4e-CQMcnD1C56oNEukwalf06xVgXl41h6K8IBEzLVod58y_VfvFn-NGWpNG0fy_Qxng6dg8Dgva2DobvzMN2eejHGLGB-x809MvC4zbG7CKNVlcrzMYDt2Gt2sOVDrt2l9YqJNfgaLFjrOEVw5cuXemGkX1MvHj6TAsbLg maxkey.auth.jwt.secret =7heM-14BtxjyKPuH3ITIm7q2-ps5MuBirWCsrrdbzzSAOuSPrbQYiaJ54AeA0uH2XdkYy3hHAkTFIsieGkyqxOJZ_dQzrCbaYISH9rhUZAKYx8tUY0wkE4ArOC6LqHDJarR6UIcMsARakK9U4dhoOPO1cj74XytemI-w6ACYfzRUn_Rn4e-CQMcnD1C56oNEukwalf06xVgXl41h6K8IBEzLVod58y_VfvFn-NGWpNG0fy_Qxng6dg8Dgva2DobvzMN2eejHGLGB-x809MvC4zbG7CKNVlcrzMYDt2Gt2sOVDrt2l9YqJNfgaLFjrOEVw5cuXemGkX1MvHj6TAsbLg
maxkey.auth.jwt.refresh.secret =7heM-14BtxjyKPuH3ITIm7q2-ps5MuBirWCsrrdbzzSAOuSPrbQYiaJ54AeA0uH2XdkYy3hHAkTFIsieGkyqxOJZ_dQzrCbaYISH9rhUZAKYx8tUY0wkE4ArOC6LqHDJarR6UIcMsARakK9U4dhoOPO1cj74XytemI-w6ACYfzRUn_Rn4e-CQMcnD1C56oNEukwalf06xVgXl41h6K8IBEzLVod58y_VfvFn-NGWpNG0fy_Qxng6dg8Dgva2DobvzMN2eejHGLGB-x809MvC4zbG7CKNVlcrzMYDt2Gt2sOVDrt2l9YqJNfgaLFjrOEVw5cuXemGkX1MvHj6TAsbLg maxkey.auth.jwt.refresh.secret =7heM-14BtxjyKPuH3ITIm7q2-ps5MuBirWCsrrdbzzSAOuSPrbQYiaJ54AeA0uH2XdkYy3hHAkTFIsieGkyqxOJZ_dQzrCbaYISH9rhUZAKYx8tUY0wkE4ArOC6LqHDJarR6UIcMsARakK9U4dhoOPO1cj74XytemI-w6ACYfzRUn_Rn4e-CQMcnD1C56oNEukwalf06xVgXl41h6K8IBEzLVod58y_VfvFn-NGWpNG0fy_Qxng6dg8Dgva2DobvzMN2eejHGLGB-x809MvC4zbG7CKNVlcrzMYDt2Gt2sOVDrt2l9YqJNfgaLFjrOEVw5cuXemGkX1MvHj6TAsbLg
############################################################################ ############################################################################

View File

@ -37,7 +37,7 @@ public class MaxKeyMgtConfig implements InitializingBean {
private static final Logger _logger = LoggerFactory.getLogger(MaxKeyMgtConfig.class); private static final Logger _logger = LoggerFactory.getLogger(MaxKeyMgtConfig.class);
//authenticationRealm for MaxKeyMgtApplication //authenticationRealm for MaxKeyMgtApplication
@Bean(name = "authenticationRealm") @Bean
public JdbcAuthenticationRealm authenticationRealm( public JdbcAuthenticationRealm authenticationRealm(
PasswordEncoder passwordEncoder, PasswordEncoder passwordEncoder,
PasswordPolicyValidator passwordPolicyValidator, PasswordPolicyValidator passwordPolicyValidator,
@ -58,7 +58,7 @@ public class MaxKeyMgtConfig implements InitializingBean {
return authenticationRealm; return authenticationRealm;
} }
@Bean(name = "timeBasedOtpAuthn") @Bean
public AbstractOtpAuthn timeBasedOtpAuthn() { public AbstractOtpAuthn timeBasedOtpAuthn() {
AbstractOtpAuthn tfaOtpAuthn = new TimeBasedOtpAuthn(); AbstractOtpAuthn tfaOtpAuthn = new TimeBasedOtpAuthn();
_logger.debug("TimeBasedOtpAuthn inited."); _logger.debug("TimeBasedOtpAuthn inited.");

View File

@ -46,8 +46,8 @@ import org.springframework.security.crypto.password.PasswordEncoder;
public class Oauth20ClientAutoConfiguration implements InitializingBean { public class Oauth20ClientAutoConfiguration implements InitializingBean {
private static final Logger _logger = LoggerFactory.getLogger(Oauth20ClientAutoConfiguration.class); private static final Logger _logger = LoggerFactory.getLogger(Oauth20ClientAutoConfiguration.class);
@Bean(name = "oauth20JdbcClientDetailsService") @Bean
public JdbcClientDetailsService jdbcClientDetailsService( public JdbcClientDetailsService oauth20JdbcClientDetailsService(
DataSource dataSource,PasswordEncoder passwordReciprocal) { DataSource dataSource,PasswordEncoder passwordReciprocal) {
JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource); JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
clientDetailsService.setPasswordEncoder(passwordReciprocal); clientDetailsService.setPasswordEncoder(passwordReciprocal);
@ -60,7 +60,7 @@ public class Oauth20ClientAutoConfiguration implements InitializingBean {
* @param persistence int * @param persistence int
* @return oauth20TokenStore * @return oauth20TokenStore
*/ */
@Bean(name = "oauth20TokenStore") @Bean
public TokenStore oauth20TokenStore( public TokenStore oauth20TokenStore(
@Value("${maxkey.server.persistence}") int persistence, @Value("${maxkey.server.persistence}") int persistence,
JdbcTemplate jdbcTemplate, JdbcTemplate jdbcTemplate,
@ -81,8 +81,8 @@ public class Oauth20ClientAutoConfiguration implements InitializingBean {
* clientDetailsUserDetailsService. * clientDetailsUserDetailsService.
* @return oauth20TokenServices * @return oauth20TokenServices
*/ */
@Bean(name = "oauth20TokenServices") @Bean
public DefaultTokenServices defaultTokenServices( public DefaultTokenServices oauth20TokenServices(
JdbcClientDetailsService oauth20JdbcClientDetailsService, JdbcClientDetailsService oauth20JdbcClientDetailsService,
TokenStore oauth20TokenStore) { TokenStore oauth20TokenStore) {
DefaultTokenServices tokenServices = new DefaultTokenServices(); DefaultTokenServices tokenServices = new DefaultTokenServices();
@ -96,7 +96,7 @@ public class Oauth20ClientAutoConfiguration implements InitializingBean {
* ProviderManager. * ProviderManager.
* @return oauth20ClientAuthenticationManager * @return oauth20ClientAuthenticationManager
*/ */
@Bean(name = "oauth20ClientAuthenticationManager") @Bean
public ProviderManager oauth20ClientAuthenticationManager( public ProviderManager oauth20ClientAuthenticationManager(
JdbcClientDetailsService oauth20JdbcClientDetailsService, JdbcClientDetailsService oauth20JdbcClientDetailsService,
PasswordEncoder passwordReciprocal PasswordEncoder passwordReciprocal

View File

@ -21,7 +21,6 @@ import org.maxkey.entity.UserInfo;
import org.maxkey.password.onetimepwd.AbstractOtpAuthn; import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
import org.maxkey.persistence.service.UserInfoService; import org.maxkey.persistence.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
@ -36,11 +35,9 @@ import io.swagger.v3.oas.annotations.tags.Tag;
public class RestTimeBasedOtpController { public class RestTimeBasedOtpController {
@Autowired @Autowired
@Qualifier("timeBasedOtpAuthn")
protected AbstractOtpAuthn timeBasedOtpAuthn; protected AbstractOtpAuthn timeBasedOtpAuthn;
@Autowired @Autowired
@Qualifier("userInfoService")
private UserInfoService userInfoService; private UserInfoService userInfoService;
@Operation(summary = "基于时间令牌验证 API文档模块", description = "传递参数username和token",method="GET") @Operation(summary = "基于时间令牌验证 API文档模块", description = "传递参数username和token",method="GET")

View File

@ -63,8 +63,7 @@ public class SAML20DetailsController extends BaseAppContorller {
final static Logger _logger = LoggerFactory.getLogger(SAML20DetailsController.class); final static Logger _logger = LoggerFactory.getLogger(SAML20DetailsController.class);
@Autowired @Autowired
@Qualifier("keyStoreLoader") private KeyStoreLoader keyStoreLoader;
private KeyStoreLoader idpKeyStoreLoader;
@Autowired @Autowired
AppsSaml20DetailsService saml20DetailsService; AppsSaml20DetailsService saml20DetailsService;
@ -184,7 +183,7 @@ public class SAML20DetailsController extends BaseAppContorller {
samlDetails.setCertIssuer(X509CertUtils.getCommonName(samlDetails.getTrustCert().getIssuerX500Principal())); samlDetails.setCertIssuer(X509CertUtils.getCommonName(samlDetails.getTrustCert().getIssuerX500Principal()));
KeyStore keyStore = KeyStoreUtil.clone(idpKeyStoreLoader.getKeyStore(),idpKeyStoreLoader.getKeystorePassword()); KeyStore keyStore = KeyStoreUtil.clone(keyStoreLoader.getKeyStore(),keyStoreLoader.getKeystorePassword());
KeyStore trustKeyStore = null; KeyStore trustKeyStore = null;
if (!samlDetails.getEntityId().equals("")) { if (!samlDetails.getEntityId().equals("")) {
@ -193,7 +192,7 @@ public class SAML20DetailsController extends BaseAppContorller {
trustKeyStore = KeyStoreUtil.importTrustCertificate(keyStore,samlDetails.getTrustCert()); trustKeyStore = KeyStoreUtil.importTrustCertificate(keyStore,samlDetails.getTrustCert());
} }
byte[] keyStoreByte = KeyStoreUtil.keyStore2Bytes(trustKeyStore,idpKeyStoreLoader.getKeystorePassword()); byte[] keyStoreByte = KeyStoreUtil.keyStore2Bytes(trustKeyStore,keyStoreLoader.getKeystorePassword());
// store KeyStore content // store KeyStore content
samlDetails.setKeyStore(keyStoreByte); samlDetails.setKeyStore(keyStoreByte);

View File

@ -26,7 +26,6 @@ import org.maxkey.persistence.service.ReportService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -41,7 +40,6 @@ public class DashboardController {
private static Logger _logger = LoggerFactory.getLogger(DashboardController.class); private static Logger _logger = LoggerFactory.getLogger(DashboardController.class);
@Autowired @Autowired
@Qualifier("reportService")
ReportService reportService; ReportService reportService;
@RequestMapping(value={"/dashboard"}, produces = {MediaType.APPLICATION_JSON_VALUE}) @RequestMapping(value={"/dashboard"}, produces = {MediaType.APPLICATION_JSON_VALUE})

View File

@ -22,7 +22,7 @@ import java.util.HashMap;
import org.maxkey.authn.AbstractAuthenticationProvider; import org.maxkey.authn.AbstractAuthenticationProvider;
import org.maxkey.authn.LoginCredential; import org.maxkey.authn.LoginCredential;
import org.maxkey.authn.jwt.AuthJwt; import org.maxkey.authn.jwt.AuthJwt;
import org.maxkey.authn.jwt.AuthJwtService; import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.configuration.ApplicationConfig; import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.entity.Institutions; import org.maxkey.entity.Institutions;
import org.maxkey.entity.Message; import org.maxkey.entity.Message;
@ -50,13 +50,12 @@ public class LoginEntryPoint {
private static Logger _logger = LoggerFactory.getLogger(LoginEntryPoint.class); private static Logger _logger = LoggerFactory.getLogger(LoginEntryPoint.class);
@Autowired @Autowired
AuthJwtService authJwtService; AuthTokenService authTokenService;
@Autowired @Autowired
protected ApplicationConfig applicationConfig; protected ApplicationConfig applicationConfig;
@Autowired @Autowired
@Qualifier("authenticationProvider")
AbstractAuthenticationProvider authenticationProvider ; AbstractAuthenticationProvider authenticationProvider ;
/** /**
@ -77,15 +76,15 @@ public class LoginEntryPoint {
model.put("captcha", inst.getCaptchaSupport()); model.put("captcha", inst.getCaptchaSupport());
model.put("captchaType", inst.getCaptchaType()); model.put("captchaType", inst.getCaptchaType());
} }
model.put("state", authJwtService.genJwt()); model.put("state", authTokenService.genRandomJwt());
return new Message<HashMap<String , Object>>(model).buildResponse(); return new Message<HashMap<String , Object>>(model).buildResponse();
} }
@RequestMapping(value={"/signin"}, produces = {MediaType.APPLICATION_JSON_VALUE}) @RequestMapping(value={"/signin"}, produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<?> signin( @RequestBody LoginCredential loginCredential) { public ResponseEntity<?> signin( @RequestBody LoginCredential loginCredential) {
if(authJwtService.validateJwtToken(loginCredential.getState())){ if(authTokenService.validateJwtToken(loginCredential.getState())){
Authentication authentication = authenticationProvider.authenticate(loginCredential); Authentication authentication = authenticationProvider.authenticate(loginCredential);
AuthJwt authJwt = authJwtService.genAuthJwt(authentication); AuthJwt authJwt = authTokenService.genAuthJwt(authentication);
return new Message<AuthJwt>(authJwt).buildResponse(); return new Message<AuthJwt>(authJwt).buildResponse();
} }
return new Message<AuthJwt>(Message.FAIL).buildResponse(); return new Message<AuthJwt>(Message.FAIL).buildResponse();

View File

@ -29,7 +29,6 @@ import org.maxkey.web.message.MessageType;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@ -44,7 +43,6 @@ public class UserAdjointController {
final static Logger _logger = LoggerFactory.getLogger(UserAdjointController.class); final static Logger _logger = LoggerFactory.getLogger(UserAdjointController.class);
@Autowired @Autowired
@Qualifier("userInfoAdjointService")
UserInfoAdjointService userInfoAdjointService; UserInfoAdjointService userInfoAdjointService;

View File

@ -52,7 +52,6 @@ public class ConnectorHistoryController {
final static Logger _logger = LoggerFactory.getLogger(ConnectorHistoryController.class); final static Logger _logger = LoggerFactory.getLogger(ConnectorHistoryController.class);
@Autowired @Autowired
@Qualifier("historyConnectorService")
HistoryConnectorService historyConnectorService; HistoryConnectorService historyConnectorService;
/** /**

View File

@ -29,7 +29,6 @@ import org.maxkey.util.DateUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.propertyeditors.CustomDateEditor; import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -52,7 +51,6 @@ public class SynchronizerHistoryController {
final static Logger _logger = LoggerFactory.getLogger(SynchronizerHistoryController.class); final static Logger _logger = LoggerFactory.getLogger(SynchronizerHistoryController.class);
@Autowired @Autowired
@Qualifier("historySynchronizerService")
HistorySynchronizerService historySynchronizerService; HistorySynchronizerService historySynchronizerService;
/** /**

View File

@ -30,7 +30,6 @@ import org.maxkey.util.AuthorizationHeaderUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.servlet.AsyncHandlerInterceptor; import org.springframework.web.servlet.AsyncHandlerInterceptor;
@ -44,12 +43,10 @@ public class Oauth20ApiPermissionAdapter implements AsyncHandlerInterceptor {
private static final Logger _logger = LoggerFactory.getLogger(Oauth20ApiPermissionAdapter.class); private static final Logger _logger = LoggerFactory.getLogger(Oauth20ApiPermissionAdapter.class);
@Autowired @Autowired
@Qualifier("passwordReciprocal")
protected PasswordReciprocal passwordReciprocal; protected PasswordReciprocal passwordReciprocal;
@Autowired @Autowired
@Qualifier("oauth20TokenServices") private DefaultTokenServices oauth20TokenServices;
private DefaultTokenServices oauth20tokenServices;
static ConcurrentHashMap<String ,String >navigationsMap=null; static ConcurrentHashMap<String ,String >navigationsMap=null;
@ -64,7 +61,7 @@ public class Oauth20ApiPermissionAdapter implements AsyncHandlerInterceptor {
String authorization = request.getHeader(AuthorizationHeaderUtils.HEADER_Authorization); String authorization = request.getHeader(AuthorizationHeaderUtils.HEADER_Authorization);
String accessToken = AuthorizationHeaderUtils.resolveBearer(authorization); String accessToken = AuthorizationHeaderUtils.resolveBearer(authorization);
OAuth2Authentication authentication = oauth20tokenServices.loadAuthentication(accessToken); OAuth2Authentication authentication = oauth20TokenServices.loadAuthentication(accessToken);
//判断应用的accessToken信息 //判断应用的accessToken信息
if(authentication != null ){ if(authentication != null ){

View File

@ -31,7 +31,6 @@ import org.maxkey.util.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.ProviderManager; import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
@ -48,12 +47,10 @@ public class RestApiPermissionAdapter implements AsyncHandlerInterceptor {
private static final Logger _logger = LoggerFactory.getLogger(RestApiPermissionAdapter.class); private static final Logger _logger = LoggerFactory.getLogger(RestApiPermissionAdapter.class);
@Autowired @Autowired
@Qualifier("oauth20TokenServices")
DefaultTokenServices oauth20TokenServices; DefaultTokenServices oauth20TokenServices;
@Autowired @Autowired
@Qualifier("oauth20ClientAuthenticationManager") ProviderManager oauth20ClientAuthenticationManager;
ProviderManager authenticationManager;
static ConcurrentHashMap<String ,String >navigationsMap=null; static ConcurrentHashMap<String ,String >navigationsMap=null;
@ -79,7 +76,7 @@ public class RestApiPermissionAdapter implements AsyncHandlerInterceptor {
new UsernamePasswordAuthenticationToken( new UsernamePasswordAuthenticationToken(
headerCredential.getUsername(), headerCredential.getUsername(),
headerCredential.getCredential()); headerCredential.getCredential());
authenticationToken= (UsernamePasswordAuthenticationToken)authenticationManager.authenticate(authRequest); authenticationToken= (UsernamePasswordAuthenticationToken)oauth20ClientAuthenticationManager.authenticate(authRequest);
} }
}else { }else {
_logger.trace("Authentication bearer " + headerCredential.getCredential()); _logger.trace("Authentication bearer " + headerCredential.getCredential());

View File

@ -30,7 +30,6 @@ import org.maxkey.util.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -46,7 +45,6 @@ public class RolePrivilegesController {
final static Logger _logger = LoggerFactory.getLogger(RolePrivilegesController.class); final static Logger _logger = LoggerFactory.getLogger(RolePrivilegesController.class);
@Autowired @Autowired
@Qualifier("rolesService")
RolesService rolesService; RolesService rolesService;
@ResponseBody @ResponseBody

View File

@ -40,9 +40,11 @@ maxkey.server.persistence =0
#identity none, Kafka ,RocketMQ #identity none, Kafka ,RocketMQ
maxkey.server.message.queue =${SERVER_MESSAGE_QUEUE:none} maxkey.server.message.queue =${SERVER_MESSAGE_QUEUE:none}
maxkey.auth.jwt.expire =86400 maxkey.session.timeout =${SERVER_SESSION_TIMEOUT:1800}
maxkey.auth.jwt.expires =86400
maxkey.auth.jwt.issuer =${maxkey.server.uri} maxkey.auth.jwt.issuer =${maxkey.server.uri}
maxkey.auth.jwt.secret =7heM-14BtxjyKPuH3ITIm7q2-ps5MuBirWCsrrdbzzSAOuSPrbQYiaJ54AeA0uH2XdkYy3hHAkTFIsieGkyqxOJZ_dQzrCbaYISH9rhUZAKYx8tUY0wkE4ArOC6LqHDJarR6UIcMsARakK9U4dhoOPO1cj74XytemI-w6ACYfzRUn_Rn4e-CQMcnD1C56oNEukwalf06xVgXl41h6K8IBEzLVod58y_VfvFn-NGWpNG0fy_Qxng6dg8Dgva2DobvzMN2eejHGLGB-x809MvC4zbG7CKNVlcrzMYDt2Gt2sOVDrt2l9YqJNfgaLFjrOEVw5cuXemGkX1MvHj6TAsbLg maxkey.auth.jwt.secret =7heM-14BtxjyKPuH3ITIm7q2-ps5MuBirWCsrrdbzzSAOuSPrbQYiaJ54AeA0uH2XdkYy3hHAkTFIsieGkyqxOJZ_dQzrCbaYISH9rhUZAKYx8tUY0wkE4ArOC6LqHDJarR6UIcMsARakK9U4dhoOPO1cj74XytemI-w6ACYfzRUn_Rn4e-CQMcnD1C56oNEukwalf06xVgXl41h6K8IBEzLVod58y_VfvFn-NGWpNG0fy_Qxng6dg8Dgva2DobvzMN2eejHGLGB-x809MvC4zbG7CKNVlcrzMYDt2Gt2sOVDrt2l9YqJNfgaLFjrOEVw5cuXemGkX1MvHj6TAsbLg
maxkey.auth.jwt.refresh.secret =7heM-14BtxjyKPuH3ITIm7q2-ps5MuBirWCsrrdbzzSAOuSPrbQYiaJ54AeA0uH2XdkYy3hHAkTFIsieGkyqxOJZ_dQzrCbaYISH9rhUZAKYx8tUY0wkE4ArOC6LqHDJarR6UIcMsARakK9U4dhoOPO1cj74XytemI-w6ACYfzRUn_Rn4e-CQMcnD1C56oNEukwalf06xVgXl41h6K8IBEzLVod58y_VfvFn-NGWpNG0fy_Qxng6dg8Dgva2DobvzMN2eejHGLGB-x809MvC4zbG7CKNVlcrzMYDt2Gt2sOVDrt2l9YqJNfgaLFjrOEVw5cuXemGkX1MvHj6TAsbLg
############################################################################ ############################################################################
#Login configuration # #Login configuration #
############################################################################ ############################################################################