Commit 944e0d24 by yuwei

项目初始化

parent 379342bc
......@@ -2,10 +2,14 @@ package cn.datax.auth.config;
import cn.datax.auth.service.DataUserDetailService;
import cn.datax.auth.translator.DataWebResponseExceptionTranslator;
import cn.datax.common.core.DataConstant;
import cn.datax.common.core.DataUser;
import cn.datax.common.security.handler.DataAccessDeniedHandler;
import cn.datax.common.security.handler.DataAuthExceptionEntryPoint;
import cn.datax.common.security.utils.RedisTokenStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
......@@ -43,6 +47,12 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
@Autowired
private DataWebResponseExceptionTranslator exceptionTranslator;
@Autowired
private DataAccessDeniedHandler accessDeniedHandler;
@Autowired
private DataAuthExceptionEntryPoint exceptionEntryPoint;
/**
* 配置客户端详情服务
* @param clients
......@@ -60,7 +70,10 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()").allowFormAuthenticationForClients();
security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()")
.allowFormAuthenticationForClients()
.authenticationEntryPoint(exceptionEntryPoint)
.accessDeniedHandler(accessDeniedHandler);
}
/**
......@@ -71,6 +84,7 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore())
.tokenServices(tokenServices())
.userDetailsService(userDetailService)
.authenticationManager(authenticationManager)
.exceptionTranslator(exceptionTranslator);
......@@ -87,8 +101,7 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
}
@Bean
@Primary
public DefaultTokenServices defaultTokenServices(){
public DefaultTokenServices tokenServices(){
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(tokenStore());
tokenServices.setSupportRefreshToken(true);
......@@ -105,12 +118,11 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
public TokenEnhancer tokenEnhancer() {
return (accessToken, authentication) -> {
final Map<String, Object> additionalInfo = new HashMap<>();
// Object principal = authentication.getUserAuthentication().getPrincipal();
// if (principal instanceof DataUserDetail) {
// DataUserDetail user = (DataUserDetail) principal;
// additionalInfo.put("user", user);
// }
additionalInfo.put("license", "datax");
DataUser user = (DataUser) authentication.getUserAuthentication().getPrincipal();
additionalInfo.put(DataConstant.DETAILS_SECURITY_LICENSE, "datax");
additionalInfo.put(DataConstant.DETAILS_SECURITY_USER_ID, user.getId());
additionalInfo.put(DataConstant.DETAILS_SECURITY_USERNAME, user.getUsername());
additionalInfo.put(DataConstant.DETAILS_SECURITY_NICKNAME, user.getNickname());
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
return accessToken;
};
......
......@@ -40,8 +40,7 @@ public class DataResourceServerConfig extends ResourceServerConfigurerAdapter {
"/doc.html",
"/swagger-resources/**",
"/webjars/**").permitAll()
.anyRequest().permitAll()
.and().httpBasic();
.anyRequest().permitAll();
}
@Override
......
package cn.datax.auth.service;
import cn.datax.common.core.DataConstant;
import cn.datax.common.core.DataUser;
import cn.datax.common.core.R;
import cn.datax.service.system.api.entity.UserEntity;
import cn.datax.service.system.api.feign.UserServiceFeign;
import cn.datax.service.system.api.vo.RoleVo;
import cn.datax.service.system.api.vo.UserInfo;
import cn.datax.service.system.api.vo.UserVo;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.Set;
import java.util.*;
@Slf4j
@Service
......@@ -28,17 +33,12 @@ public class DataUserDetailService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
//远程获取用户
R result = userServiceFeign.getUserByUsername(s);
R result = userServiceFeign.loginByUsername(s);
log.info(JSON.toJSONString(result));
if (!StrUtil.equals("admin", s)) {
if(result == null || ObjectUtil.isEmpty(result.getData())){
throw new UsernameNotFoundException(StrUtil.format("{}用户不存在", s));
}
// if(result == null || result.getData() == null){
// throw new UsernameNotFoundException(StrUtil.format("{}用户不存在", s));
// }
// UserEntity userEntity = (UserEntity) result.getData();
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
UserInfo userInfo = JSON.parseObject(JSON.toJSONString(result.getData()), UserInfo.class);
// 可用性 :true:可用 false:不可用
boolean enabled = true;
// 过期性 :true:没过期 false:过期
......@@ -47,25 +47,21 @@ public class DataUserDetailService implements UserDetailsService {
boolean credentialsNonExpired = true;
// 锁定性 :true:未锁定 false:已锁定
boolean accountNonLocked = true;
// for (Role role : member.getRoles()) {
// //角色必须是ROLE_开头,可以在数据库中设置
// GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getRoleName());
// grantedAuthorities.add(grantedAuthority);
// //获取权限
// for (Permission permission : role.getPermissions()) {
// GrantedAuthority authority = new SimpleGrantedAuthority(permission.getUri());
// grantedAuthorities.add(authority);
// }
// }
// userRoleDao.selectAll(new UserRole().setUsername(username))
// .stream()
// .map(userRole -> new SimpleGrantedAuthority(userRole.getRole()))
// .collect(Collectors.toList());
String encode = new BCryptPasswordEncoder().encode("123456");
//123456 "$2a$10$3rV8TA7XlfVkZrP0kA0t7OqKoQa93Mw/VZii6nP62pqiD.AjKSUja"
User user = new User("admin", encode,
enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, grantedAuthorities);
// new DataUserDetail(null, grantedAuthorities);
return user;
Set<String> authsSet = new HashSet<>();
if (ArrayUtil.isNotEmpty(userInfo.getPerms())) {
authsSet.addAll(Arrays.asList(userInfo.getPerms()));
}
UserVo userVo = userInfo.getUserVo();
List<RoleVo> roles = userVo.getRoles();
if (CollUtil.isNotEmpty(roles)) {
roles.stream().filter(roleVo -> DataConstant.TRUE == roleVo.getStatus() && StrUtil.isNotBlank(roleVo.getRoleCode())).forEach(roleVo -> authsSet.add(DataConstant.ROLE + roleVo.getRoleCode()));
}
if(CollUtil.isEmpty(authsSet)){
authsSet.add(DataConstant.ROLE + "USER");
}
Collection<? extends GrantedAuthority> authorities
= AuthorityUtils.createAuthorityList(authsSet.toArray(new String[0]));
return new DataUser(userVo.getId(), userVo.getNickname(), userVo.getUsername(), userVo.getPassword(),
enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
}
}
package cn.datax.auth.translator;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
@JsonSerialize(using = DataOauthExceptionSerializer.class)
public class DataOauthException extends OAuth2Exception {
public DataOauthException(String msg) {
super(msg);
}
}
package cn.datax.auth.translator;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;
public class DataOauthExceptionSerializer extends StdSerializer<DataOauthException> {
public DataOauthExceptionSerializer() {
super(DataOauthException.class);
}
@Override
public void serialize(DataOauthException value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
gen.writeNumberField("code", value.getHttpErrorCode());
gen.writeStringField("msg", value.getMessage());
gen.writeBooleanField("success", false);
gen.writeNumberField("timestamp", System.currentTimeMillis());
gen.writeEndObject();
}
}
package cn.datax.auth.translator;
import cn.datax.common.core.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.common.exceptions.UnsupportedGrantTypeException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.common.DefaultThrowableAnalyzer;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.*;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.security.web.util.ThrowableAnalyzer;
import org.springframework.stereotype.Component;
import org.springframework.web.HttpRequestMethodNotSupportedException;
@Slf4j
@Component
public class DataWebResponseExceptionTranslator implements WebResponseExceptionTranslator {
private ThrowableAnalyzer throwableAnalyzer = new DefaultThrowableAnalyzer();
public void setThrowableAnalyzer(ThrowableAnalyzer throwableAnalyzer) {
this.throwableAnalyzer = throwableAnalyzer;
}
@Override
public ResponseEntity translate(Exception e) {
ResponseEntity.BodyBuilder status = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);
String message = "认证失败";
log.error(message, e);
public ResponseEntity<OAuth2Exception> translate(Exception e) throws Exception {
log.error(e.getMessage(), e);
// Try to extract a SpringSecurityException from the stacktrace
Throwable[] causeChain = throwableAnalyzer.determineCauseChain(e);
// 异常栈获取 OAuth2Exception 异常
Exception ase = (OAuth2Exception) throwableAnalyzer.getFirstThrowableOfType(
OAuth2Exception.class, causeChain);
// 异常栈中有OAuth2Exception
if (ase != null) {
return handleOAuth2Exception((OAuth2Exception) ase);
}
ase = (AuthenticationException) throwableAnalyzer.getFirstThrowableOfType(AuthenticationException.class,
causeChain);
if (ase != null) {
return handleOAuth2Exception(new UnauthorizedException(e.getMessage(), e));
}
ase = (AccessDeniedException) throwableAnalyzer
.getFirstThrowableOfType(AccessDeniedException.class, causeChain);
if (ase instanceof AccessDeniedException) {
return handleOAuth2Exception(new ForbiddenException(ase.getMessage(), ase));
}
ase = (HttpRequestMethodNotSupportedException) throwableAnalyzer
.getFirstThrowableOfType(HttpRequestMethodNotSupportedException.class, causeChain);
if (ase instanceof HttpRequestMethodNotSupportedException) {
return handleOAuth2Exception(new MethodNotAllowed(ase.getMessage(), ase));
}
// 不包含上述异常则服务器内部错误
return handleOAuth2Exception(new ServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), e));
}
private ResponseEntity<OAuth2Exception> handleOAuth2Exception(OAuth2Exception e) {
int status = e.getHttpErrorCode();
HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.CACHE_CONTROL, "no-store");
headers.set(HttpHeaders.PRAGMA, "no-cache");
if (status == HttpStatus.UNAUTHORIZED.value() || (e instanceof InsufficientScopeException)) {
headers.set(HttpHeaders.WWW_AUTHENTICATE, String.format("%s %s", OAuth2AccessToken.BEARER_TYPE, e.getSummary()));
}
String message = e.getMessage();
if (e instanceof UnsupportedGrantTypeException) {
message = "不支持该认证类型";
return status.body(R.error(message));
}
if (e instanceof InvalidGrantException) {
if (StringUtils.containsIgnoreCase(e.getMessage(), "Bad client credentials")) {
message = "认证失败";
return status.body(R.error(message));
}
if (StringUtils.containsIgnoreCase(e.getMessage(), "Invalid refresh token")) {
message = "refresh token无效";
return status.body(R.error(message));
}
if (StringUtils.containsIgnoreCase(e.getMessage(), "Invalid access token")) {
message = "客户端认证失败";
}else if (StringUtils.containsIgnoreCase(e.getMessage(), "Invalid refresh token")) {
message = "Refresh Token无效";
}else if (StringUtils.containsIgnoreCase(e.getMessage(), "Invalid access token")) {
message = "Token验证失败";
return status.body(R.error(message));
}
if (StringUtils.containsIgnoreCase(e.getMessage(), "Access token expired")) {
}else if (StringUtils.containsIgnoreCase(e.getMessage(), "Access token expired")) {
message = "Token过期";
return status.body(R.error(message));
}
if (StringUtils.containsIgnoreCase(e.getMessage(), "locked")) {
}else if (StringUtils.containsIgnoreCase(e.getMessage(), "locked")) {
message = "用户已被锁定,请联系管理员";
return status.body(R.error(message));
}else if (StringUtils.containsIgnoreCase(e.getMessage(), "Bad credentials")) {
message = "用户名或密码错误";
}
message = "用户名或密码错误";
return status.body(R.error(message));
}
return status.body(R.error(message));
return new ResponseEntity<>(new DataOauthException(message), headers, HttpStatus.valueOf(status));
}
@SuppressWarnings("serial")
private static class ForbiddenException extends OAuth2Exception {
public ForbiddenException(String msg, Throwable t) {
super(msg, t);
}
@Override
public String getOAuth2ErrorCode() {
return "access_denied";
}
@Override
public int getHttpErrorCode() {
return 403;
}
}
@SuppressWarnings("serial")
private static class ServerErrorException extends OAuth2Exception {
public ServerErrorException(String msg, Throwable t) {
super(msg, t);
}
@Override
public String getOAuth2ErrorCode() {
return "server_error";
}
@Override
public int getHttpErrorCode() {
return 500;
}
}
@SuppressWarnings("serial")
private static class UnauthorizedException extends OAuth2Exception {
public UnauthorizedException(String msg, Throwable t) {
super(msg, t);
}
@Override
public String getOAuth2ErrorCode() {
return "unauthorized";
}
@Override
public int getHttpErrorCode() {
return 401;
}
}
@SuppressWarnings("serial")
private static class MethodNotAllowed extends OAuth2Exception {
public MethodNotAllowed(String msg, Throwable t) {
super(msg, t);
}
@Override
public String getOAuth2ErrorCode() {
return "method_not_allowed";
}
@Override
public int getHttpErrorCode() {
return 405;
}
}
}
......@@ -79,6 +79,10 @@
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
......@@ -50,13 +50,4 @@ public abstract class BaseEntity implements Serializable {
*/
@TableField(value = "status", fill = FieldFill.INSERT)
private Integer status;
/**
* 逻辑删除(1正常,0已删除)
*/
@TableLogic
@TableField(value = "deleted", fill = FieldFill.INSERT)
@JsonIgnore
private Integer deleted;
}
......@@ -16,4 +16,20 @@ public class DataConstant {
* OAUTH2 令牌类型
*/
public static final String OAUTH2_TOKEN_TYPE = "bearer ";
public static String ROLE = "ROLE_";
public static int TRUE = 1;
public static int FALSE = 0;
public static String DETAILS_SECURITY_LICENSE = "license";
public static String DETAILS_SECURITY_DATAX_USER = "datax_user";
public static String DETAILS_SECURITY_USER_ID = "user_id";
public static String DETAILS_SECURITY_USERNAME = "username";
public static String DETAILS_SECURITY_NICKNAME = "nickname";
public static String DETAILS_SECURITY_USER_DEPT = "user_dept";
public static String DETAILS_SECURITY_USER_ROLE = "user_role";
public static String DETAILS_SECURITY_USER_POST = "user_post";
}
package cn.datax.common.core;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import java.util.Collection;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = true)
public class DataUser extends User {
private String id;
private String nickname;
private List<String> depts;
private List<String> roles;
private List<String> posts;
public DataUser(String id, String nickname, String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
this.id = id;
this.nickname = nickname;
}
}
package cn.datax.common.utils;
import cn.datax.common.core.DataUser;
import org.springframework.security.core.context.SecurityContextHolder;
public class SecurityUtil {
/**
* 获取用户
*
* @return user
*/
public static DataUser getDataUser() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof DataUser) {
DataUser user = (DataUser) principal;
return user;
}
return null;
}
/**
* 获取用户ID
*
* @return id
*/
public static String getUserId() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof DataUser) {
DataUser user = (DataUser) principal;
return user.getId();
}
return null;
}
/**
* 获取用户名称
*
* @return username
*/
public static String getUserName() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof DataUser) {
DataUser user = (DataUser) principal;
return user.getUsername();
}
return null;
}
}
......@@ -31,6 +31,11 @@
<artifactId>p6spy</artifactId>
<version>${p6spy.version}</version>
</dependency>
<dependency>
<groupId>cn.datax</groupId>
<artifactId>datax-common-core</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package cn.datax.common.mybatis.config;
import cn.datax.common.utils.SecurityUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
......@@ -12,10 +14,25 @@ public class DataMetaObjectHandler implements MetaObjectHandler {
this.setInsertFieldValByName("createTime", LocalDateTime.now(), metaObject);
this.setInsertFieldValByName("updateTime", LocalDateTime.now(), metaObject);
this.setInsertFieldValByName("status", 1, metaObject);
String userId = getUserId();
if(StrUtil.isNotBlank(userId)){
this.setInsertFieldValByName("createBy", userId, metaObject);
this.setInsertFieldValByName("updateBy", userId, metaObject);
}
}
@Override
public void updateFill(MetaObject metaObject) {
this.setUpdateFieldValByName("updateTime", LocalDateTime.now(), metaObject);
String userId = getUserId();
if(StrUtil.isNotBlank(userId)){
this.setInsertFieldValByName("updateBy", userId, metaObject);
}
}
private String getUserId() {
String userId = SecurityUtil.getUserId();
return userId;
}
}
......@@ -34,6 +34,11 @@
<artifactId>datax-common-core</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>cn.datax</groupId>
<artifactId>datax-common-redis</artifactId>
<version>${app.version}</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
......@@ -16,6 +16,6 @@ public class DataAuthExceptionEntryPoint implements AuthenticationEntryPoint {
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
ResponseUtil.makeResponse(
response, MediaType.APPLICATION_JSON_UTF8_VALUE,
HttpServletResponse.SC_UNAUTHORIZED, R.error("token无效"));
HttpServletResponse.SC_UNAUTHORIZED, R.error("无效的Token"));
}
}
package cn.datax.common.security.utils;
import cn.datax.common.core.DataConstant;
import cn.datax.common.core.DataUser;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.provider.token.UserAuthenticationConverter;
import org.springframework.util.StringUtils;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 根据checktoken的结果转化用户信息
*/
public class DataUserAuthenticationConverter implements UserAuthenticationConverter {
private static final String N_A = "N/A";
private Collection<? extends GrantedAuthority> defaultAuthorities;
public void setDefaultAuthorities(String[] defaultAuthorities) {
this.defaultAuthorities = AuthorityUtils.commaSeparatedStringToAuthorityList(StringUtils.arrayToCommaDelimitedString(defaultAuthorities));
}
@Override
public Map<String, ?> convertUserAuthentication(Authentication authentication) {
Map<String, Object> response = new LinkedHashMap();
response.put(USERNAME, authentication.getName());
if (authentication.getAuthorities() != null && !authentication.getAuthorities().isEmpty()) {
response.put(AUTHORITIES, AuthorityUtils.authorityListToSet(authentication.getAuthorities()));
}
return response;
}
@Override
public Authentication extractAuthentication(Map<String, ?> map) {
if (map.containsKey(USERNAME)) {
Object principal = map.get(USERNAME);
Collection<? extends GrantedAuthority> authorities = this.getAuthorities(map);
String id = (String) map.get(DataConstant.DETAILS_SECURITY_USER_ID);
String username = (String) map.get(DataConstant.DETAILS_SECURITY_USERNAME);
String nickname = (String) map.get(DataConstant.DETAILS_SECURITY_USERNAME);
DataUser user = new DataUser(id, nickname, username, N_A, true
, true, true, true, authorities);
return new UsernamePasswordAuthenticationToken(user, N_A, authorities);
} else {
return null;
}
}
private Collection<? extends GrantedAuthority> getAuthorities(Map<String, ?> map) {
if (!map.containsKey(AUTHORITIES)) {
return this.defaultAuthorities;
} else {
Object authorities = map.get(AUTHORITIES);
if (authorities instanceof String) {
return AuthorityUtils.commaSeparatedStringToAuthorityList((String)authorities);
} else if (authorities instanceof Collection) {
return AuthorityUtils.commaSeparatedStringToAuthorityList(StringUtils.collectionToCommaDelimitedString((Collection)authorities));
} else {
throw new IllegalArgumentException("Authorities must be either a String or a Collection");
}
}
}
}
package cn.datax.auth.config;
package cn.datax.common.security.utils;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
......
......@@ -6,7 +6,6 @@
<resultMap id="BaseResultMap" type="cn.datax.service.file.api.entity.FileEntity">
<result column="id" property="id" />
<result column="status" property="status" />
<result column="deleted" property="deleted" />
<result column="create_by" property="createBy" />
<result column="create_time" property="createTime" />
<result column="update_by" property="updateBy" />
......@@ -22,7 +21,6 @@
<sql id="Base_Column_List">
id,
status,
deleted,
create_by,
create_time,
update_by,
......
......@@ -9,6 +9,6 @@ import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(contextId = "userServiceFeign", value = "datax-service-system", fallbackFactory = UserServiceFeignFallbackFactory.class)
public interface UserServiceFeign {
@GetMapping("/users/username/{username}")
R getUserByUsername(@PathVariable("username") String username);
@GetMapping("/inner/login/username/{username}")
R loginByUsername(@PathVariable("username") String username);
}
......@@ -12,7 +12,7 @@ public class UserServiceFeignFallbackImpl implements UserServiceFeign {
private final Throwable cause;
@Override
public R getUserByUsername(String username) {
public R loginByUsername(String username) {
log.error("feign 调用用户{}出错,信息:{}", username, cause.getLocalizedMessage());
return null;
}
......
......@@ -3,6 +3,7 @@ package cn.datax.service.system.api.vo;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class RoleVo implements Serializable {
......@@ -13,4 +14,5 @@ public class RoleVo implements Serializable {
private Integer status;
private String roleName;
private String roleCode;
private List<MenuVo> menus;
}
package cn.datax.service.system.api.vo;
import lombok.Data;
import java.io.Serializable;
@Data
public class UserInfo implements Serializable {
private static final long serialVersionUID=1L;
/**
* 用户基本信息
*/
private UserVo userVo;
/**
* 权限标识集合
*/
private String[] perms;
}
......@@ -15,6 +15,7 @@ public class UserVo implements Serializable {
private String id;
private Integer status;
private String username;
private String password;
private String nickname;
private String email;
private String phone;
......
package cn.datax.service.system.config;
import cn.datax.common.security.utils.DataUserAuthenticationConverter;
import cn.datax.common.security.handler.DataAccessDeniedHandler;
import cn.datax.common.security.handler.DataAuthExceptionEntryPoint;
import cn.datax.common.security.utils.RedisTokenStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
......@@ -11,9 +13,8 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import org.springframework.security.oauth2.provider.token.*;
import org.springframework.web.client.RestTemplate;
@Configuration
@EnableResourceServer
......@@ -29,8 +30,11 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Autowired
private RemoteTokenServices tokenService;
// @Autowired
// private RemoteTokenServices remoteTokenServices;
//
// @Autowired
// private RestTemplate restTemplate;
@Bean
public TokenStore redisTokenStore() {
......@@ -38,10 +42,18 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
public void configure(ResourceServerSecurityConfigurer resources) {
//token不对的时候验证返还不了信息
// DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter();
// UserAuthenticationConverter userAuthenticationConverter = new DataUserAuthenticationConverter();
// accessTokenConverter.setUserTokenConverter(userAuthenticationConverter);
//
// remoteTokenServices.setRestTemplate(restTemplate);
// remoteTokenServices.setAccessTokenConverter(accessTokenConverter);
resources
.tokenStore(redisTokenStore())
.tokenServices(tokenService)
// .tokenServices(remoteTokenServices)
.authenticationEntryPoint(exceptionEntryPoint)
.accessDeniedHandler(accessDeniedHandler);
}
......@@ -59,7 +71,7 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
"/swagger-resources/**",
"/webjars/**",
// feign 内部调用不用授权
"/users/username/**"
"/inner/**"
).permitAll()
.anyRequest().authenticated()
.and().csrf().disable();
......
package cn.datax.service.system.controller;
import cn.datax.common.base.BaseController;
import cn.datax.common.core.DataUser;
import cn.datax.common.core.R;
import cn.datax.common.security.annotation.DataInner;
import cn.datax.common.utils.SecurityUtil;
import cn.datax.service.system.api.vo.UserInfo;
import cn.datax.service.system.service.UserService;
import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/inner")
public class LoginController extends BaseController {
@Autowired
private UserService userService;
@Autowired
private TokenStore tokenStore;
@GetMapping("/token")
public R getTokenUser() {
DataUser user = SecurityUtil.getDataUser();
return R.ok().setData(user);
}
@DataInner
@GetMapping("/login/username/{username}")
public R loginByUsername(@PathVariable String username) {
UserInfo userInfo = userService.getUserByUsername(username);
return R.ok().setData(userInfo);
}
@DeleteMapping("/logout/{token}")
public R logout(@PathVariable("token") String token) {
if (StrUtil.isBlank(token)) {
return R.error("退出失败,Token为空");
}
OAuth2AccessToken accessToken = tokenStore.readAccessToken(token);
if (accessToken == null || StrUtil.isBlank(accessToken.getValue())) {
return R.ok();
}
tokenStore.removeAccessToken(accessToken);
OAuth2RefreshToken refreshToken = accessToken.getRefreshToken();
tokenStore.removeRefreshToken(refreshToken);
return R.ok();
}
}
package cn.datax.service.system.controller;
import cn.datax.common.core.R;
import cn.datax.common.security.annotation.DataInner;
import cn.datax.common.validate.ValidateGroupForSave;
import cn.datax.common.validate.ValidateGroupForUpdate;
import cn.datax.service.system.api.dto.UserDto;
......@@ -20,6 +19,7 @@ import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
......@@ -53,16 +53,6 @@ public class UserController extends BaseController {
return R.ok().setData(userMapper.toVO(userEntity));
}
@DataInner
@ApiOperation(value = "获取用户详细信息", notes = "根据url的username来获取用户详细信息")
@ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String", paramType = "path")
@GetMapping("/username/{username}")
public R getUserByUsername(@PathVariable String username) {
UserEntity userEntity = userService.getOne(Wrappers.<UserEntity>query()
.lambda().eq(UserEntity::getUsername, username));
return R.ok().setData(userMapper.toVO(userEntity));
}
@ApiOperation(value = "用户分页查询", notes = "")
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNum", value = "当前页码", required = true, dataType = "int", example = "1"),
......@@ -110,6 +100,7 @@ public class UserController extends BaseController {
return R.ok();
}
@PreAuthorize("hasAuthority('user:delete')")
@ApiOperation(value = "删除用户", notes = "根据url的id来指定删除对象")
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "String", paramType = "path")
@DeleteMapping("/{id}")
......
......@@ -4,6 +4,8 @@ import cn.datax.service.system.api.entity.MenuEntity;
import cn.datax.common.base.BaseDao;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* <p>
* Mapper 接口
......@@ -15,4 +17,5 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface MenuDao extends BaseDao<MenuEntity> {
List<MenuEntity> selectMenuByRoleIds(List<String> roleIds);
}
......@@ -4,6 +4,7 @@ import cn.datax.common.base.BaseService;
import cn.datax.service.system.api.dto.UserDto;
import cn.datax.service.system.api.dto.UserPasswordDto;
import cn.datax.service.system.api.entity.UserEntity;
import cn.datax.service.system.api.vo.UserInfo;
/**
* <p>
......@@ -22,4 +23,6 @@ public interface UserService extends BaseService<UserEntity> {
void deleteUserById(String id);
void updateUserPassword(UserPasswordDto user);
UserInfo getUserByUsername(String username);
}
package cn.datax.service.system.service.impl;
import cn.datax.common.core.DataConstant;
import cn.datax.common.exception.DataException;
import cn.datax.service.system.api.dto.UserDto;
import cn.datax.service.system.api.dto.UserPasswordDto;
import cn.datax.service.system.api.entity.UserDeptEntity;
import cn.datax.service.system.api.entity.UserEntity;
import cn.datax.service.system.api.entity.UserPostEntity;
import cn.datax.service.system.api.entity.UserRoleEntity;
import cn.datax.service.system.dao.UserDao;
import cn.datax.service.system.dao.UserDeptDao;
import cn.datax.service.system.dao.UserRoleDao;
import cn.datax.service.system.dao.UserPostDao;
import cn.datax.service.system.api.entity.*;
import cn.datax.service.system.api.vo.RoleVo;
import cn.datax.service.system.api.vo.UserInfo;
import cn.datax.service.system.api.vo.UserVo;
import cn.datax.service.system.dao.*;
import cn.datax.service.system.mapstruct.UserMapper;
import cn.datax.service.system.service.UserService;
import cn.datax.common.base.BaseServiceImpl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -22,7 +22,9 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
......@@ -46,6 +48,8 @@ public class UserServiceImpl extends BaseServiceImpl<UserDao, UserEntity> implem
@Autowired
private UserRoleDao userRoleDao;
@Autowired
private MenuDao menuDao;
@Autowired
private UserMapper userMapper;
@Override
......@@ -132,5 +136,31 @@ public class UserServiceImpl extends BaseServiceImpl<UserDao, UserEntity> implem
String passwordEncode = new BCryptPasswordEncoder().encode(userPasswordDto.getPassword());
userDao.updateUserPassword(passwordEncode, userPasswordDto.getId());
}
@Override
public UserInfo getUserByUsername(String username) {
UserInfo userInfo = new UserInfo();
UserEntity userEntity = userDao.selectOne(Wrappers.<UserEntity>query()
.lambda().eq(UserEntity::getUsername, username));
if(null != userEntity){
UserVo userVo = userMapper.toVO(userEntity);
userInfo.setUserVo(userVo);
if(CollUtil.isNotEmpty(userVo.getRoles())){
Set<String> permissions = new HashSet<>();
List<String> roleIds = userVo.getRoles().stream()
.filter(roleVo -> DataConstant.TRUE == roleVo.getStatus())
.map(RoleVo::getId).collect(Collectors.toList());
List<MenuEntity> menuEntitys = menuDao.selectMenuByRoleIds(roleIds);
if(CollUtil.isNotEmpty(menuEntitys)){
List<String> permissionList = menuEntitys.stream().filter(menuEntity -> StrUtil.isNotBlank(menuEntity.getMenuPerms()))
.map(MenuEntity::getMenuPerms)
.collect(Collectors.toList());
permissions.addAll(permissionList);
userInfo.setPerms(ArrayUtil.toArray(permissions, String.class));
}
}
}
return userInfo;
}
}
......@@ -5,7 +5,6 @@
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.datax.service.system.api.entity.DeptEntity">
<result column="id" property="id" />
<result column="deleted" property="deleted" />
<result column="create_by" property="createBy" />
<result column="create_time" property="createTime" />
<result column="update_by" property="updateBy" />
......@@ -18,7 +17,6 @@
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
deleted,
create_by,
create_time,
update_by,
......
......@@ -5,7 +5,6 @@
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.datax.service.system.api.entity.MenuEntity">
<result column="id" property="id" />
<result column="deleted" property="deleted" />
<result column="create_by" property="createBy" />
<result column="create_time" property="createTime" />
<result column="update_by" property="updateBy" />
......@@ -24,7 +23,6 @@
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
deleted,
create_by,
create_time,
update_by,
......@@ -32,4 +30,17 @@
parent_id, menu_name, menu_path, menu_component, menu_perms, menu_icon, menu_type, menu_sort, status
</sql>
<select id="selectMenuByRoleIds" parameterType="java.util.List" resultMap="BaseResultMap">
select
m.id, m.create_by, m.create_time, m.update_by, m.update_time,
m.parent_id, m.menu_name, m.menu_path, m.menu_component, m.menu_perms, m.menu_icon, m.menu_type, m.menu_sort, m.status
from
sys_menu m
left join sys_role_menu rm om m.id = rm.menu_id
where m.status = 1 and rm.role_id in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
</mapper>
......@@ -5,7 +5,6 @@
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.datax.service.system.api.entity.PostEntity">
<result column="id" property="id" />
<result column="deleted" property="deleted" />
<result column="create_by" property="createBy" />
<result column="create_time" property="createTime" />
<result column="update_by" property="updateBy" />
......@@ -17,7 +16,6 @@
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
deleted,
create_by,
create_time,
update_by,
......
......@@ -5,7 +5,6 @@
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.datax.service.system.api.entity.RoleEntity">
<result column="id" property="id" />
<result column="deleted" property="deleted" />
<result column="create_by" property="createBy" />
<result column="create_time" property="createTime" />
<result column="update_by" property="updateBy" />
......@@ -18,7 +17,6 @@
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
deleted,
create_by,
create_time,
update_by,
......
......@@ -5,7 +5,6 @@
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.datax.service.system.api.entity.UserEntity">
<result column="id" property="id" />
<result column="deleted" property="deleted" />
<result column="create_by" property="createBy" />
<result column="create_time" property="createTime" />
<result column="update_by" property="updateBy" />
......@@ -22,7 +21,6 @@
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
deleted,
create_by,
create_time,
update_by,
......
......@@ -113,7 +113,7 @@ public class CodeGenerator {
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setSuperEntityClass("cn.datax.common.base.BaseEntity");
// 写于父类中的公共字段
strategy.setSuperEntityColumns(new String[]{"id", "create_time", "create_by", "update_time", "update_by", "status", "deleted"});
strategy.setSuperEntityColumns(new String[]{"id", "create_time", "create_by", "update_time", "update_by", "status"});
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
// 公共父类
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment