|
@@ -1,9 +1,9 @@
|
|
|
package com.chelvc.framework.oauth.config;
|
|
|
|
|
|
import java.lang.reflect.Method;
|
|
|
+import java.util.Collection;
|
|
|
import java.util.Collections;
|
|
|
import java.util.List;
|
|
|
-import java.util.Objects;
|
|
|
import java.util.Set;
|
|
|
import javax.crypto.SecretKey;
|
|
|
import javax.crypto.spec.SecretKeySpec;
|
|
@@ -15,11 +15,14 @@ import com.chelvc.framework.base.context.SessionContextHolder;
|
|
|
import com.chelvc.framework.base.util.HttpUtils;
|
|
|
import com.chelvc.framework.base.util.SpringUtils;
|
|
|
import com.chelvc.framework.common.util.AESUtils;
|
|
|
+import com.chelvc.framework.common.util.AssertUtils;
|
|
|
import com.chelvc.framework.common.util.ObjectUtils;
|
|
|
import com.chelvc.framework.common.util.StringUtils;
|
|
|
import com.chelvc.framework.oauth.annotation.Authorize;
|
|
|
import com.chelvc.framework.oauth.context.OAuthContextHolder;
|
|
|
-import com.chelvc.framework.oauth.token.RedisTokenValidator;
|
|
|
+import com.chelvc.framework.oauth.token.TimestampTokenValidator;
|
|
|
+import com.chelvc.framework.oauth.token.TokenValidator;
|
|
|
+import com.google.common.collect.Lists;
|
|
|
import com.google.common.collect.Sets;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
@@ -37,8 +40,12 @@ 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.configuration.WebSecurityConfigurerAdapter;
|
|
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
|
|
+import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
|
|
|
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
|
|
import org.springframework.security.oauth2.core.OAuth2Error;
|
|
|
+import org.springframework.security.oauth2.core.OAuth2TokenValidator;
|
|
|
+import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult;
|
|
|
+import org.springframework.security.oauth2.jwt.Jwt;
|
|
|
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
|
|
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
|
|
|
import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException;
|
|
@@ -67,12 +74,20 @@ public class OAuthConfigurer extends WebSecurityConfigurerAdapter {
|
|
|
@Bean
|
|
|
public JwtDecoder jwtDecoder() {
|
|
|
// 构建JWT解码器实例
|
|
|
- String secret = Objects.requireNonNull(this.properties.getSecret());
|
|
|
+ String secret = AssertUtils.nonempty(this.properties.getSecret(), () -> "OAuth secret is missing");
|
|
|
SecretKey key = new SecretKeySpec(secret.getBytes(), AESUtils.ALGORITHM);
|
|
|
NimbusJwtDecoder decoder = NimbusJwtDecoder.withSecretKey(key).build();
|
|
|
|
|
|
- // 设置令牌验证器
|
|
|
- decoder.setJwtValidator(new RedisTokenValidator());
|
|
|
+ // 添加自定义令牌验证器
|
|
|
+ Collection<OAuth2TokenValidator<Jwt>> validators = Lists.newLinkedList();
|
|
|
+ validators.add(new TimestampTokenValidator());
|
|
|
+ validators.addAll(ApplicationContextHolder.getOrderBeans(this.applicationContext, TokenValidator.class));
|
|
|
+ validators.add(jwt -> {
|
|
|
+ // 初始化会话主体信息
|
|
|
+ OAuthContextHolder.initializeSessionPrincipal(jwt);
|
|
|
+ return OAuth2TokenValidatorResult.success();
|
|
|
+ });
|
|
|
+ decoder.setJwtValidator(new DelegatingOAuth2TokenValidator<>(validators));
|
|
|
return decoder;
|
|
|
}
|
|
|
|
|
@@ -142,10 +157,12 @@ public class OAuthConfigurer extends WebSecurityConfigurerAdapter {
|
|
|
http.logout().addLogoutHandler(this.logoutHandler);
|
|
|
}
|
|
|
|
|
|
- // 排除认证
|
|
|
- Set<String> ignores = Sets.newHashSet();
|
|
|
+ // 如果排除认证配置非空,则其他资源全部守保护
|
|
|
if (ObjectUtils.notEmpty(this.properties.getIgnores())) {
|
|
|
- ignores.addAll(this.properties.getIgnores());
|
|
|
+ String[] ignores = this.properties.getIgnores().toArray(new String[0]);
|
|
|
+ http.authorizeRequests().antMatchers(ignores).permitAll();
|
|
|
+ http.authorizeRequests().anyRequest().authenticated();
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
// 判断是否启用多服务MVC配置,如果包含则获取所有服务资源对象
|
|
@@ -153,7 +170,8 @@ public class OAuthConfigurer extends WebSecurityConfigurerAdapter {
|
|
|
List<Resource> resources = multiserver ?
|
|
|
ApplicationContextHolder.getApplicationResources() : Collections.emptyList();
|
|
|
|
|
|
- // 将所有使用@Authorize注解并且enabled = true的接口地址排除认证
|
|
|
+ // 将所有使用@Authorize注解并且enabled=true的接口地址加入认证
|
|
|
+ Set<String> authenticates = Sets.newHashSet();
|
|
|
ApplicationContextHolder.lookupControllers(this.applicationContext).forEach(controller -> {
|
|
|
Class<?> clazz = AopProxyUtils.ultimateTargetClass(controller);
|
|
|
|
|
@@ -168,16 +186,16 @@ public class OAuthConfigurer extends WebSecurityConfigurerAdapter {
|
|
|
for (Method method : clazz.getDeclaredMethods()) {
|
|
|
Authorize authorize = method.getAnnotation(Authorize.class);
|
|
|
if ((authorize != null || (authorize = clazz.getAnnotation(Authorize.class)) != null)
|
|
|
- && !authorize.enabled()) {
|
|
|
+ && authorize.enabled()) {
|
|
|
for (String api : SpringUtils.getApis(method)) {
|
|
|
- ignores.add(HttpUtils.uri(prefix, api));
|
|
|
+ authenticates.add(HttpUtils.uri(prefix, api));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
- if (ObjectUtils.notEmpty(ignores)) {
|
|
|
- http.authorizeRequests().antMatchers(ignores.toArray(new String[0])).permitAll();
|
|
|
+ if (ObjectUtils.notEmpty(authenticates)) {
|
|
|
+ http.authorizeRequests().antMatchers(authenticates.toArray(new String[0])).authenticated();
|
|
|
}
|
|
|
- http.authorizeRequests().anyRequest().authenticated();
|
|
|
+ http.authorizeRequests().anyRequest().permitAll();
|
|
|
}
|
|
|
}
|