This commit is contained in:
ran.shang
2025-06-11 09:42:13 +08:00
commit 7e38b8d971
1935 changed files with 132836 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
package com.newyetai.security.config;
import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.newyetai.security.handle.MyAuthenctiationFailureHandler;
import com.newyetai.security.mobile.MobileAuthenticationProvider;
import com.newyetai.security.social.service.StandardClientRegistrationRepository;
import com.newyetai.security.social.wechat.service.WechatOauthLoginProvider;
import com.newyetai.security.ssb.SsbAuthenticationProvider;
import com.newyetai.security.temptoken.TokenAuthenticationProvider;
import com.newyetai.security.upassword.UpasswordAuthenticationProvider;
import com.newyetai.security.util.SecurityPropertyUtils;
import com.newyetai.usercenter.constants.SecurityConstants;
import com.newyetai.usercenter.user.login.service.UserLoginService;
/**
* security配置类
*
* @author on 2019-11-05
*/
@Configuration
@AutoConfigurationPackage
public class SecurityConfiguration {
private SecurityProperties securityProperties;
SecurityConfiguration(SecurityProperties securityProperties){
this.securityProperties = securityProperties;
SecurityPropertyUtils.setSecurityProperties(securityProperties);
}
/**
* 声明密码加密方式
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
MyAuthenctiationFailureHandler myAuthenctiationFailureHandler() {
return new MyAuthenctiationFailureHandler(securityProperties.getLoginPage());
}
@Bean
@ConditionalOnProperty(name = SecurityConstants.PROP_KEY_SECURITY_OAUTH2_USEDB, havingValue = "true",
matchIfMissing = false)
StandardClientRegistrationRepository standardClientRegistrationRepository(UserLoginService userLoginService) {
return new StandardClientRegistrationRepository(userLoginService);
}
@Bean
@ConditionalOnBean(UserLoginService.class)
MobileAuthenticationProvider mobileAuthenticationProvider(UserLoginService userLoginService) {
return new MobileAuthenticationProvider(userLoginService);
}
@Bean
@ConditionalOnBean(UserLoginService.class)
WechatOauthLoginProvider wechatOauthLoginProvider(UserLoginService userLoginService) {
return new WechatOauthLoginProvider(userLoginService);
}
@Bean
@ConditionalOnBean(UserLoginService.class)
TokenAuthenticationProvider tokenAuthenticationProvider(UserLoginService userLoginService) {
return new TokenAuthenticationProvider(userLoginService);
}
@Bean
@ConditionalOnBean(UserLoginService.class)
UpasswordAuthenticationProvider upasswordAuthenticationProvider(UserLoginService userLoginService) {
return new UpasswordAuthenticationProvider(userLoginService);
}
@Bean
@ConditionalOnBean(UserLoginService.class)
SsbAuthenticationProvider ssbAuthenticationProvider(UserLoginService userLoginService) {
return new SsbAuthenticationProvider(userLoginService);
}
}

View File

@@ -0,0 +1,76 @@
package com.newyetai.security.config;
import com.newyetai.security.jwt.JwtProperties;
import lombok.Data;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 安全相关配置项
*
* @author guhong
*/
@Component
@Data
@ConfigurationProperties(prefix = SecurityProperties.PREFIX)
public class SecurityProperties {
/** 配置前缀 **/
public final static String PREFIX = "security";
/**
* 匿名访问的url
*/
private String anonymous;
/**
* 忽略的资源,直接跳过spring security权限校验,一般是用做静态资源
*/
private String ignoring;
/** 登录页面 **/
private String loginPage;
private String loginSuccessPage;
/** h5登录成功页 **/
private String loginH5SuccessPage;
/** 登录请求路径 **/
private String loginProcessingUrl;
private Boolean allowIfAllAbstainDecisions;
/** 域名 **/
private String domain;
private Boolean superiorOnly;
/** 不记日志路径,contains匹配 **/
private String notLogs;
private JwtProperties jwt = new JwtProperties();
/** 是否调用本地认证鉴权,默认本地;调用户中心配置false **/
private Boolean useLocal;
private Oauth2Properties oauth2 = new Oauth2Properties();
public String[] getAnonymousArray() {
return StringUtils.isBlank(anonymous) ? ArrayUtils.EMPTY_STRING_ARRAY : anonymous.split(",");
}
public String[] getIgnoringArray() {
return StringUtils.isBlank(ignoring) ? ArrayUtils.EMPTY_STRING_ARRAY : ignoring.split(",");
}
@Data
public class Oauth2Properties{
/** 是否启用 **/
private Boolean enable;
/** oauth配置类型:true使用数据库配置,否则配置文件 **/
private Boolean usedb;
}
}

View File

@@ -0,0 +1,247 @@
package com.newyetai.security.config;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.stereotype.Component;
import com.newyetai.security.access.intercept.FilterSecurityInterceptor;
import com.newyetai.security.handle.MyAuthenctiationFailureHandler;
import com.newyetai.security.handle.MyLoginSuccessHandler;
import com.newyetai.security.handle.MyLoginUrlAuthenticationEntryPoint;
import com.newyetai.security.handle.MyLogoutSuccessHandler;
import com.newyetai.security.jwt.JwtAuthenticationTokenFilter;
import com.newyetai.security.mobile.MobileAuthenticationFilter;
import com.newyetai.security.mobile.MobileAuthenticationProvider;
import com.newyetai.security.social.service.StandardAuthorizationCodeTokenResponseClient;
import com.newyetai.security.social.service.StandardOAuth2UserService;
import com.newyetai.security.social.service.StandardOauth2AuthorizationRequestResolver;
import com.newyetai.security.ssb.SsbAuthenticationFilter;
import com.newyetai.security.ssb.SsbAuthenticationProvider;
import com.newyetai.security.temptoken.TokenAuthenticationFilter;
import com.newyetai.security.temptoken.TokenAuthenticationProvider;
import com.newyetai.security.upassword.UpasswordAuthenticationFilter;
import com.newyetai.security.upassword.UpasswordAuthenticationProvider;
import com.newyetai.swagger.config.SwaggerConfig;
import com.newyetai.usercenter.user.login.service.UserLoginService;
import com.newyetai.usercenter.websocket.util.WebSocketUtils;
import lombok.extern.slf4j.Slf4j;
/**
* security配置
*
* @author on 2019-11-05
*/
@Slf4j
@Component
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Autowired
private SecurityProperties securityProperties;
@Autowired
private MyLogoutSuccessHandler myLogoutSuccessHandler;
@Autowired
private MyLoginSuccessHandler myLoginSuccessHandler;
@Autowired
private MyAuthenctiationFailureHandler myAuthenctiationFailureHandler;
@Autowired
private FilterInvocationSecurityMetadataSource securityMetadataSource;
@Autowired
private AccessDecisionManager accessDecisionManager;
@Autowired(required = false)
private UpasswordAuthenticationProvider upasswordAuthenticationProvider;
@Autowired(required = false)
private MobileAuthenticationProvider mobileAuthenticationProvider;
@Autowired(required = false)
private TokenAuthenticationProvider tokenAuthenticationProvider;
@Autowired
private SsbAuthenticationProvider ssbAuthenticationProvider;
@Autowired
private SwaggerConfig swaggerConfig;
@Autowired(required = false)
private UserLoginService userLoginService;
@Autowired(required = false)
private ClientRegistrationRepository standardClientRegistrationRepository;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 添加cas认证提供者
auth.authenticationProvider(upasswordAuthenticationProvider)
.authenticationProvider(mobileAuthenticationProvider)
.authenticationProvider(tokenAuthenticationProvider)
.authenticationProvider(ssbAuthenticationProvider)
;
}
@Override
public void configure(WebSecurity web) throws Exception {
String[] ignoringArray = securityProperties.getIgnoringArray();
// swagger 接口文档,不设置访问权限
if (swaggerConfig.isSwaggerEnable() && StringUtils.isNotBlank(SwaggerConfig.ACCESS_PREFIX)) {
ignoringArray = ArrayUtils.addAll(ignoringArray, SwaggerConfig.ACCESS_PREFIX.split(","));
}
// websocket
if (StringUtils.isNotBlank(WebSocketUtils.getPath())) {
ignoringArray = ArrayUtils.add(ignoringArray, WebSocketUtils.getPath());
}
// 忽略的资源,直接跳过spring security权限校验
web.ignoring()
.antMatchers(ignoringArray)/*.antMatchers(securityProperties.getAnonymousArray())*/;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
log.info("------WebSecurityConfigurer configure");
http
.logout()
.logoutSuccessHandler(myLogoutSuccessHandler).and()
// 自定义认证失败处理器
.exceptionHandling().authenticationEntryPoint(
new MyLoginUrlAuthenticationEntryPoint(securityProperties.getLoginPage()))
.and();
if (BooleanUtils.isTrue(securityProperties.getOauth2().getEnable())) {
// oauth2
http.oauth2Login()
.authorizationEndpoint()
.authorizationRequestResolver(
new StandardOauth2AuthorizationRequestResolver(
this.standardClientRegistrationRepository,
OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI))
.and()
.tokenEndpoint()
.accessTokenResponseClient(new StandardAuthorizationCodeTokenResponseClient())
.and()
.userInfoEndpoint().userService(new StandardOAuth2UserService()).and()
.failureHandler(myAuthenctiationFailureHandler)
.successHandler(myLoginSuccessHandler).and();
}
http.addFilterAfter(upasswordAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class);
http.addFilterAfter(mobileAuthenticationFilter(), UpasswordAuthenticationFilter.class);
http.addFilterAfter(tokenAuthenticationFilter(), UpasswordAuthenticationFilter.class);
http.addFilterAfter(ssbAuthenticationFilter(), UpasswordAuthenticationFilter.class);
// 禁用CSRF
http.csrf().disable();
http.headers().frameOptions().deny();
http.headers().xssProtection().block(true);
http.headers().contentTypeOptions();
// 拦截器
FilterSecurityInterceptor securityInterceptor = createFilterSecurityInterceptor();
http.addFilterAfter(securityInterceptor,
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.class);
http.setSharedObject(FilterSecurityInterceptor.class, securityInterceptor);
// 启用jwt
if (Boolean.TRUE.equals(securityProperties.getJwt().getEnable())) {
JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter =
createJwtAuthenticationTokenFilter();
http.addFilterAfter(jwtAuthenticationTokenFilter,
AnonymousAuthenticationFilter.class);
// 禁用session
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
private JwtAuthenticationTokenFilter createJwtAuthenticationTokenFilter() {
return new JwtAuthenticationTokenFilter(securityProperties);
}
/**
* 拦截器
*
* @return
* @throws Exception
* @author sr on 2019-11-28
*/
private FilterSecurityInterceptor createFilterSecurityInterceptor() throws Exception {
FilterSecurityInterceptor securityInterceptor = new FilterSecurityInterceptor();
securityInterceptor.setSecurityMetadataSource(securityMetadataSource);
securityInterceptor.setAccessDecisionManager(accessDecisionManager);
// httpSecurity中shareobject共用的authenticationBuilder
securityInterceptor.setAuthenticationManager(this.authenticationManagerBean());
securityInterceptor.setUserLoginService(userLoginService);
securityInterceptor.afterPropertiesSet();
return securityInterceptor;
}
/**
* 手机号登录请求过滤器
*
* @param authenticationManager
* @return
* @author sr on 2020-06-04
* @throws Exception
*/
private MobileAuthenticationFilter mobileAuthenticationFilter() throws Exception {
MobileAuthenticationFilter filter = new MobileAuthenticationFilter();
addHandler(filter);
return filter;
}
private void addHandler(AbstractAuthenticationProcessingFilter filter) throws Exception {
filter.setAuthenticationManager(this.authenticationManagerBean());
filter.setAuthenticationSuccessHandler(myLoginSuccessHandler);
filter.setAuthenticationFailureHandler(myAuthenctiationFailureHandler);
}
/**
* 账号密码
* @return
* @throws Exception
* @author sr on 2021-06-22
*/
private UpasswordAuthenticationFilter upasswordAuthenticationFilter() throws Exception {
UpasswordAuthenticationFilter filter = new UpasswordAuthenticationFilter();
addHandler(filter);
return filter;
}
/**
* 临时token
* @return
* @throws Exception
* @author sr on 2021-06-22
*/
private TokenAuthenticationFilter tokenAuthenticationFilter() throws Exception {
TokenAuthenticationFilter filter = new TokenAuthenticationFilter();
addHandler(filter);
return filter;
}
private SsbAuthenticationFilter ssbAuthenticationFilter() throws Exception {
SsbAuthenticationFilter filter = new SsbAuthenticationFilter();
addHandler(filter);
return filter;
}
}