增加访客控制

This commit is contained in:
TS-QD1 2023-09-07 14:31:18 +08:00
parent be3fa53cb6
commit 8d59cc17be
9 changed files with 433 additions and 3 deletions

View File

@ -0,0 +1,128 @@
package cn.com.tenlion.usercenter.aspect;
import cn.com.tenlion.usercenter.login.guest.GuestProperties;
import ink.wgink.common.component.SecurityComponent;
import ink.wgink.exceptions.base.SystemException;
import ink.wgink.pojo.dtos.role.RoleSimpleDTO;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.List;
@Order(-1)
@Component
@Aspect
public class GuestControllerAspect {
/**
* 默认新增事务
*/
private static String[] DEFAULT_SAVE_ARRAY = {"add*", "save*", "insert*", "create*", "new*"};
/**
* 默认删除事务
*/
private static String[] DEFAULT_REMOVE_ARRAY = {"delete*", "remove*"};
/**
* 默认执行事务
*/
private static String[] DEFAULT_UPDATE_ARRAY = {"update*", "edit*", "reset*"};
/**
* 默认其它事务
*/
private static String[] DEFAULT_OTHER_ARRAY = {"send*", "exec*", "set*", "login*", "register*", "sign*", "rest*", "upload*"};
@Autowired
private GuestProperties guestProperties;
@Autowired
private SecurityComponent securityComponent;
@Pointcut("execution(public * *..controller..*.*(..))")
public void apiLogCutPoint() {
}
/**
* 访客没有曾改权限只有查看权限
*
* @param proceedingJoinPoint
* @return
* @throws Throwable
*/
@Around("apiLogCutPoint()")
public Object apiLogAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
if (guestProperties == null) {
return proceedingJoinPoint.proceed();
}
// 非访客不处理
if (!isGuest()) {
return result(proceedingJoinPoint);
}
Method method = ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod();
// GET不处理
if (isGetMethod(method)) {
return result(proceedingJoinPoint);
}
throw new SystemException("权限不足");
}
private Object result(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object result;
try {
result = proceedingJoinPoint.proceed();
} catch (Throwable e) {
throw e;
}
return result;
}
private boolean isGuest() {
if (securityComponent == null) {
return false;
}
if (securityComponent.getCurrentUser() == null) {
return false;
}
if (securityComponent.getCurrentUser().getUserUsername().equalsIgnoreCase("admin")) {
return false;
}
List<RoleSimpleDTO> roles = securityComponent.getCurrentUser().getRoles();
for (RoleSimpleDTO roleSimpleDTO : roles) {
for (String guestRoleId : guestProperties.getGuestRoleIds()) {
if (StringUtils.equals(roleSimpleDTO.getRoleId(), guestRoleId)) {
return true;
}
}
}
return false;
}
private boolean isGetMethod(Method method) {
GetMapping getMapping = method.getAnnotation(GetMapping.class);
if (getMapping != null) {
return true;
}
RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
if (requestMapping == null) {
return false;
}
RequestMethod[] requestMethods = requestMapping.method();
for (RequestMethod requestMethod : requestMethods) {
if (StringUtils.equalsIgnoreCase(requestMethod.name(), "GET")) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,30 @@
package cn.com.tenlion.usercenter.login.guest;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@ConfigurationProperties(prefix = "guest")
public class GuestProperties {
private String loginProcess;
private List<String> guestRoleIds;
public String getLoginProcess() {
return loginProcess;
}
public void setLoginProcess(String loginProcess) {
this.loginProcess = loginProcess;
}
public List<String> getGuestRoleIds() {
return guestRoleIds;
}
public void setGuestRoleIds(List<String> guestRoleIds) {
this.guestRoleIds = guestRoleIds;
}
}

View File

@ -0,0 +1,24 @@
package cn.com.tenlion.usercenter.login.guest;
import org.apache.http.HttpStatus;
import org.apache.http.entity.ContentType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class GuestUserAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
httpServletResponse.setStatus(HttpStatus.SC_OK);
httpServletResponse.setContentType("text/html;charset=utf-8");
PrintWriter writer = httpServletResponse.getWriter();
writer.write("<html><header><title>错误</title></header><body><div style=\"font-size: 20px; font-weight: bold;\">" + e.getMessage() + "<div></body></html>");
writer.flush();
}
}

View File

@ -0,0 +1,37 @@
package cn.com.tenlion.usercenter.login.guest;
import ink.wgink.login.base.exceptions.UserAuthenticationException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AndRequestMatcher;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class GuestUserAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
protected GuestUserAuthenticationFilter(String loginProcess) {
super(new AntPathRequestMatcher(loginProcess, "GET"));
}
@Override
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {
String guest = httpServletRequest.getParameter("guest");
if (StringUtils.isBlank(guest)) {
throw new UserAuthenticationException("guest不能为空");
}
GuestUserAuthenticationToken guestUserAuthenticationToken = new GuestUserAuthenticationToken(guest, guest);
guestUserAuthenticationToken.setDetails(authenticationDetailsSource.buildDetails(httpServletRequest));
return this.getAuthenticationManager().authenticate(guestUserAuthenticationToken);
}
}

View File

@ -0,0 +1,112 @@
package cn.com.tenlion.usercenter.login.guest;
import ink.wgink.common.manager.env.EnvManager;
import ink.wgink.exceptions.base.SystemException;
import ink.wgink.interfaces.expand.login.ILoginHandlerService;
import ink.wgink.login.base.authentication.user.UserAuthenticationToken;
import ink.wgink.login.base.consts.IUserCenterConst;
import ink.wgink.login.base.enums.LoginTypeEnum;
import ink.wgink.login.base.exceptions.UserAuthenticationException;
import ink.wgink.login.base.service.user.UserDetailServiceImpl;
import ink.wgink.login.base.service.user.UserLoginService;
import ink.wgink.pojo.bos.LoginUser;
import ink.wgink.service.role.service.IRoleUserService;
import ink.wgink.service.user.enums.UserStateEnum;
import ink.wgink.service.user.enums.UserTypeEnum;
import ink.wgink.service.user.pojo.pos.UserPO;
import ink.wgink.service.user.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.kafka.common.protocol.types.Field;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import javax.servlet.http.HttpSession;
import java.util.Arrays;
import java.util.List;
public class GuestUserAuthenticationProvider implements AuthenticationProvider {
private static final Logger LOG = LoggerFactory.getLogger(GuestUserAuthenticationProvider.class);
private UserDetailServiceImpl userDetailService;
private IRoleUserService roleUserService;
private ILoginHandlerService loginHandler;
private UserLoginService userLoginService;
private HttpSession httpSession;
private GuestProperties guestProperties;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
GuestUserAuthenticationToken guestUserAuthenticationToken = (GuestUserAuthenticationToken) authentication;
String username = guestUserAuthenticationToken.getPrincipal().toString();
httpSession.setAttribute(IUserCenterConst.LOGIN_USERNAME, username);
LoginUser loginUser = (LoginUser) userDetailService.loadUserByUsername(username);
userLoginService.setLoginUserInfo(loginUser);
List<String> roleIds = roleUserService.listRoleIdByUserId(loginUser.getUserId());
if (!isGuestUser(roleIds)) {
throw new UserAuthenticationException("非访客用户");
}
// 登录逻辑处理
loginHandler(loginUser);
// 更新登录信息
userLoginService.updateUserLoginInfo(loginUser.getUserId(), loginUser.getUserName(), LoginTypeEnum.USERNAME_AND_PASSWORD.getValue());
UserAuthenticationToken userAuthenticationTokenResult = new UserAuthenticationToken(loginUser, null, loginUser.getAuthorities());
userAuthenticationTokenResult.setDetails(guestUserAuthenticationToken.getDetails());
return userAuthenticationTokenResult;
}
@Override
public boolean supports(Class<?> aClass) {
return GuestUserAuthenticationToken.class.isAssignableFrom(aClass);
}
private void loginHandler(LoginUser loginUser) {
if (loginHandler != null) {
try {
loginHandler.handle(loginUser);
} catch (Exception e) {
LOG.error(e.getMessage(), e);
throw new UserAuthenticationException("登录异常");
}
}
}
private Boolean isGuestUser(List<String> roleIds) {
for (String roleId : roleIds) {
for (String guestRoleId : guestProperties.getGuestRoleIds()) {
if (StringUtils.equals(roleId, guestRoleId)) {
return true;
}
}
}
return false;
}
public void setUserDetailService(UserDetailServiceImpl userDetailService) {
this.userDetailService = userDetailService;
}
public void setRoleUserService(IRoleUserService roleUserService) {
this.roleUserService = roleUserService;
}
public void setLoginHandler(ILoginHandlerService loginHandler) {
this.loginHandler = loginHandler;
}
public void setUserLoginService(UserLoginService userLoginService) {
this.userLoginService = userLoginService;
}
public void setHttpSession(HttpSession httpSession) {
this.httpSession = httpSession;
}
public void setGuestProperties(GuestProperties guestProperties) {
this.guestProperties = guestProperties;
}
}

View File

@ -0,0 +1,43 @@
package cn.com.tenlion.usercenter.login.guest;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;
public class GuestUserAuthenticationToken extends AbstractAuthenticationToken {
private final Object principal;
private Object credentials;
public GuestUserAuthenticationToken(Object principal, Object credentials) {
super(null);
this.principal = principal;
this.credentials = credentials;
super.setAuthenticated(true);
}
public GuestUserAuthenticationToken(Object principal, Object credentials,
Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
super.setAuthenticated(true);
}
@Override
public Object getCredentials() {
return credentials;
}
@Override
public Object getPrincipal() {
return principal;
}
@Override
public void eraseCredentials() {
super.eraseCredentials();
credentials = null;
}
}

View File

@ -0,0 +1,51 @@
package cn.com.tenlion.usercenter.login.guest;
import ink.wgink.interfaces.config.ICustomUserSecurityConfig;
import ink.wgink.interfaces.expand.login.ILoginHandlerService;
import ink.wgink.login.base.service.user.UserDetailServiceImpl;
import ink.wgink.login.base.service.user.UserLoginService;
import ink.wgink.service.role.service.IRoleUserService;
import org.springframework.beans.factory.annotation.Autowired;
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.web.DefaultSecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpSession;
@Component
public class GuestUserSecurityConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> implements ICustomUserSecurityConfig {
@Autowired
private UserDetailServiceImpl userDetailService;
@Autowired
private UserLoginService userLoginService;
@Autowired
private IRoleUserService roleUserService;
@Autowired
private ILoginHandlerService loginHandlerService;
@Autowired
private HttpSession httpSession;
@Autowired
private GuestProperties guestProperties;
@Override
public void configure(HttpSecurity builder) throws Exception {
super.configure(builder);
GuestUserAuthenticationFilter guestUserAuthenticationFilter = new GuestUserAuthenticationFilter(guestProperties.getLoginProcess());
guestUserAuthenticationFilter.setAuthenticationManager(builder.getSharedObject(AuthenticationManager.class));
guestUserAuthenticationFilter.setAuthenticationFailureHandler(new GuestUserAuthenticationFailureHandler());
GuestUserAuthenticationProvider guestUserAuthenticationProvider = new GuestUserAuthenticationProvider();
guestUserAuthenticationProvider.setUserDetailService(userDetailService);
guestUserAuthenticationProvider.setUserLoginService(userLoginService);
guestUserAuthenticationProvider.setRoleUserService(roleUserService);
guestUserAuthenticationProvider.setLoginHandler(loginHandlerService);
guestUserAuthenticationProvider.setHttpSession(httpSession);
guestUserAuthenticationProvider.setGuestProperties(guestProperties);
builder.authenticationProvider(guestUserAuthenticationProvider).addFilterBefore(guestUserAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
}

View File

@ -10,6 +10,11 @@ server:
encoding:
force-response: true
guest:
login-process: /oauth/guest-login
guest-role-ids:
- b71d2127-ed91-4f7f-9f6c-7860f6e0028c
spring:
login-url: /oauth/login
login-failure: /oauth/login?error

View File

@ -238,7 +238,7 @@
<td colspan="2">其中</td>
</tr>
<tr>
<td>重点信访人</td>
<td>涉稳重点</td>
<td>${data.petitionNum}人</td>
</tr>
<tr>
@ -254,11 +254,11 @@
<td>${data.crimeReleaseNum}人</td>
</tr>
<tr>
<td>邪教人员</td>
<td>信教群众</td>
<td>${data.cultistNum}人</td>
</tr>
<tr>
<td>吸毒人员</td>
<td>管控吸毒</td>
<td>${data.drugAddictNum}人</td>
</tr>
</tbody>