Skip to content

Commit

Permalink
♻️ 业务模块使用 ballcat 提供的安全权限注解,方便与 spring security 解耦
Browse files Browse the repository at this point in the history
  • Loading branch information
Hccake committed Jun 12, 2023
1 parent ca35b7d commit 4b92538
Show file tree
Hide file tree
Showing 48 changed files with 408 additions and 235 deletions.
34 changes: 19 additions & 15 deletions ballcat-admin/ballcat-admin-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@
<artifactId>ballcat-admin-core</artifactId>

<dependencies>
<!--mybatis plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<groupId>org.ballcat</groupId>
<artifactId>ballcat-spring-boot-starter-web</artifactId>
</dependency>
<!-- 脱敏工具 -->
<dependency>
Expand All @@ -37,23 +36,15 @@
<groupId>org.ballcat</groupId>
<artifactId>ballcat-spring-boot-starter-redis</artifactId>
</dependency>
<dependency>
<groupId>org.ballcat</groupId>
<artifactId>ballcat-spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.ballcat</groupId>
<artifactId>ballcat-spring-boot-starter-xss</artifactId>
</dependency>
<!-- 基于 spring authorization server 的授权服务器 -->
<dependency>
<groupId>org.ballcat</groupId>
<artifactId>ballcat-spring-security-oauth2-authorization-server</artifactId>
<scope>provided</scope>
</dependency>

<!--mybatis plus-->
<dependency>
<groupId>org.ballcat</groupId>
<artifactId>ballcat-spring-security-oauth2-resource-server</artifactId>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>

<!-- 业务模块 -->
Expand All @@ -73,5 +64,18 @@
<groupId>org.ballcat.business</groupId>
<artifactId>ballcat-system-controller</artifactId>
</dependency>

<!-- 基于 spring authorization server 的授权服务器 -->
<dependency>
<groupId>org.ballcat</groupId>
<artifactId>ballcat-spring-security-oauth2-authorization-server</artifactId>
<scope>provided</scope>
</dependency>
<!-- 基于 spring security 的资源服务器 -->
<dependency>
<groupId>org.ballcat</groupId>
<artifactId>ballcat-spring-security-oauth2-resource-server</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.ballcat.business.system.authentication;
package org.ballcat.admin.springsecurity;

import org.ballcat.admin.springsecurity.UserInfoCoordinator;
import org.ballcat.business.system.model.dto.UserInfoDTO;

import java.util.Map;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.ballcat.admin.springsecurity;

import org.ballcat.business.system.component.AbstractPasswordHelper;
import org.ballcat.business.system.properties.SystemProperties;
import org.ballcat.security.properties.SecurityProperties;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
* 基于 SpringSecurity 的密码工具类
*
* @author Hccake
* @since 2.0.0
*/
public class SpringSecurityPasswordHelper extends AbstractPasswordHelper {

private final PasswordEncoder passwordEncoder;

public SpringSecurityPasswordHelper(SecurityProperties securityProperties, SystemProperties systemProperties,
PasswordEncoder passwordEncoder) {
super(securityProperties, systemProperties);
this.passwordEncoder = passwordEncoder;
}

@Override
public String encode(String rawPassword) {
return passwordEncoder.encode(rawPassword);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.ballcat.admin.springsecurity;

import org.ballcat.security.core.PrincipalAttributeAccessor;
import org.ballcat.springsecurity.oauth2.userdetails.User;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

public class SpringSecurityPrincipalAttributeAccessor implements PrincipalAttributeAccessor {

@Override
@SuppressWarnings("unchecked")
public <A> A getAttribute(String name) {
User user = getUser();
if (user != null) {
return (A) user.getAttributes().get(name);
}
return null;
}

@Override
@SuppressWarnings("unchecked")
public Long getUserId() {
User user = getUser();
if (user != null) {
return user.getUserId();
}
return null;
}

@Override
public String getName() {
User user = getUser();
if (user != null) {
return user.getUsername();
}
return null;
}

private static Authentication getAuthentication() {
return SecurityContextHolder.getContext().getAuthentication();
}

private static User getUser() {
Authentication authentication = getAuthentication();
if (authentication == null) {
return null;
}
Object principal = authentication.getPrincipal();
if (principal instanceof User) {
return (User) principal;
}
else {
return null;
}
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.ballcat.business.system.authentication;
package org.ballcat.admin.springsecurity;

import org.ballcat.springsecurity.oauth2.constant.UserAttributeNameConstants;
import org.ballcat.springsecurity.oauth2.userdetails.User;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.ballcat.business.system.authentication;
package org.ballcat.admin.springsecurity;

import org.ballcat.business.system.model.dto.UserInfoDTO;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.ballcat.business.notify.listener;
package org.ballcat.admin.springsecurity.login;

import org.ballcat.business.notify.enums.NotifyChannelEnum;
import org.ballcat.business.notify.model.entity.Announcement;
Expand All @@ -13,7 +13,6 @@
import org.springframework.context.event.EventListener;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
Expand All @@ -25,7 +24,6 @@
* @version 1.0
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class AnnouncementLoginEventListener {

Expand All @@ -36,11 +34,11 @@ public class AnnouncementLoginEventListener {
private final UserAnnouncementService userAnnouncementService;

/**
* 登录成功时间监听 用户未读公告生成
* 登录成功时监听 用户未读公告生成
* @param event 登录成功 event
*/
@EventListener(AuthenticationSuccessEvent.class)
public void onAuthenticationSuccessEvent(AuthenticationSuccessEvent event) throws InterruptedException {
public void onAuthenticationSuccessEvent(AuthenticationSuccessEvent event) {

AbstractAuthenticationToken source = (AbstractAuthenticationToken) event.getSource();
Object details = source.getDetails();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.ballcat.business.system.authentication;
package org.ballcat.admin.springsecurity.oauth2;

import org.ballcat.springsecurity.oauth2.constant.TokenAttributeNameConstants;
import org.ballcat.springsecurity.oauth2.constant.UserAttributeNameConstants;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package org.ballcat.admin.upms;

import org.ballcat.admin.springsecurity.*;
import org.ballcat.admin.springsecurity.oauth2.BallcatOAuth2TokenResponseEnhancer;
import org.ballcat.admin.upms.log.LogConfiguration;
import org.ballcat.business.system.authentication.BallcatOAuth2TokenResponseEnhancer;
import org.ballcat.business.system.authentication.DefaultUserInfoCoordinatorImpl;
import org.ballcat.business.system.authentication.SysUserDetailsServiceImpl;
import org.ballcat.business.system.authentication.UserInfoCoordinator;
import org.ballcat.business.system.component.PasswordHelper;
import org.ballcat.business.system.properties.SystemProperties;
import org.ballcat.business.system.service.SysUserService;
import org.ballcat.security.core.PrincipalAttributeAccessor;
import org.ballcat.security.properties.SecurityProperties;
import org.ballcat.springsecurity.oauth2.server.authorization.web.authentication.OAuth2TokenResponseEnhancer;
import org.ballcat.springsecurity.oauth2.server.resource.introspection.SpringAuthorizationServerSharedStoredOpaqueTokenIntrospector;
Expand All @@ -22,6 +22,7 @@
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
Expand All @@ -44,7 +45,7 @@ public class UpmsAutoConfiguration {
* @author hccake
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(SysUserService.class)
@ConditionalOnClass({ UserDetailsService.class, SysUserService.class })
@ConditionalOnMissingBean(UserDetailsService.class)
static class UserDetailsServiceConfiguration {

Expand All @@ -69,6 +70,19 @@ public UserInfoCoordinator userInfoCoordinator() {
return new DefaultUserInfoCoordinatorImpl();
}

@Bean
@ConditionalOnMissingBean
public PasswordHelper passwordHelper(SecurityProperties securityProperties, SystemProperties systemProperties,
PasswordEncoder passwordEncoder) {
return new SpringSecurityPasswordHelper(securityProperties, systemProperties, passwordEncoder);
}

@Bean
@ConditionalOnMissingBean
public PrincipalAttributeAccessor principalAttributeAccessor() {
return new SpringSecurityPrincipalAttributeAccessor();
}

}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package org.ballcat.admin.upms.config.mybatis;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.ballcat.common.core.constant.GlobalConstants;
import org.ballcat.springsecurity.oauth2.userdetails.User;
import org.ballcat.springsecurity.util.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.ballcat.common.core.constant.GlobalConstants;
import org.ballcat.security.core.PrincipalAttributeAccessor;

import java.time.LocalDateTime;

Expand All @@ -15,16 +14,22 @@
@Slf4j
public class FillMetaObjectHandle implements MetaObjectHandler {

private final PrincipalAttributeAccessor principalAttributeAccessor;

public FillMetaObjectHandle(PrincipalAttributeAccessor principalAttributeAccessor) {
this.principalAttributeAccessor = principalAttributeAccessor;
}

@Override
public void insertFill(MetaObject metaObject) {
// 逻辑删除标识
this.strictInsertFill(metaObject, "deleted", Long.class, GlobalConstants.NOT_DELETED_FLAG);
// 创建时间
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
// 创建人
User user = SecurityUtils.getUser();
if (user != null) {
this.strictInsertFill(metaObject, "createBy", Long.class, user.getUserId());
Long userId = principalAttributeAccessor.getUserId();
if (userId != null) {
this.strictInsertFill(metaObject, "createBy", Long.class, userId);
}
}

Expand All @@ -33,9 +38,9 @@ public void updateFill(MetaObject metaObject) {
// 修改时间
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
// 修改人
User user = SecurityUtils.getUser();
if (user != null) {
this.strictUpdateFill(metaObject, "updateBy", Long.class, user.getUserId());
Long userId = principalAttributeAccessor.getUserId();
if (userId != null) {
this.strictUpdateFill(metaObject, "updateBy", Long.class, userId);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.ballcat.mybatisplus.injector.CustomSqlInjector;
import org.ballcat.mybatisplus.methods.InsertBatchSomeColumnByCollection;
import org.ballcat.security.core.PrincipalAttributeAccessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -17,8 +18,9 @@
import java.util.List;

/**
* @author hccake
* @date 2020/04/19 默认配置MybatisPlus分页插件,通过conditional注解达到覆盖效用
* 默认配置MybatisPlus分页插件,通过conditional注解达到覆盖效用
*
* @author hccake 2020/04/19
*/
@Configuration
public class MybatisPlusConfig {
Expand All @@ -42,8 +44,8 @@ public MybatisPlusInterceptor mybatisPlusInterceptor() {
*/
@Bean
@ConditionalOnMissingBean(MetaObjectHandler.class)
public MetaObjectHandler fillMetaObjectHandle() {
return new FillMetaObjectHandle();
public MetaObjectHandler fillMetaObjectHandle(PrincipalAttributeAccessor principalAttributeAccessor) {
return new FillMetaObjectHandle(principalAttributeAccessor);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.ballcat.business.log.service.LoginLogService;
import org.ballcat.business.log.service.OperationLogService;
import org.ballcat.business.log.thread.AccessLogSaveThread;
import org.ballcat.security.core.PrincipalAttributeAccessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
Expand All @@ -25,6 +26,12 @@
@ConditionalOnClass(LoginLogService.class)
public class LogConfiguration {

private final PrincipalAttributeAccessor principalAttributeAccessor;

public LogConfiguration(PrincipalAttributeAccessor principalAttributeAccessor) {
this.principalAttributeAccessor = principalAttributeAccessor;
}

/**
* 访问日志保存
* @param accessLogService 访问日志Service
Expand All @@ -34,7 +41,7 @@ public class LogConfiguration {
@ConditionalOnBean(AccessLogService.class)
@ConditionalOnMissingBean(AccessLogHandler.class)
public AccessLogHandler<AccessLog> customAccessLogHandler(AccessLogService accessLogService) {
return new CustomAccessLogHandler(new AccessLogSaveThread(accessLogService));
return new CustomAccessLogHandler(new AccessLogSaveThread(accessLogService), principalAttributeAccessor);
}

/**
Expand All @@ -46,7 +53,7 @@ public AccessLogHandler<AccessLog> customAccessLogHandler(AccessLogService acces
@ConditionalOnBean(OperationLogService.class)
@ConditionalOnMissingBean(OperationLogHandler.class)
public OperationLogHandler<OperationLog> customOperationLogHandler(OperationLogService operationLogService) {
return new CustomOperationLogHandler(operationLogService);
return new CustomOperationLogHandler(operationLogService, principalAttributeAccessor);
}

@ConditionalOnClass(OAuth2AuthorizationServerConfigurer.class)
Expand Down
Loading

0 comments on commit 4b92538

Please sign in to comment.