diff --git a/README.md b/README.md index a1d30c5d..c731df8e 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ v.3.x 为springboot 3.x版本,使用jdk17版本 * springboot-starter | Springboot领域驱动框架 * springboot-starter-data-fast | 快速数据呈现框架 -* springboot-starter-security-jwt | security&jwt权限框架 +* springboot-starter-security | security&jwt权限框架 ## SpringBoot DDD Architecture | SpringBoot DDD 框架图 @@ -44,7 +44,7 @@ v.3.x 为springboot 3.x版本,使用jdk17版本 com.codingapi.springboot - springboot-starter-security-jwt + springboot-starter-security ${last.version} diff --git a/docs/wiki/springboot-starter-security-jwt.md b/docs/wiki/springboot-starter-security.md similarity index 86% rename from docs/wiki/springboot-starter-security-jwt.md rename to docs/wiki/springboot-starter-security.md index 2cad32e0..9f7e7481 100644 --- a/docs/wiki/springboot-starter-security-jwt.md +++ b/docs/wiki/springboot-starter-security.md @@ -1,18 +1,28 @@ -springboot-starter-security-jwt 功能介绍 +springboot-starter-security 功能介绍 + +支持无状态的JWT和有状态的redis两种不同的token机制 配置文件,默认参数即说明 ```properties +# JWT开关 +codingapi.security.jwt.enable=true # JWT密钥 需大于32位的字符串 -codingapi.security.jwt-secret=codingapi.security.jwt.secretkey +codingapi.security.jwt.secret-key=codingapi.security.jwt.secretkey + +# JWT 有效时间(毫秒) 15分钟有效期 1000*60*15=900000 +codingapi.security.jwt.valid-time=900000 +# JWT 更换令牌时间(毫秒) 10分钟后更换令牌 1000*60*10=600000 +codingapi.security.jwt.rest-time=600000 + # JWT AES密钥 codingapi.security.ase-key=QUNEWCQlXiYqJCNYQ1phc0FDRFgkJV4mKiQjWENaYXM= # JWT AES IV codingapi.security.aes-iv=QUNYRkdIQEVEUyNYQ1phcw== -# JWT 有效时间(毫秒) 15分钟有效期 1000*60*15=900000 -codingapi.security.jwt-time=900000 -# JWT 更换令牌时间(毫秒) 10分钟后更换令牌 1000*60*10=600000 -codingapi.security.jwt-rest-time=600000 +# Redis开关 +#codingapi.security.redis.enable=true +#spring.data.redis.host=localhost +#spring.data.redis.port=6379 # Security 配置 请求权限拦截地址 codingapi.security.authenticated-urls=/api/** diff --git a/pom.xml b/pom.xml index 0b05f8e4..64d1be66 100644 --- a/pom.xml +++ b/pom.xml @@ -6,13 +6,13 @@ org.springframework.boot spring-boot-starter-parent - 3.1.8 + 3.2.4 com.codingapi.springboot springboot-parent - 3.1.10 + 3.2.0 https://github.com/codingapi/springboot-framewrok springboot-parent @@ -32,7 +32,7 @@ 3.1.0 ${project.version} 2.0.42 - 0.12.3 + 0.12.5 2.15.0 1.8.1 1.11.0 @@ -145,7 +145,7 @@ com.codingapi.springboot - springboot-starter-security-jwt + springboot-starter-security ${codingapi.framework.version} @@ -251,7 +251,7 @@ springboot-starter - springboot-starter-security-jwt + springboot-starter-security springboot-starter-data-fast @@ -262,7 +262,7 @@ springboot-starter - springboot-starter-security-jwt + springboot-starter-security springboot-starter-data-fast @@ -311,7 +311,7 @@ springboot-starter - springboot-starter-security-jwt + springboot-starter-security springboot-starter-data-fast diff --git a/springboot-starter-data-fast/pom.xml b/springboot-starter-data-fast/pom.xml index 1026a173..0f757bed 100644 --- a/springboot-starter-data-fast/pom.xml +++ b/springboot-starter-data-fast/pom.xml @@ -5,7 +5,7 @@ springboot-parent com.codingapi.springboot - 3.1.10 + 3.2.0 4.0.0 diff --git a/springboot-starter-security-jwt/src/main/resources/META-INF/spring.factories b/springboot-starter-security-jwt/src/main/resources/META-INF/spring.factories deleted file mode 100644 index b7882c59..00000000 --- a/springboot-starter-security-jwt/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,4 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -com.codingapi.springboot.security.configurer.WebSecurityConfigurer,\ -com.codingapi.springboot.security.crypto.MyCryptoConfiguration,\ -com.codingapi.springboot.security.AutoConfiguration \ No newline at end of file diff --git a/springboot-starter-security-jwt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/springboot-starter-security-jwt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index 69b9af0d..00000000 --- a/springboot-starter-security-jwt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1,3 +0,0 @@ -com.codingapi.springboot.security.configurer.WebSecurityConfigurer -com.codingapi.springboot.security.crypto.MyCryptoConfiguration -com.codingapi.springboot.security.AutoConfiguration \ No newline at end of file diff --git a/springboot-starter-security-jwt/pom.xml b/springboot-starter-security/pom.xml similarity index 73% rename from springboot-starter-security-jwt/pom.xml rename to springboot-starter-security/pom.xml index 9fb6e94f..cd0e09e4 100644 --- a/springboot-starter-security-jwt/pom.xml +++ b/springboot-starter-security/pom.xml @@ -6,13 +6,13 @@ springboot-parent com.codingapi.springboot - 3.1.10 + 3.2.0 - springboot-starter-security-jwt + springboot-starter-security - springboot-starter-security-jwt - springboot-starter-security-jwt project for Spring Boot + springboot-starter-security + springboot-starter-security project for Spring Boot 17 @@ -30,19 +30,28 @@ spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-data-redis + provided + + io.jsonwebtoken jjwt-api + provided io.jsonwebtoken jjwt-impl + provided io.jsonwebtoken jjwt-jackson + provided diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/AutoConfiguration.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/AutoConfiguration.java similarity index 64% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/AutoConfiguration.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/AutoConfiguration.java index 35d4c1a6..b89cfe79 100644 --- a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/AutoConfiguration.java +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/AutoConfiguration.java @@ -4,9 +4,9 @@ import com.codingapi.springboot.security.controller.VersionController; import com.codingapi.springboot.security.dto.request.LoginRequest; import com.codingapi.springboot.security.filter.*; -import com.codingapi.springboot.security.jwt.Jwt; -import com.codingapi.springboot.security.jwt.Token; -import com.codingapi.springboot.security.properties.SecurityJwtProperties; +import com.codingapi.springboot.security.gateway.Token; +import com.codingapi.springboot.security.gateway.TokenGateway; +import com.codingapi.springboot.security.properties.CodingApiSecurityProperties; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -16,8 +16,10 @@ import org.springframework.core.env.Environment; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; @@ -60,23 +62,23 @@ public PasswordEncoder passwordEncoder() { @Bean @ConditionalOnMissingBean - public SecurityLoginHandler securityLoginHandler(){ - return new SecurityLoginHandler() { - @Override - public void preHandle(HttpServletRequest request, HttpServletResponse response, LoginRequest handler) throws Exception { + public SecurityLoginHandler securityLoginHandler() { + return new SecurityLoginHandler() { + @Override + public void preHandle(HttpServletRequest request, HttpServletResponse response, LoginRequest handler) throws Exception { - } + } - @Override - public void postHandle(HttpServletRequest request, HttpServletResponse response, LoginRequest handler, Token token) { + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, LoginRequest handler, Token token) { - } - }; + } + }; } @Bean @ConditionalOnMissingBean - public AuthenticationTokenFilter authenticationTokenFilter(){ + public AuthenticationTokenFilter authenticationTokenFilter() { return (request, response, chain) -> { }; @@ -85,22 +87,29 @@ public AuthenticationTokenFilter authenticationTokenFilter(){ @Bean @ConditionalOnMissingBean - public SecurityFilterChain filterChain(HttpSecurity security, Jwt jwt,SecurityLoginHandler loginHandler, - SecurityJwtProperties properties,AuthenticationTokenFilter authenticationTokenFilter) throws Exception { + public SecurityFilterChain filterChain(HttpSecurity security, TokenGateway tokenGateway, SecurityLoginHandler loginHandler, + CodingApiSecurityProperties properties, AuthenticationTokenFilter authenticationTokenFilter) throws Exception { //disable basic auth - security.httpBasic().disable(); + security.httpBasic(AbstractHttpConfigurer::disable); //before add addCorsMappings to enable cors. - security.cors(); - if(properties.isDisableCsrf() ){ - security.csrf().disable(); - } - security.apply(new HttpSecurityConfigurer(jwt,loginHandler,properties,authenticationTokenFilter)); - security - .exceptionHandling() - .authenticationEntryPoint(new MyUnAuthenticationEntryPoint()) - .accessDeniedHandler(new MyAccessDeniedHandler()) - .and() + security.cors(httpSecurityCorsConfigurer -> { + if (properties.isDisableCors()) { + httpSecurityCorsConfigurer.disable(); + } + }); + + security.csrf(httpSecurityCsrfConfigurer -> { + if (properties.isDisableCsrf()) { + httpSecurityCsrfConfigurer.disable(); + } + }); + + + security.with(new HttpSecurityConfigurer(tokenGateway, loginHandler, properties, authenticationTokenFilter), Customizer.withDefaults()); + security.exceptionHandling(httpSecurityExceptionHandlingConfigurer -> + httpSecurityExceptionHandlingConfigurer.authenticationEntryPoint(new MyUnAuthenticationEntryPoint()) + .accessDeniedHandler(new MyAccessDeniedHandler())) .authorizeHttpRequests( registry -> { registry.requestMatchers(properties.getIgnoreUrls()).permitAll() @@ -109,15 +118,13 @@ public SecurityFilterChain filterChain(HttpSecurity security, Jwt jwt,SecurityLo } ) //default login url :/login - .formLogin() - .loginProcessingUrl(properties.getLoginProcessingUrl()) - .permitAll() - .and() + .formLogin(httpSecurityFormLoginConfigurer -> + httpSecurityFormLoginConfigurer.loginPage(properties.getLoginProcessingUrl()) + ) //default logout url :/logout - .logout() - .logoutUrl(properties.getLogoutUrl()) - .addLogoutHandler(new MyLogoutHandler()) - .logoutSuccessHandler(new MyLogoutSuccessHandler()); + .logout(httpSecurityLogoutConfigurer -> httpSecurityLogoutConfigurer.logoutUrl(properties.getLogoutUrl()) + .addLogoutHandler(new MyLogoutHandler()) + .logoutSuccessHandler(new MyLogoutSuccessHandler())); return security.build(); } @@ -135,18 +142,11 @@ public AuthenticationProvider authenticationProvider(UserDetailsService userDeta @Bean - @ConditionalOnMissingBean - public Jwt jwt(SecurityJwtProperties properties) { - return new Jwt(properties.getJwtSecretKey(), properties.getJwtTime(), properties.getJwtRestTime()); - } - - - @Bean - public WebMvcConfigurer corsConfigurer(SecurityJwtProperties securityJwtProperties) { + public WebMvcConfigurer corsConfigurer(CodingApiSecurityProperties securityJwtProperties) { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { - if(securityJwtProperties.isDisableCors()) { + if (securityJwtProperties.isDisableCors()) { registry.addMapping("/**") .allowedHeaders("*") .allowedMethods("*") @@ -163,14 +163,14 @@ public void addCorsMappings(CorsRegistry registry) { @Bean @ConfigurationProperties(prefix = "codingapi.security") - public SecurityJwtProperties securityJwtProperties() { - return new SecurityJwtProperties(); + public CodingApiSecurityProperties codingApiSecurityProperties() { + return new CodingApiSecurityProperties(); } @Bean @ConditionalOnMissingBean - public VersionController versionController(Environment environment){ + public VersionController versionController(Environment environment) { return new VersionController(environment); } diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/configurer/HttpSecurityConfigurer.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/configurer/HttpSecurityConfigurer.java similarity index 53% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/configurer/HttpSecurityConfigurer.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/configurer/HttpSecurityConfigurer.java index c95ec34e..a1ca9ecc 100644 --- a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/configurer/HttpSecurityConfigurer.java +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/configurer/HttpSecurityConfigurer.java @@ -4,26 +4,27 @@ import com.codingapi.springboot.security.filter.MyAuthenticationFilter; import com.codingapi.springboot.security.filter.MyLoginFilter; import com.codingapi.springboot.security.filter.SecurityLoginHandler; -import com.codingapi.springboot.security.jwt.Jwt; -import com.codingapi.springboot.security.properties.SecurityJwtProperties; +import com.codingapi.springboot.security.gateway.TokenGateway; +import com.codingapi.springboot.security.properties.CodingApiSecurityProperties; import lombok.AllArgsConstructor; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.SecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.web.DefaultSecurityFilterChain; @AllArgsConstructor -public class HttpSecurityConfigurer extends AbstractHttpConfigurer { +public class HttpSecurityConfigurer extends SecurityConfigurerAdapter { - private final Jwt jwt; + private final TokenGateway tokenGateway; private final SecurityLoginHandler securityLoginHandler; - private final SecurityJwtProperties securityJwtProperties; + private final CodingApiSecurityProperties securityJwtProperties; private final AuthenticationTokenFilter authenticationTokenFilter; @Override public void configure(HttpSecurity security) throws Exception { AuthenticationManager manager = security.getSharedObject(AuthenticationManager.class); - security.addFilter(new MyLoginFilter(manager, jwt,securityLoginHandler, securityJwtProperties)); - security.addFilter(new MyAuthenticationFilter(manager,securityJwtProperties,jwt,authenticationTokenFilter)); + security.addFilter(new MyLoginFilter(manager, tokenGateway,securityLoginHandler, securityJwtProperties)); + security.addFilter(new MyAuthenticationFilter(manager, securityJwtProperties, tokenGateway, authenticationTokenFilter)); } } diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/configurer/WebSecurityConfigurer.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/configurer/WebSecurityConfigurer.java similarity index 80% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/configurer/WebSecurityConfigurer.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/configurer/WebSecurityConfigurer.java index 7e5f3e75..369ad328 100644 --- a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/configurer/WebSecurityConfigurer.java +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/configurer/WebSecurityConfigurer.java @@ -1,6 +1,6 @@ package com.codingapi.springboot.security.configurer; -import com.codingapi.springboot.security.properties.SecurityJwtProperties; +import com.codingapi.springboot.security.properties.CodingApiSecurityProperties; import lombok.AllArgsConstructor; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.WebSecurity; @@ -10,7 +10,7 @@ @AllArgsConstructor public class WebSecurityConfigurer implements WebSecurityCustomizer { - private final SecurityJwtProperties securityJwtProperties; + private final CodingApiSecurityProperties securityJwtProperties; @Override public void customize(WebSecurity web) { diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/controller/VersionController.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/controller/VersionController.java similarity index 100% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/controller/VersionController.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/controller/VersionController.java diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/crypto/MyAES.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/crypto/AESTools.java similarity index 84% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/crypto/MyAES.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/crypto/AESTools.java index b3536ca8..efe4a7a8 100644 --- a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/crypto/MyAES.java +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/crypto/AESTools.java @@ -6,20 +6,20 @@ import java.nio.charset.StandardCharsets; import java.util.Base64; -public class MyAES { +public class AESTools { - private final static MyAES instance = new MyAES(); + private final static AESTools instance = new AESTools(); private AES aes; - private MyAES() { + private AESTools() { } void init(AES aes) { this.aes = aes; } - public static MyAES getInstance() { + public static AESTools getInstance() { return instance; } diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/crypto/MyCryptoConfiguration.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/crypto/SecurityCryptoConfiguration.java similarity index 69% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/crypto/MyCryptoConfiguration.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/crypto/SecurityCryptoConfiguration.java index 0d4b2bd4..6820dc5c 100644 --- a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/crypto/MyCryptoConfiguration.java +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/crypto/SecurityCryptoConfiguration.java @@ -1,7 +1,7 @@ package com.codingapi.springboot.security.crypto; import com.codingapi.springboot.framework.crypto.AES; -import com.codingapi.springboot.security.properties.SecurityJwtProperties; +import com.codingapi.springboot.security.properties.CodingApiSecurityProperties; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -9,15 +9,14 @@ import java.util.Base64; @Configuration -public class MyCryptoConfiguration { +public class SecurityCryptoConfiguration { @Bean @ConditionalOnMissingBean - public AES aes(SecurityJwtProperties properties) throws Exception { + public AES aes(CodingApiSecurityProperties properties) throws Exception { AES aes = new AES(Base64.getDecoder().decode(properties.getAseKey().getBytes()), Base64.getDecoder().decode(properties.getAseIv())); - MyAES.getInstance().init(aes); + AESTools.getInstance().init(aes); return aes; } - } diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/dto/request/LoginRequest.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/dto/request/LoginRequest.java similarity index 100% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/dto/request/LoginRequest.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/dto/request/LoginRequest.java diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/dto/request/LoginRequestContext.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/dto/request/LoginRequestContext.java similarity index 100% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/dto/request/LoginRequestContext.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/dto/request/LoginRequestContext.java diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/dto/response/LoginResponse.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/dto/response/LoginResponse.java similarity index 100% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/dto/response/LoginResponse.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/dto/response/LoginResponse.java diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/exception/TokenExpiredException.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/exception/TokenExpiredException.java similarity index 100% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/exception/TokenExpiredException.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/exception/TokenExpiredException.java diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/AuthenticationTokenFilter.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/AuthenticationTokenFilter.java similarity index 100% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/AuthenticationTokenFilter.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/AuthenticationTokenFilter.java diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/MyAccessDeniedHandler.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/MyAccessDeniedHandler.java similarity index 100% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/MyAccessDeniedHandler.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/MyAccessDeniedHandler.java diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/MyAuthenticationFilter.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/MyAuthenticationFilter.java similarity index 75% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/MyAuthenticationFilter.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/MyAuthenticationFilter.java index e00964b3..c4305aaa 100644 --- a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/MyAuthenticationFilter.java +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/MyAuthenticationFilter.java @@ -3,9 +3,9 @@ import com.alibaba.fastjson.JSONObject; import com.codingapi.springboot.framework.dto.response.Response; import com.codingapi.springboot.security.exception.TokenExpiredException; -import com.codingapi.springboot.security.jwt.Jwt; -import com.codingapi.springboot.security.jwt.Token; -import com.codingapi.springboot.security.properties.SecurityJwtProperties; +import com.codingapi.springboot.security.gateway.Token; +import com.codingapi.springboot.security.gateway.TokenGateway; +import com.codingapi.springboot.security.properties.CodingApiSecurityProperties; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; @@ -26,16 +26,16 @@ public class MyAuthenticationFilter extends BasicAuthenticationFilter { private final static String TOKEN_KEY = "Authorization"; - private final Jwt jwt; + private final TokenGateway tokenGateway; - private final SecurityJwtProperties securityJwtProperties; + private final CodingApiSecurityProperties securityJwtProperties; private final AuthenticationTokenFilter authenticationTokenFilter; private final AntPathMatcher antPathMatcher = new AntPathMatcher(); - public MyAuthenticationFilter(AuthenticationManager manager, SecurityJwtProperties securityJwtProperties, Jwt jwt,AuthenticationTokenFilter authenticationTokenFilter) { + public MyAuthenticationFilter(AuthenticationManager manager, CodingApiSecurityProperties securityJwtProperties, TokenGateway tokenGateway, AuthenticationTokenFilter authenticationTokenFilter) { super(manager); - this.jwt = jwt; + this.tokenGateway = tokenGateway; this.securityJwtProperties = securityJwtProperties; this.authenticationTokenFilter = authenticationTokenFilter; } @@ -45,7 +45,7 @@ public MyAuthenticationFilter(AuthenticationManager manager, SecurityJwtProperti protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { log.debug("token authentication ~"); for (String antUrl : securityJwtProperties.getAuthenticatedUrls()) { - if(antPathMatcher.match(antUrl,request.getRequestURI())) { + if (antPathMatcher.match(antUrl, request.getRequestURI())) { String sign = request.getHeader(TOKEN_KEY); if (!StringUtils.hasLength(sign)) { @@ -53,9 +53,13 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse return; } - Token token = jwt.parser(sign); + Token token = tokenGateway.parser(sign); + if (token == null) { + writeResponse(response, Response.buildFailure("token.expire", "token expire.")); + return; + } if (token.canRestToken()) { - Token newSign = jwt.create(token.getUsername(), token.decodeIv(), token.getAuthorities(), token.getExtra()); + Token newSign = tokenGateway.create(token.getUsername(), token.decodeIv(), token.getAuthorities(), token.getExtra()); log.info("reset token "); response.setHeader(TOKEN_KEY, newSign.getToken()); } diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/MyLoginFilter.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/MyLoginFilter.java similarity index 88% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/MyLoginFilter.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/MyLoginFilter.java index eb7e02ab..962aca1c 100644 --- a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/MyLoginFilter.java +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/MyLoginFilter.java @@ -6,10 +6,10 @@ import com.codingapi.springboot.security.dto.request.LoginRequest; import com.codingapi.springboot.security.dto.request.LoginRequestContext; import com.codingapi.springboot.security.dto.response.LoginResponse; -import com.codingapi.springboot.security.jwt.Jwt; -import com.codingapi.springboot.security.jwt.Token; -import com.codingapi.springboot.security.jwt.TokenContext; -import com.codingapi.springboot.security.properties.SecurityJwtProperties; +import com.codingapi.springboot.security.gateway.TokenGateway; +import com.codingapi.springboot.security.gateway.Token; +import com.codingapi.springboot.security.gateway.TokenContext; +import com.codingapi.springboot.security.properties.CodingApiSecurityProperties; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; import org.springframework.security.authentication.AuthenticationManager; @@ -33,13 +33,13 @@ @Slf4j public class MyLoginFilter extends UsernamePasswordAuthenticationFilter { - private final Jwt jwt; + private final TokenGateway tokenGateway; private final SecurityLoginHandler loginHandler; - public MyLoginFilter(AuthenticationManager authenticationManager, Jwt jwt, SecurityLoginHandler loginHandler, SecurityJwtProperties securityJwtProperties) { + public MyLoginFilter(AuthenticationManager authenticationManager, TokenGateway tokenGateway, SecurityLoginHandler loginHandler, CodingApiSecurityProperties securityJwtProperties) { super(authenticationManager); - this.jwt = jwt; + this.tokenGateway = tokenGateway; this.loginHandler = loginHandler; this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(securityJwtProperties.getLoginProcessingUrl(), "POST")); } @@ -72,7 +72,7 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR User user = (User) authResult.getPrincipal(); LoginRequest loginRequest = LoginRequestContext.getInstance().get(); - Token token = jwt.create(user.getUsername(), loginRequest.getPassword(), + Token token = tokenGateway.create(user.getUsername(), loginRequest.getPassword(), user.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()), TokenContext.getExtra()); diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/MyLogoutHandler.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/MyLogoutHandler.java similarity index 100% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/MyLogoutHandler.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/MyLogoutHandler.java diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/MyLogoutSuccessHandler.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/MyLogoutSuccessHandler.java similarity index 100% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/MyLogoutSuccessHandler.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/MyLogoutSuccessHandler.java diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/MyUnAuthenticationEntryPoint.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/MyUnAuthenticationEntryPoint.java similarity index 100% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/MyUnAuthenticationEntryPoint.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/MyUnAuthenticationEntryPoint.java diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/SecurityLoginHandler.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/SecurityLoginHandler.java similarity index 89% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/SecurityLoginHandler.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/SecurityLoginHandler.java index 25611828..e73dda67 100644 --- a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/filter/SecurityLoginHandler.java +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/SecurityLoginHandler.java @@ -1,7 +1,7 @@ package com.codingapi.springboot.security.filter; import com.codingapi.springboot.security.dto.request.LoginRequest; -import com.codingapi.springboot.security.jwt.Token; +import com.codingapi.springboot.security.gateway.Token; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/jwt/Token.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/gateway/Token.java similarity index 91% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/jwt/Token.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/gateway/Token.java index a3fd6345..9579a9b3 100644 --- a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/jwt/Token.java +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/gateway/Token.java @@ -1,8 +1,8 @@ -package com.codingapi.springboot.security.jwt; +package com.codingapi.springboot.security.gateway; import com.alibaba.fastjson.JSONObject; import com.codingapi.springboot.framework.serializable.JsonSerializable; -import com.codingapi.springboot.security.crypto.MyAES; +import com.codingapi.springboot.security.crypto.AESTools; import com.codingapi.springboot.security.exception.TokenExpiredException; import lombok.Getter; import lombok.NoArgsConstructor; @@ -34,7 +34,7 @@ public Token(String username, String iv,String extra, List authorities, this.username = username; this.extra = extra; if(iv!=null) { - this.iv = MyAES.getInstance().encode(iv); + this.iv = AESTools.getInstance().encode(iv); } this.authorities = authorities; this.expireTime = System.currentTimeMillis() + expireValue; @@ -56,7 +56,7 @@ public String decodeIv(){ if(iv==null){ return null; } - return MyAES.getInstance().decode(iv); + return AESTools.getInstance().decode(iv); } diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/jwt/TokenContext.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/gateway/TokenContext.java similarity index 91% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/jwt/TokenContext.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/gateway/TokenContext.java index 99b37a7c..e3ecaa8f 100644 --- a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/jwt/TokenContext.java +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/gateway/TokenContext.java @@ -1,4 +1,4 @@ -package com.codingapi.springboot.security.jwt; +package com.codingapi.springboot.security.gateway; import org.springframework.security.core.context.SecurityContextHolder; diff --git a/springboot-starter-security/src/main/java/com/codingapi/springboot/security/gateway/TokenGateway.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/gateway/TokenGateway.java new file mode 100644 index 00000000..b339079d --- /dev/null +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/gateway/TokenGateway.java @@ -0,0 +1,23 @@ +package com.codingapi.springboot.security.gateway; + +import java.util.List; + +public interface TokenGateway { + + Token create(String username, String iv, List authorities, String extra); + + default Token create(String username, String iv, List authorities) { + return create(username, iv, authorities, null); + } + + default Token create(String username, List authorities) { + return create(username, null, authorities, null); + } + + default Token create(String username, List authorities, String extra) { + return create(username, null, authorities, extra); + } + + Token parser(String sign); + +} diff --git a/springboot-starter-security/src/main/java/com/codingapi/springboot/security/jwt/JWTSecurityConfiguration.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/jwt/JWTSecurityConfiguration.java new file mode 100644 index 00000000..54df5b3c --- /dev/null +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/jwt/JWTSecurityConfiguration.java @@ -0,0 +1,35 @@ +package com.codingapi.springboot.security.jwt; + +import com.codingapi.springboot.security.gateway.TokenGateway; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConditionalOnProperty(prefix = "codingapi.security.jwt", name = "enable", havingValue = "true") +public class JWTSecurityConfiguration { + + + @Bean + @ConfigurationProperties(prefix = "codingapi.security.jwt") + public SecurityJWTProperties securityJWTProperties() { + return new SecurityJWTProperties(); + } + + + @Bean + @ConditionalOnMissingBean + public JwtTokenGateway jwtTokenGateway(SecurityJWTProperties properties) { + return new JwtTokenGateway(properties); + } + + + @Bean + @ConditionalOnMissingBean + public TokenGateway jwtTokenGatewayImpl(JwtTokenGateway jwtTokenGateway) { + return new JWTTokenGatewayImpl(jwtTokenGateway); + } + +} diff --git a/springboot-starter-security/src/main/java/com/codingapi/springboot/security/jwt/JWTTokenGatewayImpl.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/jwt/JWTTokenGatewayImpl.java new file mode 100644 index 00000000..4a890ab7 --- /dev/null +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/jwt/JWTTokenGatewayImpl.java @@ -0,0 +1,25 @@ +package com.codingapi.springboot.security.jwt; + +import com.codingapi.springboot.security.gateway.Token; +import com.codingapi.springboot.security.gateway.TokenGateway; + +import java.util.List; + +public class JWTTokenGatewayImpl implements TokenGateway { + + private final JwtTokenGateway jwtTokenGateway; + + public JWTTokenGatewayImpl(JwtTokenGateway jwtTokenGateway) { + this.jwtTokenGateway = jwtTokenGateway; + } + + @Override + public Token create(String username, String password, List authorities, String extra) { + return jwtTokenGateway.create(username, password, authorities, extra); + } + + @Override + public Token parser(String sign) { + return jwtTokenGateway.parser(sign); + } +} diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/jwt/Jwt.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/jwt/JwtTokenGateway.java similarity index 78% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/jwt/Jwt.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/jwt/JwtTokenGateway.java index 611ba04e..57dab485 100644 --- a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/jwt/Jwt.java +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/jwt/JwtTokenGateway.java @@ -2,6 +2,7 @@ import com.alibaba.fastjson.JSONObject; import com.codingapi.springboot.framework.exception.LocaleMessageException; +import com.codingapi.springboot.security.gateway.Token; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jws; import io.jsonwebtoken.Jwts; @@ -11,19 +12,19 @@ import java.nio.charset.StandardCharsets; import java.util.List; -public class Jwt { +public class JwtTokenGateway { private final SecretKey key; - private final int jwtTime; - private final int jwtRestTime; + private final int validTime; + private final int restTime; - public Jwt(String secretKey, int jwtTime, int jwtRestTime) { - this.key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8)); - this.jwtTime = jwtTime; - this.jwtRestTime = jwtRestTime; + public JwtTokenGateway(SecurityJWTProperties properties) { + this.key = Keys.hmacShaKeyFor(properties.getSecretKey().getBytes(StandardCharsets.UTF_8)); + this.validTime = properties.getValidTime(); + this.restTime = properties.getRestTime(); } - public Token create(String username, List authorities,String extra){ + public Token create(String username, List authorities, String extra){ return create(username, null,authorities, extra); } @@ -36,7 +37,7 @@ public Token create(String username, String iv, List authorities){ } public Token create(String username, String iv,List authorities,String extra){ - Token token = new Token(username, iv,extra, authorities, jwtTime, jwtRestTime); + Token token = new Token(username, iv,extra, authorities, validTime, restTime); String jwt = Jwts.builder().subject(token.toJson()).signWith(key).compact(); token.setToken(jwt); return token; diff --git a/springboot-starter-security/src/main/java/com/codingapi/springboot/security/jwt/SecurityJWTProperties.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/jwt/SecurityJWTProperties.java new file mode 100644 index 00000000..d4ca0537 --- /dev/null +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/jwt/SecurityJWTProperties.java @@ -0,0 +1,35 @@ +package com.codingapi.springboot.security.jwt; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class SecurityJWTProperties { + + + /** + * 是否启用JWT + */ + private boolean enable = true; + + /** + * JWT密钥 + * 需大于32位的字符串 + */ + private String secretKey = "codingapi.security.jwt.secretkey"; + + + /** + * JWT 有效时间(毫秒) + * 15分钟有效期 1000*60*15=900000 + */ + private int validTime = 900000; + + /** + * JWT 更换令牌时间(毫秒) + * 10分钟后更换令牌 1000*60*10=600000 + */ + private int restTime = 600000; + +} diff --git a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/properties/SecurityJwtProperties.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/properties/CodingApiSecurityProperties.java similarity index 69% rename from springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/properties/SecurityJwtProperties.java rename to springboot-starter-security/src/main/java/com/codingapi/springboot/security/properties/CodingApiSecurityProperties.java index 5c296e80..4a33d91b 100644 --- a/springboot-starter-security-jwt/src/main/java/com/codingapi/springboot/security/properties/SecurityJwtProperties.java +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/properties/CodingApiSecurityProperties.java @@ -5,37 +5,7 @@ @Setter @Getter -public class SecurityJwtProperties { - - /** - * JWT密钥 - * 需大于32位的字符串 - */ - private String jwtSecretKey = "codingapi.security.jwt.secretkey"; - - - /** - * aes key - */ - private String aseKey = "QUNEWCQlXiYqJCNYQ1phc0FDRFgkJV4mKiQjWENaYXM="; - - /** - * aes iv - */ - private String aseIv = "QUNYRkdIQEVEUyNYQ1phcw=="; - - - /** - * JWT 有效时间(毫秒) - * 15分钟有效期 1000*60*15=900000 - */ - private int jwtTime = 900000; - - /** - * JWT 更换令牌时间(毫秒) - * 10分钟后更换令牌 1000*60*10=600000 - */ - private int jwtRestTime = 600000; +public class CodingApiSecurityProperties { /** * 权限拦截URL @@ -58,6 +28,17 @@ public class SecurityJwtProperties { */ private String ignoreUrls = "/open/**"; + /** + * aes key + */ + private String aseKey = "QUNEWCQlXiYqJCNYQ1phc0FDRFgkJV4mKiQjWENaYXM="; + + /** + * aes iv + */ + private String aseIv = "QUNYRkdIQEVEUyNYQ1phcw=="; + + /** * 启用禁用CSRF */ diff --git a/springboot-starter-security/src/main/java/com/codingapi/springboot/security/redis/RedisSecurityConfiguration.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/redis/RedisSecurityConfiguration.java new file mode 100644 index 00000000..c4bf141b --- /dev/null +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/redis/RedisSecurityConfiguration.java @@ -0,0 +1,35 @@ +package com.codingapi.springboot.security.redis; + +import com.codingapi.springboot.security.gateway.TokenGateway; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.core.RedisTemplate; + +@Configuration +@ConditionalOnProperty(prefix = "codingapi.security.redis", name = "enable", havingValue = "true") +public class RedisSecurityConfiguration { + + + @Bean + @ConfigurationProperties(prefix = "codingapi.security.redis") + public SecurityRedisProperties securityRedisProperties() { + return new SecurityRedisProperties(); + } + + + @Bean + @ConditionalOnMissingBean + public RedisTokenGateway redisTokenGateway(RedisTemplate redisTemplate, SecurityRedisProperties properties) { + return new RedisTokenGateway(redisTemplate, properties); + } + + @Bean + @ConditionalOnMissingBean + public TokenGateway redisTokenGatewayImpl(RedisTokenGateway redisTokenGateway) { + return new RedisTokenGatewayImpl(redisTokenGateway); + } + +} diff --git a/springboot-starter-security/src/main/java/com/codingapi/springboot/security/redis/RedisTokenGateway.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/redis/RedisTokenGateway.java new file mode 100644 index 00000000..d4eb4257 --- /dev/null +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/redis/RedisTokenGateway.java @@ -0,0 +1,65 @@ +package com.codingapi.springboot.security.redis; + +import com.alibaba.fastjson2.JSONObject; +import com.codingapi.springboot.security.gateway.Token; +import org.springframework.data.redis.core.RedisTemplate; + +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; + +public class RedisTokenGateway { + + private final RedisTemplate redisTemplate; + private final int validTime; + private final int restTime; + + public RedisTokenGateway(RedisTemplate redisTemplate, SecurityRedisProperties properties) { + this.redisTemplate = redisTemplate; + this.validTime = properties.getValidTime(); + this.restTime = properties.getRestTime(); + } + + public Token create(String username, String iv, List authorities, String extra) { + Token token = new Token(username, iv, extra, authorities, validTime, restTime); + String key = String.format("%s:%s", username, UUID.randomUUID().toString().replaceAll("-", "")); + token.setToken(key); + redisTemplate.opsForValue().set(key, token.toJson(), validTime, TimeUnit.MILLISECONDS); + return token; + } + + public Token parser(String sign) { + String json = redisTemplate.opsForValue().get(sign); + if (json == null) { + return null; + } + return JSONObject.parseObject(json, Token.class); + } + + public void removeToken(String token) { + redisTemplate.delete(token); + } + + public void removeUsername(String username) { + Set keys = redisTemplate.keys(username + ":*"); + if (keys != null && !keys.isEmpty()) { + redisTemplate.delete(keys); + } + } + + public void removeUsername(String username, Predicate predicate) { + Set keys = redisTemplate.keys(username + ":*"); + if (keys != null && !keys.isEmpty()) { + for (String key : keys) { + Token token = parser(key); + if (token != null && predicate.test(token)) { + redisTemplate.delete(key); + } + } + } + } + + +} diff --git a/springboot-starter-security/src/main/java/com/codingapi/springboot/security/redis/RedisTokenGatewayImpl.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/redis/RedisTokenGatewayImpl.java new file mode 100644 index 00000000..19453d66 --- /dev/null +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/redis/RedisTokenGatewayImpl.java @@ -0,0 +1,26 @@ +package com.codingapi.springboot.security.redis; + +import com.codingapi.springboot.security.gateway.Token; +import com.codingapi.springboot.security.gateway.TokenGateway; + +import java.util.List; + +public class RedisTokenGatewayImpl implements TokenGateway { + + private final RedisTokenGateway redisTokenGateway; + + public RedisTokenGatewayImpl(RedisTokenGateway redisTokenGateway) { + this.redisTokenGateway = redisTokenGateway; + } + + @Override + public Token create(String username, String iv, List authorities, String extra) { + return redisTokenGateway.create(username, iv, authorities, extra); + } + + @Override + public Token parser(String sign) { + return redisTokenGateway.parser(sign); + } + +} diff --git a/springboot-starter-security/src/main/java/com/codingapi/springboot/security/redis/SecurityRedisProperties.java b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/redis/SecurityRedisProperties.java new file mode 100644 index 00000000..14eae9ac --- /dev/null +++ b/springboot-starter-security/src/main/java/com/codingapi/springboot/security/redis/SecurityRedisProperties.java @@ -0,0 +1,27 @@ +package com.codingapi.springboot.security.redis; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class SecurityRedisProperties { + + + /** + * 是否启用redis + */ + private boolean enable = true; + + /** + * 15分钟有效期 1000*60*15=900000 + */ + private int validTime = 900000; + + /** + * 10分钟后更换令牌 1000*60*10=600000 + */ + private int restTime = 600000; + + +} diff --git a/springboot-starter-security/src/main/resources/META-INF/spring.factories b/springboot-starter-security/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..ef66f5b0 --- /dev/null +++ b/springboot-starter-security/src/main/resources/META-INF/spring.factories @@ -0,0 +1,6 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.codingapi.springboot.security.configurer.WebSecurityConfigurer,\ +com.codingapi.springboot.security.jwt.JWTSecurityConfiguration,\ +com.codingapi.springboot.security.redis.RedisSecurityConfiguration,\ +com.codingapi.springboot.security.crypto.SecurityCryptoConfiguration,\ +com.codingapi.springboot.security.AutoConfiguration \ No newline at end of file diff --git a/springboot-starter-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/springboot-starter-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..59324754 --- /dev/null +++ b/springboot-starter-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,5 @@ +com.codingapi.springboot.security.configurer.WebSecurityConfigurer +com.codingapi.springboot.security.crypto.SecurityCryptoConfiguration +com.codingapi.springboot.security.jwt.JWTSecurityConfiguration +com.codingapi.springboot.security.redis.RedisSecurityConfiguration +com.codingapi.springboot.security.AutoConfiguration \ No newline at end of file diff --git a/springboot-starter-security-jwt/src/test/java/com/codingapi/springboot/security/SecurityJwtApplication.java b/springboot-starter-security/src/test/java/com/codingapi/springboot/security/SecurityJwtApplication.java similarity index 100% rename from springboot-starter-security-jwt/src/test/java/com/codingapi/springboot/security/SecurityJwtApplication.java rename to springboot-starter-security/src/test/java/com/codingapi/springboot/security/SecurityJwtApplication.java diff --git a/springboot-starter-security-jwt/src/test/java/com/codingapi/springboot/security/SecurityJwtApplicationTest.java b/springboot-starter-security/src/test/java/com/codingapi/springboot/security/SecurityJwtApplicationTest.java similarity index 100% rename from springboot-starter-security-jwt/src/test/java/com/codingapi/springboot/security/SecurityJwtApplicationTest.java rename to springboot-starter-security/src/test/java/com/codingapi/springboot/security/SecurityJwtApplicationTest.java diff --git a/springboot-starter-security-jwt/src/test/java/com/codingapi/springboot/security/controller/DemoController.java b/springboot-starter-security/src/test/java/com/codingapi/springboot/security/controller/DemoController.java similarity index 100% rename from springboot-starter-security-jwt/src/test/java/com/codingapi/springboot/security/controller/DemoController.java rename to springboot-starter-security/src/test/java/com/codingapi/springboot/security/controller/DemoController.java diff --git a/springboot-starter-security-jwt/src/test/java/com/codingapi/springboot/security/jwt/TestVO.java b/springboot-starter-security/src/test/java/com/codingapi/springboot/security/jwt/TestVO.java similarity index 100% rename from springboot-starter-security-jwt/src/test/java/com/codingapi/springboot/security/jwt/TestVO.java rename to springboot-starter-security/src/test/java/com/codingapi/springboot/security/jwt/TestVO.java diff --git a/springboot-starter-security-jwt/src/test/java/com/codingapi/springboot/security/jwt/TokenTest.java b/springboot-starter-security/src/test/java/com/codingapi/springboot/security/jwt/TokenTest.java similarity index 73% rename from springboot-starter-security-jwt/src/test/java/com/codingapi/springboot/security/jwt/TokenTest.java rename to springboot-starter-security/src/test/java/com/codingapi/springboot/security/jwt/TokenTest.java index 3010f7fb..b5611674 100644 --- a/springboot-starter-security-jwt/src/test/java/com/codingapi/springboot/security/jwt/TokenTest.java +++ b/springboot-starter-security/src/test/java/com/codingapi/springboot/security/jwt/TokenTest.java @@ -1,6 +1,8 @@ package com.codingapi.springboot.security.jwt; import com.codingapi.springboot.security.exception.TokenExpiredException; +import com.codingapi.springboot.security.gateway.Token; +import com.codingapi.springboot.security.gateway.TokenGateway; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -14,7 +16,7 @@ class TokenTest { @Autowired - private Jwt jwt; + private TokenGateway tokenGateway; @Test void verify1() throws TokenExpiredException { @@ -22,10 +24,10 @@ void verify1() throws TokenExpiredException { String iv = "123456"; List authorities = Collections.singletonList("ADMIN"); - Token token =jwt.create(username,iv,authorities); + Token token =tokenGateway.create(username,iv,authorities); token.verify(); - Token data = jwt.parser(token.getToken()); + Token data = tokenGateway.parser(token.getToken()); assertEquals(data.decodeIv(),iv); assertEquals(data.getAuthorities(),authorities); } @@ -35,10 +37,10 @@ void verify2() throws TokenExpiredException { String username = "admin"; List authorities = Collections.singletonList("ADMIN"); - Token token =jwt.create(username,authorities); + Token token =tokenGateway.create(username,authorities); token.verify(); - Token data = jwt.parser(token.getToken()); + Token data = tokenGateway.parser(token.getToken()); assertEquals(data.getUsername(),username); assertEquals(data.getAuthorities(),authorities); } @@ -52,10 +54,10 @@ void verify3() throws TokenExpiredException { String extra = testVO.toJson(); List authorities = Collections.singletonList("ADMIN"); - Token token =jwt.create(username,authorities,extra); + Token token =tokenGateway.create(username,authorities,extra); token.verify(); - Token data = jwt.parser(token.getToken()); + Token data = tokenGateway.parser(token.getToken()); assertEquals(data.parseExtra(TestVO.class).getName(), testVO.getName()); assertEquals(data.getAuthorities(),authorities); } diff --git a/springboot-starter-security-jwt/src/test/resources/application.properties b/springboot-starter-security/src/test/resources/application.properties similarity index 74% rename from springboot-starter-security-jwt/src/test/resources/application.properties rename to springboot-starter-security/src/test/resources/application.properties index 3848c355..fe90d5f8 100644 --- a/springboot-starter-security-jwt/src/test/resources/application.properties +++ b/springboot-starter-security/src/test/resources/application.properties @@ -1,14 +1,15 @@ server.port=8088 -codingapi.security.jwt-time=10000 -codingapi.security.jwt-rest-time=5000 +codingapi.security.jwt.valid-time=10000 +codingapi.security.jwt.rest-time=5000 +codingapi.security.jwt.enable=true # JWT密钥 需大于32位的字符串 -codingapi.security.jwt-secret=codingapi.security.jwt.secretkey +codingapi.security.jwt.secret-key=codingapi.security.jwt.secretkey # JWT AES密钥 codingapi.security.ase-key=QUNEWCQlXiYqJCNYQ1phc0FDRFgkJV4mKiQjWENaYXM= # JWT AES IV -codingapi.security.aes-iv=QUNYRkdIQEVEUyNYQ1phcw== +codingapi.security.ase-iv=QUNYRkdIQEVEUyNYQ1phcw== # JWT 有效时间(毫秒) 15分钟有效期 1000*60*15=900000 #codingapi.security.jwt-time=900000 @@ -27,3 +28,5 @@ codingapi.security.ignore-urls=/open/** codingapi.security.disable-csrf=true # 禁用CORS codingapi.security.disable-cors=true + +spring.main.allow-bean-definition-overriding=true \ No newline at end of file diff --git a/springboot-starter/pom.xml b/springboot-starter/pom.xml index 432a5763..a4bda8f6 100644 --- a/springboot-starter/pom.xml +++ b/springboot-starter/pom.xml @@ -5,7 +5,7 @@ com.codingapi.springboot springboot-parent - 3.1.10 + 3.2.0 springboot-starter