新增postgresql适配

This commit is contained in:
zhuyijun 2022-09-21 20:14:03 +08:00
parent d675d07254
commit 42e55f0d06
79 changed files with 1065 additions and 400 deletions

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,65 @@
CREATE TABLE oauth_client_details (
client_id varchar(255) NOT NULL,
resource_ids varchar(255) DEFAULT NULL,
client_secret varchar(255) DEFAULT NULL,
scope varchar(255) DEFAULT NULL,
authorized_grant_types varchar(255) DEFAULT NULL,
web_server_redirect_uri varchar(255) DEFAULT NULL,
authorities varchar(255) DEFAULT NULL,
access_token_validity int DEFAULT NULL,
refresh_token_validity int DEFAULT NULL,
additional_information text ,
create_time timestamp WITH TIME ZONE NOT NULL DEFAULT NOW(),
archived smallint DEFAULT 0,
trusted smallint DEFAULT 0,
autoapprove varchar(255) DEFAULT 'false',
PRIMARY KEY (client_id)
);
INSERT INTO oauth_client_details (client_id, resource_ids, client_secret, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, create_time, archived, trusted, autoapprove) VALUES ('zyjblogs-oauth','zyjblogs-oauth,zyjblogs-rbac','$2a$10$Wk2w4OX5DpFgG3rBuhPnnulCSOIuU3TZhpWjaOq39LZnL.p0LJila','all','authorization_code,password,client_credentials,implicit,refresh_token','http://localhost:9019/',NULL,NULL,NULL,NULL,'2022-08-18 06:14:32',0,0,'false'),('zyjblogs-rbac','zyjblogs-rbac,zyjblogs-oauth','$2a$10$Wk2w4OX5DpFgG3rBuhPnnulCSOIuU3TZhpWjaOq39LZnL.p0LJila','all','authorization_code,password,client_credentials,implicit,refresh_token','http://localhost:9029/',NULL,NULL,NULL,NULL,'2022-08-18 00:34:24',0,0,'false');
CREATE TABLE oauth_code (
create_time timestamp WITH TIME ZONE NOT NULL DEFAULT NOW(),
code varchar(255) DEFAULT NULL,
authentication bytea
) ;
create index code_index on oauth_code(code);
CREATE TABLE role (
id varchar(64) NOT NULL,
name varchar(64) DEFAULT NULL ,
status int DEFAULT NULL ,
deleted smallint DEFAULT 0,
description varchar(600) ,
create_user_id varchar(64) ,
create_time timestamp WITH TIME ZONE NOT NULL DEFAULT NOW(),
edit_user_id varchar(64) ,
edit_time timestamp WITH TIME ZONE NOT NULL DEFAULT NOW(),
tenant_id varchar(100) NOT NULL DEFAULT '',
PRIMARY KEY (id)
);
CREATE TABLE "user" (
id varchar(64) NOT NULL ,
username varchar(64) NOT NULL ,
name varchar(64) DEFAULT NULL ,
age int DEFAULT NULL ,
avatar varchar(255) DEFAULT NULL ,
password varchar(255) DEFAULT NULL,
phone char(11) DEFAULT NULL ,
email varchar(64) DEFAULT NULL ,
invite_user_id varchar(64) DEFAULT NULL ,
status int DEFAULT NULL ,
follow_num int DEFAULT NULL ,
fans_num int DEFAULT NULL ,
deleted smallint DEFAULT 0,
description varchar(600) DEFAULT NULL,
create_user_id varchar(64) ,
create_time timestamp WITH TIME ZONE NOT NULL DEFAULT NOW(),
edit_user_id varchar(64) ,
edit_time timestamp WITH TIME ZONE NOT NULL DEFAULT NOW(),
tenant_id varchar(100) NOT NULL DEFAULT '',
PRIMARY KEY (id)
);
create index username_index on "user"(username);
INSERT INTO "user" (id, username, name, age, avatar, password, phone, email, invite_user_id, status, follow_num, fans_num, deleted, description, create_user_id, create_time, edit_user_id, edit_time, tenant_id) VALUES ('1','admin','admin',1,NULL,'$2a$10$4DlfvZrq7zgKzkbKyg.GHO6yHdGnozcaf3B5JSAC0fNB4k1GhMk6y',NULL,NULL,NULL,0,NULL,NULL,0,NULL,NULL,now(),NULL,now(),'');

View File

@ -106,6 +106,11 @@
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.gateway;
package cn.zyjblogs;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.gateway.filter;
package cn.zyjblogs.filter;
import cn.zyjblogs.starter.common.entity.constant.HttpHeaderConstant;
import cn.zyjblogs.starter.common.entity.response.ResponseObject;

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.gateway.filter;
package cn.zyjblogs.filter;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

View File

@ -1,7 +1,5 @@
package cn.zyjblogs.oauth;
package cn.zyjblogs;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.annotation.MapperScans;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.oauth.config.handler;
package cn.zyjblogs.config.handler;
import cn.zyjblogs.starter.common.entity.response.HttpCode;
import cn.zyjblogs.starter.common.entity.response.ResponseResult;

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.oauth.config.handler;
package cn.zyjblogs.config.handler;
import cn.zyjblogs.starter.common.entity.response.HttpCode;
import cn.zyjblogs.starter.common.entity.response.ResponseResult;

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.oauth.config.rsa;
package cn.zyjblogs.config.rsa;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.oauth.config.rsa;
package cn.zyjblogs.config.rsa;
import lombok.Getter;

View File

@ -1,18 +1,16 @@
package cn.zyjblogs.oauth.config.security;
package cn.zyjblogs.config.security;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
@ -37,11 +35,10 @@ public class AuthorizationServerConfiguration extends AuthorizationServerConfigu
private final TokenStore tokenStore;
private final AuthenticationManager authenticationManager;
private final JwtAccessTokenConverter accessTokenConverter;
private final PasswordEncoder passwordEncoder;
private final DataSource dataSource;
private final JwtTokenEnhancer jwtTokenEnhancer;
private final OauthResponseExceptionTranslator oAuthResponseExceptionTranslator;
private final ClientDetailsService oauthClientDetailsService;
/**
* 令牌端点的安全约束
*
@ -123,9 +120,9 @@ public class AuthorizationServerConfiguration extends AuthorizationServerConfigu
@Bean
public ClientDetailsService clientDetails(DataSource dataSource) {
JdbcClientDetailsService jdbcClientDetailsService = new JdbcClientDetailsService(dataSource);
jdbcClientDetailsService.setPasswordEncoder(passwordEncoder);
return jdbcClientDetailsService;
// JdbcClientDetailsService jdbcClientDetailsService = new JdbcClientDetailsService(dataSource);
// jdbcClientDetailsService.setPasswordEncoder(passwordEncoder);
return oauthClientDetailsService;
}
@Bean

View File

@ -1,6 +1,6 @@
package cn.zyjblogs.oauth.config.security;
package cn.zyjblogs.config.security;
import cn.zyjblogs.oauth.config.rsa.RsaKeyProperties;
import cn.zyjblogs.config.rsa.RsaKeyProperties;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.IOUtils;
import org.springframework.context.annotation.Bean;

View File

@ -1,6 +1,6 @@
package cn.zyjblogs.oauth.config.security;
package cn.zyjblogs.config.security;
import cn.zyjblogs.oauth.server.user.po.OauthUserDetails;
import cn.zyjblogs.server.user.po.OauthUserDetails;
import cn.zyjblogs.starter.common.entity.constant.ContextKeyConstant;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.oauth.config.security;
package cn.zyjblogs.config.security;
import cn.zyjblogs.starter.common.entity.constant.ContextKeyConstant;
import cn.zyjblogs.starter.common.entity.context.BaseContext;

View File

@ -1,21 +1,17 @@
package cn.zyjblogs.oauth.config.security;
package cn.zyjblogs.config.security;
import cn.zyjblogs.oauth.server.user.po.OauthUserDetails;
import lombok.RequiredArgsConstructor;
import cn.zyjblogs.server.user.po.OauthUserDetails;
import cn.zyjblogs.starter.common.entity.response.HttpCode;
import cn.zyjblogs.starter.common.exception.AuthRuntimeException;
import lombok.extern.log4j.Log4j2;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
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.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
@ -50,7 +46,7 @@ public class OauthAuthenticationProvider extends DaoAuthenticationProvider {
UserDetails user = userDetailsService.loadUserByUsername(username);
if (user == null){
this.logger.debug("用户不存在");
throw new RuntimeException("用户不存在");
throw new AuthRuntimeException(HttpCode.UNAUTHORIZED,"用户不存在");
}
OauthUserDetails userDetails = (OauthUserDetails) user;
//比较前端传入的密码明文和数据库中加密的密码是否相等
@ -60,9 +56,7 @@ public class OauthAuthenticationProvider extends DaoAuthenticationProvider {
}
//获取用户权限信息
Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();
authorities.forEach(x -> {
log.info("{}", x);
});
authorities.forEach(x -> log.info("{}", x));
return new UsernamePasswordAuthenticationToken(userDetails, password, authorities);
}

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.oauth.config.security;
package cn.zyjblogs.config.security;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;

View File

@ -1,15 +1,12 @@
package cn.zyjblogs.oauth.config.security;
package cn.zyjblogs.config.security;
import cn.zyjblogs.server.user.po.OauthUserDetails;
import cn.zyjblogs.starter.common.entity.constant.ContextKeyConstant;
import cn.zyjblogs.oauth.server.user.po.OauthUserDetails;
import cn.zyjblogs.starter.common.entity.context.BaseContext;
import cn.zyjblogs.starter.common.entity.dto.ContextDto;
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.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.oauth.config.security;
package cn.zyjblogs.config.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@ -1,7 +1,7 @@
package cn.zyjblogs.oauth.config.security;
package cn.zyjblogs.config.security;
import cn.zyjblogs.oauth.config.handler.ResourceAccessDeniedHandler;
import cn.zyjblogs.oauth.config.handler.ResourceAuthenticationEntryPoint;
import cn.zyjblogs.config.handler.ResourceAccessDeniedHandler;
import cn.zyjblogs.config.handler.ResourceAuthenticationEntryPoint;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;

View File

@ -1,6 +1,6 @@
package cn.zyjblogs.oauth.config.security;
package cn.zyjblogs.config.security;
import cn.zyjblogs.oauth.server.user.service.impl.OauthUserDetailsServiceImpl;
import cn.zyjblogs.server.user.service.impl.OauthUserDetailsServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@ -1,78 +0,0 @@
package cn.zyjblogs.oauth.server.user.po;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.provider.ClientDetails;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
/**
* @author zhuyijun
*/
public class OauthClientDetail implements ClientDetails {
@Override
public String getClientId() {
return null;
}
@Override
public Set<String> getResourceIds() {
return null;
}
@Override
public boolean isSecretRequired() {
return false;
}
@Override
public String getClientSecret() {
return null;
}
@Override
public boolean isScoped() {
return false;
}
@Override
public Set<String> getScope() {
return null;
}
@Override
public Set<String> getAuthorizedGrantTypes() {
return null;
}
@Override
public Set<String> getRegisteredRedirectUri() {
return null;
}
@Override
public Collection<GrantedAuthority> getAuthorities() {
return null;
}
@Override
public Integer getAccessTokenValiditySeconds() {
return null;
}
@Override
public Integer getRefreshTokenValiditySeconds() {
return null;
}
@Override
public boolean isAutoApprove(String s) {
return false;
}
@Override
public Map<String, Object> getAdditionalInformation() {
return null;
}
}

View File

@ -1,56 +0,0 @@
package cn.zyjblogs.oauth.server.user.service;
import cn.zyjblogs.oauth.server.user.dto.AuthorizationCodeDto;
import cn.zyjblogs.oauth.server.user.dto.OAuth2AccessTokenDto;
import cn.zyjblogs.oauth.server.user.dto.UserLoginDto;
import cn.zyjblogs.oauth.server.user.vo.OAuth2AccessTokenVo;
/**
* 登录
*
* @author zhuyijun
*/
public interface LoginService {
/**
* 登录接口
*
* @param userLoginDto
* @return cn.zyjblogs.oauth.server.user.vo.OAuth2AccessTokenVo
* @author zhuyijun
* @date 2022/9/17 下午5:11
*/
OAuth2AccessTokenVo login(UserLoginDto userLoginDto);
/**
* 退出
*
* @param
* @return void
* @author zhuyijun
* @date 2022/9/17 下午5:53
*/
void logout();
/**
* 刷新token
*
* @param oAuth2AccessTokenDto
* @return
*/
OAuth2AccessTokenVo refreshToken(OAuth2AccessTokenDto oAuth2AccessTokenDto);
/**
* 检测token信息
*
* @param oAuth2AccessTokenDto
* @return
*/
OAuth2AccessTokenVo checkToken(OAuth2AccessTokenDto oAuth2AccessTokenDto);
/**
* 获取授权码
*
* @param authorizationCodeDto
*/
void getAuthorizationCode(AuthorizationCodeDto authorizationCodeDto);
}

View File

@ -0,0 +1,8 @@
package cn.zyjblogs.server.client.constant;
/**
* @author zhuyijun
*/
public class ClientConstant {
public static final String REDIS_KEY = "oauth:clients";
}

View File

@ -0,0 +1,12 @@
package cn.zyjblogs.server.client.mapper;
import cn.zyjblogs.server.client.po.OauthClientDetail;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author zhuyijun
*/
@Mapper
public interface OauthClientDetailsMapper extends BaseMapper<OauthClientDetail> {
}

View File

@ -0,0 +1,275 @@
package cn.zyjblogs.server.client.po;
import cn.zyjblogs.starter.common.utils.bean.BeanUtils;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.util.StringUtils;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* @author zhuyijun
*/
@org.codehaus.jackson.map.annotate.JsonSerialize(
include = org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_DEFAULT
)
@JsonIgnoreProperties(
ignoreUnknown = true
)
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
@com.fasterxml.jackson.annotation.JsonIgnoreProperties(
ignoreUnknown = true
)
@TableName("oauth_client_details")
public class OauthClientDetail implements ClientDetails , Serializable {
@TableId("client_id")
private String clientId;
@TableField("client_secret")
private String clientSecret;
@TableField("resource_ids")
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
private String resourceIds;
@TableField("scope")
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
private String scope;
@TableField("authorized_grant_types")
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
private String authorizedGrantTypes;
@TableField("web_server_redirect_uri")
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
private String webServerRedirectUri;
@TableField("authorities")
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
private String authorities;
@TableField("access_token_validity")
private String accessTokenValidity;
@TableField("refresh_token_validity")
private String refreshTokenValidity;
@TableField("additional_information")
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
private String additionalInformation;
@TableField("create_time")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@TableField("archived")
@JsonProperty("archived")
@com.fasterxml.jackson.annotation.JsonProperty("archived")
private Integer archived;
@TableField("trusted")
@JsonProperty("trusted")
@com.fasterxml.jackson.annotation.JsonProperty("trusted")
private Integer trusted;
@TableField("autoapprove")
private String autoapprove;
@TableField(exist = false)
@JsonProperty("access_token_validity")
@com.fasterxml.jackson.annotation.JsonProperty("access_token_validity")
private Integer accessTokenValiditySeconds;
@TableField(exist = false)
@JsonProperty("access_token_validity")
@com.fasterxml.jackson.annotation.JsonProperty("refresh_token_validity")
private Integer refreshTokenValiditySeconds;
public OauthClientDetail() {
}
public OauthClientDetail(ClientDetails prototype){
this();
this.setAccessTokenValiditySeconds(prototype.getAccessTokenValiditySeconds());
this.setRefreshTokenValiditySeconds(prototype.getRefreshTokenValiditySeconds());
Collection<GrantedAuthority> authorities = prototype.getAuthorities();
this.setAuthorities(JSON.toJSONString(authorities));
this.setAuthorizedGrantTypes(String.join(",",prototype.getAuthorizedGrantTypes()));
this.setClientId(prototype.getClientId());
this.setClientSecret(prototype.getClientSecret());
this.setWebServerRedirectUri(String.join(",",prototype.getRegisteredRedirectUri()));
this.setScope(String.join(",",prototype.getScope()));
this.setResourceIds(String.join(",",prototype.getResourceIds()));
}
@Override
public String getClientId() {
return clientId;
}
@Override
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
public Set<String> getResourceIds() {
return Set.of(resourceIds.split(","));
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public void setResourceIds(String resourceIds) {
this.resourceIds = resourceIds;
}
public void setScope(String scope) {
this.scope = scope;
}
public void setAuthorizedGrantTypes(String authorizedGrantTypes) {
this.authorizedGrantTypes = authorizedGrantTypes;
}
public void setWebServerRedirectUri(String webServerRedirectUri) {
this.webServerRedirectUri = webServerRedirectUri;
}
public void setAuthorities(String authorities) {
this.authorities = authorities;
}
public void setAccessTokenValiditySeconds(Integer accessTokenValiditySeconds) {
this.accessTokenValiditySeconds = accessTokenValiditySeconds;
}
public void setRefreshTokenValiditySeconds(Integer refreshTokenValiditySeconds) {
this.refreshTokenValiditySeconds = refreshTokenValiditySeconds;
}
@Override
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
public boolean isSecretRequired() {
return this.clientSecret != null;
}
@Override
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
public String getClientSecret() {
return clientSecret;
}
@Override
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
public boolean isScoped() {
return this.scope != null && !this.scope.isEmpty();
}
@Override
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
public Set<String> getScope() {
return Set.of(scope.split(","));
}
@Override
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
public Set<String> getAuthorizedGrantTypes() {
if (authorizedGrantTypes == null){
return new HashSet<>(0);
}
return Set.of(authorizedGrantTypes.split(","));
}
@Override
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
public Set<String> getRegisteredRedirectUri() {
if (webServerRedirectUri == null){
return new HashSet<>(0);
}
return Set.of(webServerRedirectUri.split(","));
}
@Override
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
public Collection<GrantedAuthority> getAuthorities() {
if (StringUtils.isEmpty(authorities)){
return Collections.emptyList();
}
return JSON.parseArray(authorities, GrantedAuthority.class);
}
@Override
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
public Integer getAccessTokenValiditySeconds() {
return accessTokenValiditySeconds;
}
@Override
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
public Integer getRefreshTokenValiditySeconds() {
return refreshTokenValiditySeconds;
}
@Override
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
public boolean isAutoApprove(String s) {
return Boolean.getBoolean(autoapprove);
}
@Override
@JsonIgnore
@com.fasterxml.jackson.annotation.JsonIgnore
public Map<String, Object> getAdditionalInformation() {
if (additionalInformation == null){
return new HashMap<>(0);
}
return BeanUtils.beanToMap(additionalInformation);
}
}

View File

@ -0,0 +1,79 @@
package cn.zyjblogs.server.client.service.impl;
import cn.zyjblogs.server.client.mapper.OauthClientDetailsMapper;
import cn.zyjblogs.server.client.po.OauthClientDetail;
import cn.zyjblogs.starter.common.utils.bean.BeanUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientAlreadyExistsException;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.security.oauth2.provider.ClientRegistrationService;
import org.springframework.security.oauth2.provider.NoSuchClientException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
/**
* @author zhuyijun
*/
@Service("oauthClientDetailsService")
@RequiredArgsConstructor
public class OauthClientDetailsServiceImpl implements ClientDetailsService, ClientRegistrationService {
private final OauthClientDetailsMapper oauthClientDetailsMapper;
private final PasswordEncoder passwordEncoder;
@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
LambdaQueryWrapper<OauthClientDetail> wrapper = Wrappers.lambdaQuery();
wrapper.eq(OauthClientDetail::getClientId,clientId);
return oauthClientDetailsMapper.selectOne(wrapper);
}
@Override
public void addClientDetails(ClientDetails clientDetails) throws ClientAlreadyExistsException {
OauthClientDetail oauthClientDetail = new OauthClientDetail(clientDetails);
if (oauthClientDetail.getClientSecret() != null){
oauthClientDetail.setClientSecret(passwordEncoder.encode(oauthClientDetail.getClientSecret()));
}
oauthClientDetailsMapper.insert(oauthClientDetail);
}
@Override
public void updateClientDetails(ClientDetails clientDetails) throws NoSuchClientException {
LambdaUpdateWrapper<OauthClientDetail> updateWrapper = Wrappers.lambdaUpdate();
updateWrapper.eq(OauthClientDetail::getClientId,clientDetails.getClientId());
OauthClientDetail oauthClientDetail = new OauthClientDetail(clientDetails);
oauthClientDetailsMapper.update(oauthClientDetail,updateWrapper);
}
@Override
public void updateClientSecret(String clientId, String clientSecret) throws NoSuchClientException {
LambdaUpdateWrapper<OauthClientDetail> updateWrapper = Wrappers.lambdaUpdate();
updateWrapper.eq(OauthClientDetail::getClientId,clientId).set(OauthClientDetail::getClientSecret,passwordEncoder.encode(clientSecret));
oauthClientDetailsMapper.update(null,updateWrapper);
}
@Override
public void removeClientDetails(String clientId) throws NoSuchClientException {
LambdaUpdateWrapper<OauthClientDetail> updateWrapper = Wrappers.lambdaUpdate();
updateWrapper.eq(OauthClientDetail::getClientId,clientId);
oauthClientDetailsMapper.delete(updateWrapper);
}
@Override
public List<ClientDetails> listClientDetails() {
List<OauthClientDetail> oauthClientDetails = oauthClientDetailsMapper.selectList(Wrappers.emptyWrapper());
if (CollectionUtils.isEmpty(oauthClientDetails)){
return new ArrayList<>();
}
return BeanUtils.map(oauthClientDetails,ClientDetails.class);
}
}

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.oauth.server.demo;
package cn.zyjblogs.server.demo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.oauth.server.user.constant;
package cn.zyjblogs.server.user.constant;
/**
*

View File

@ -0,0 +1,37 @@
package cn.zyjblogs.server.user.constant;
import lombok.Getter;
/**
* @author zhuyijun
*/
public enum LoginEnum {
/**
* 账号号邮箱方式
*/
NORMAL("1","普通登录方式"),
/**
* 验证码方式
*/
VERIFY_CODE("2","手机验证码方式"),
/**
* 第三方登录
*/
OTHER("3","第三方登录");
private String code;
private String name;
public String getCode() {
return code;
}
public String getName() {
return name;
}
LoginEnum(String code, String name) {
this.code = code;
this.name = name;
}
}

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.oauth.server.user.constant;
package cn.zyjblogs.server.user.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;

View File

@ -1,10 +1,9 @@
package cn.zyjblogs.oauth.server.user.controller;
package cn.zyjblogs.server.user.controller;
import cn.zyjblogs.oauth.server.user.dto.AuthorizationCodeDto;
import cn.zyjblogs.oauth.server.user.dto.OAuth2AccessTokenDto;
import cn.zyjblogs.oauth.server.user.dto.UserLoginDto;
import cn.zyjblogs.oauth.server.user.service.LoginService;
import cn.zyjblogs.oauth.server.user.vo.OAuth2AccessTokenVo;
import cn.zyjblogs.server.user.dto.AuthorizationCodeDto;
import cn.zyjblogs.server.user.dto.OAuth2AccessTokenDto;
import cn.zyjblogs.server.user.service.AuthService;
import cn.zyjblogs.server.user.vo.OAuth2AccessTokenVo;
import cn.zyjblogs.starter.common.entity.response.ResponseObject;
import cn.zyjblogs.starter.common.entity.response.ResponseResult;
import io.swagger.annotations.ApiOperation;
@ -20,38 +19,26 @@ import org.springframework.web.bind.annotation.RestController;
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/user")
public class LoginController {
private final LoginService loginService;
@ApiOperation(value = "用户登录", notes = "用户登录")
@PostMapping("/login")
public ResponseObject<OAuth2AccessTokenVo> login(@RequestBody @Validated UserLoginDto userLoginDto) {
return ResponseResult.success(loginService.login(userLoginDto));
}
@ApiOperation(value = "用户注销", notes = "用户注销")
@PostMapping("/logout")
public void logout() {
loginService.logout();
}
@RequestMapping("/auth")
public class AutoController {
private final AuthService authService;
@ApiOperation(value = "刷新token", notes = "刷新token")
@PostMapping("/refresh/token")
public ResponseObject<OAuth2AccessTokenVo> refreshToken(@RequestBody @Validated OAuth2AccessTokenDto oAuth2AccessTokenDto) {
return ResponseResult.success(loginService.refreshToken(oAuth2AccessTokenDto));
return ResponseResult.success(authService.refreshToken(oAuth2AccessTokenDto));
}
@ApiOperation(value = "检测token", notes = "刷新token")
@PostMapping("/check/token")
public ResponseObject<OAuth2AccessTokenVo> checkToken(@RequestBody @Validated OAuth2AccessTokenDto oAuth2AccessTokenDto) {
return ResponseResult.success(loginService.checkToken(oAuth2AccessTokenDto));
return ResponseResult.success(authService.checkToken(oAuth2AccessTokenDto));
}
@ApiOperation(value = "获取授权码", notes = "刷新token")
@PostMapping("/authorize")
public void getAuthorizationCode(@RequestBody @Validated AuthorizationCodeDto authorizationCodeDto) {
loginService.getAuthorizationCode(authorizationCodeDto);
authService.getAuthorizationCode(authorizationCodeDto);
}
}

View File

@ -0,0 +1,36 @@
package cn.zyjblogs.server.user.controller;
import cn.zyjblogs.server.user.dto.UserLoginDto;
import cn.zyjblogs.server.user.service.LoginService;
import cn.zyjblogs.server.user.vo.OAuth2AccessTokenVo;
import cn.zyjblogs.starter.common.entity.response.ResponseObject;
import cn.zyjblogs.starter.common.entity.response.ResponseResult;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author zhuyijun
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/user")
public class LoginController {
private final LoginService loginService;
@ApiOperation(value = "用户登录", notes = "用户登录")
@PostMapping("/login")
public ResponseObject<OAuth2AccessTokenVo> login(@RequestBody @Validated UserLoginDto userLoginDto) {
return ResponseResult.success(loginService.login(userLoginDto));
}
@ApiOperation(value = "用户注销", notes = "用户注销")
@PostMapping("/logout")
public void logout() {
loginService.logout();
}
}

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.oauth.server.user.dto;
package cn.zyjblogs.server.user.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.oauth.server.user.dto;
package cn.zyjblogs.server.user.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.oauth.server.user.dto;
package cn.zyjblogs.server.user.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
@ -18,13 +18,13 @@ public class UserLoginDto implements Serializable {
/**
* 账号 (手机号 邮箱 用户名)
*/
private String username;
private String userIdentification;
/**
* 密码
*/
private String password;
private String pwdOrVerifyCode;
/**
* 登录类型
*/
private Integer type;
private String loginType;
}

View File

@ -1,6 +1,6 @@
package cn.zyjblogs.oauth.server.user.mapper;
package cn.zyjblogs.server.user.mapper;
import cn.zyjblogs.oauth.server.user.po.UserPo;
import cn.zyjblogs.server.user.po.UserPo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

View File

@ -1,8 +1,8 @@
package cn.zyjblogs.oauth.server.user.po;
package cn.zyjblogs.server.user.po;
import cn.zyjblogs.oauth.server.user.constant.CommonConstant;
import cn.zyjblogs.oauth.server.user.constant.UserEnum;
import cn.zyjblogs.server.user.constant.CommonConstant;
import cn.zyjblogs.server.user.constant.UserEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.oauth.server.user.po;
package cn.zyjblogs.server.user.po;
import lombok.AllArgsConstructor;
import lombok.Builder;

View File

@ -1,16 +1,20 @@
package cn.zyjblogs.oauth.server.user.po;
package cn.zyjblogs.server.user.po;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.sql.Timestamp;
import java.time.LocalDateTime;
/**
@ -20,7 +24,7 @@ import java.time.LocalDateTime;
@AllArgsConstructor
@NoArgsConstructor
@Builder
@TableName("user")
@TableName("users")
public class UserPo implements Serializable {
@TableId(value = "id", type = IdType.ASSIGN_UUID)
@ -68,7 +72,8 @@ public class UserPo implements Serializable {
@TableField("create_user_id")
private String createUserId;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField("create_time")
private LocalDateTime createTime;
@ -76,7 +81,8 @@ public class UserPo implements Serializable {
private String editUserId;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField("edit_time")
private LocalDateTime editTime;

View File

@ -0,0 +1,33 @@
package cn.zyjblogs.server.user.service;
import cn.zyjblogs.server.user.dto.AuthorizationCodeDto;
import cn.zyjblogs.server.user.dto.OAuth2AccessTokenDto;
import cn.zyjblogs.server.user.vo.OAuth2AccessTokenVo;
/**
* @author zhuyijun
*/
public interface AuthService {
/**
* 刷新token
*
* @param oAuth2AccessTokenDto
* @return
*/
OAuth2AccessTokenVo refreshToken(OAuth2AccessTokenDto oAuth2AccessTokenDto);
/**
* 检测token信息
*
* @param oAuth2AccessTokenDto
* @return
*/
OAuth2AccessTokenVo checkToken(OAuth2AccessTokenDto oAuth2AccessTokenDto);
/**
* 获取授权码
*
* @param authorizationCodeDto
*/
void getAuthorizationCode(AuthorizationCodeDto authorizationCodeDto);
}

View File

@ -0,0 +1,31 @@
package cn.zyjblogs.server.user.service;
import cn.zyjblogs.server.user.dto.UserLoginDto;
import cn.zyjblogs.server.user.vo.OAuth2AccessTokenVo;
/**
* 登录
*
* @author zhuyijun
*/
public interface LoginService {
/**
* 登录接口
*
* @param userLoginDto
* @return cn.zyjblogs.oauth.server.user.vo.OAuth2AccessTokenVo
* @author zhuyijun
* @date 2022/9/17 下午5:11
*/
OAuth2AccessTokenVo login(UserLoginDto userLoginDto);
/**
* 退出
*
* @param
* @return void
* @author zhuyijun
* @date 2022/9/17 下午5:53
*/
void logout();
}

View File

@ -1,6 +1,6 @@
package cn.zyjblogs.oauth.server.user.service;
package cn.zyjblogs.server.user.service;
import cn.zyjblogs.oauth.server.user.po.UserPo;
import cn.zyjblogs.server.user.po.UserPo;
import com.baomidou.mybatisplus.extension.service.IService;

View File

@ -1,18 +1,12 @@
package cn.zyjblogs.oauth.server.user.service.impl;
package cn.zyjblogs.server.user.service.impl;
import cn.zyjblogs.oauth.server.user.dto.AuthorizationCodeDto;
import cn.zyjblogs.oauth.server.user.dto.OAuth2AccessTokenDto;
import cn.zyjblogs.oauth.server.user.dto.UserLoginDto;
import cn.zyjblogs.oauth.server.user.service.LoginService;
import cn.zyjblogs.oauth.server.user.vo.OAuth2AccessTokenVo;
import cn.zyjblogs.starter.common.entity.constant.HttpHeaderConstant;
import cn.zyjblogs.starter.common.entity.context.BaseContext;
import cn.zyjblogs.starter.common.entity.dto.ContextDto;
import cn.zyjblogs.server.user.dto.AuthorizationCodeDto;
import cn.zyjblogs.server.user.dto.OAuth2AccessTokenDto;
import cn.zyjblogs.server.user.service.AuthService;
import cn.zyjblogs.server.user.vo.OAuth2AccessTokenVo;
import cn.zyjblogs.starter.common.entity.response.HttpCode;
import cn.zyjblogs.starter.common.exception.AuthRuntimeException;
import cn.zyjblogs.starter.common.utils.bean.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerEndpointsConfiguration;
import org.springframework.security.oauth2.provider.ClientDetails;
@ -23,7 +17,6 @@ import org.springframework.security.oauth2.provider.TokenRequest;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.HashMap;
import java.util.Map;
@ -32,61 +25,35 @@ import java.util.Map;
* @author zhuyijun
*/
@Service
public class LoginServiceImpl implements LoginService {
public class AuthServiceImpl implements AuthService {
private final TokenGranter tokenGranter;
private final ClientDetailsService clientDetails;
private final OAuth2RequestFactory oAuth2RequestFactory;
private final TokenStore tokenStore;
public LoginServiceImpl(AuthorizationServerEndpointsConfiguration authorizationServerEndpointsConfiguration,
ClientDetailsService clientDetails,
TokenStore tokenStore) {
public AuthServiceImpl(AuthorizationServerEndpointsConfiguration authorizationServerEndpointsConfiguration,
ClientDetailsService clientDetails,
TokenStore tokenStore) {
this.tokenGranter = authorizationServerEndpointsConfiguration.getEndpointsConfigurer().getTokenGranter();
this.clientDetails = clientDetails;
this.oAuth2RequestFactory = new DefaultOAuth2RequestFactory(clientDetails);
this.tokenStore = tokenStore;
}
@Value("${spring.application.name}")
@Value("${security.oauth2.client.client-id}")
private String clientId;
@Override
public OAuth2AccessTokenVo login(UserLoginDto userLoginDto) {
Map<String, String> parameters = BeanUtils.map(userLoginDto, Map.class);
parameters.put("grant_type", "password");
ClientDetails authenticatedClient = clientDetails.loadClientByClientId(clientId);
TokenRequest tokenRequest = oAuth2RequestFactory.createTokenRequest(parameters, authenticatedClient);
OAuth2AccessToken token = tokenGranter.grant(tokenRequest.getGrantType(), tokenRequest);
if (token == null) {
throw new AuthRuntimeException(HttpCode.INTERNAL_SERVER_ERROR, "客户端获取token失败");
}
return transferToken(token);
}
@Override
public void logout() {
String token = BaseContext.getToken();
if (StringUtils.isEmpty(token)) {
return;
}
token = token.replace(HttpHeaderConstant.AUTHORIZATION_TYPE, "").trim();
OAuth2AccessToken oAuth2AccessToken = new DefaultOAuth2AccessToken(token);
tokenStore.removeAccessToken(oAuth2AccessToken);
}
@Override
public OAuth2AccessTokenVo refreshToken(OAuth2AccessTokenDto oAuth2AccessTokenDto) {
Map<String, String> parameters = new HashMap<>();
parameters.put("refresh_token", oAuth2AccessTokenDto.getToken());
parameters.put("grant_type", "refresh_token");
ClientDetails authenticatedClient = clientDetails.loadClientByClientId(clientId);
TokenRequest tokenRequest = oAuth2RequestFactory.createTokenRequest(parameters, authenticatedClient);
if (authenticatedClient == null){
throw new AuthRuntimeException(HttpCode.INTERNAL_SERVER_ERROR, "客户端获取失败");
}
try {
TokenRequest tokenRequest = oAuth2RequestFactory.createTokenRequest(parameters, authenticatedClient);
OAuth2AccessToken token = tokenGranter.grant(tokenRequest.getGrantType(), tokenRequest);
if (token == null) {
throw new AuthRuntimeException(HttpCode.INTERNAL_SERVER_ERROR, "客户端刷新token失败");
}
return transferToken(token);
return OAuth2AccessTokenVo.TransferToken(token);
} catch (Exception e) {
throw new AuthRuntimeException(HttpCode.INTERNAL_SERVER_ERROR, e.getMessage());
}
@ -116,25 +83,4 @@ public class LoginServiceImpl implements LoginService {
// }
}
/**
* 处理token
*
* @param token
* @return
*/
private OAuth2AccessTokenVo transferToken(OAuth2AccessToken token) {
OAuth2AccessTokenVo oAuth2AccessTokenVo = new OAuth2AccessTokenVo(
token.getValue(),
token.getTokenType(),
token.getRefreshToken().getValue(),
token.getExpiresIn(),
token.getScope(),
token.getAdditionalInformation());
BaseContext.set(ContextDto.builder()
.userId(oAuth2AccessTokenVo.getUserId())
.username(oAuth2AccessTokenVo.getUsername())
.token(oAuth2AccessTokenVo.getValue())
.build());
return oAuth2AccessTokenVo;
}
}

View File

@ -0,0 +1,78 @@
package cn.zyjblogs.server.user.service.impl;
import cn.zyjblogs.server.user.dto.UserLoginDto;
import cn.zyjblogs.server.user.service.LoginService;
import cn.zyjblogs.server.user.vo.OAuth2AccessTokenVo;
import cn.zyjblogs.starter.common.entity.constant.HttpHeaderConstant;
import cn.zyjblogs.starter.common.entity.context.BaseContext;
import cn.zyjblogs.starter.common.entity.response.HttpCode;
import cn.zyjblogs.starter.common.exception.AuthRuntimeException;
import cn.zyjblogs.starter.common.utils.bean.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerEndpointsConfiguration;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
import org.springframework.security.oauth2.provider.TokenGranter;
import org.springframework.security.oauth2.provider.TokenRequest;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.Map;
/**
* @author zhuyijun
*/
@Service
public class LoginServiceImpl implements LoginService {
private final TokenGranter tokenGranter;
private final ClientDetailsService clientDetails;
private final OAuth2RequestFactory oAuth2RequestFactory;
private final TokenStore tokenStore;
public LoginServiceImpl(AuthorizationServerEndpointsConfiguration authorizationServerEndpointsConfiguration,
ClientDetailsService clientDetails,
TokenStore tokenStore) {
this.tokenGranter = authorizationServerEndpointsConfiguration.getEndpointsConfigurer().getTokenGranter();
this.clientDetails = clientDetails;
this.oAuth2RequestFactory = new DefaultOAuth2RequestFactory(clientDetails);
this.tokenStore = tokenStore;
}
@Value("${security.oauth2.client.client-id}")
private String clientId;
@Override
public OAuth2AccessTokenVo login(UserLoginDto userLoginDto) {
Map<String, String> parameters = BeanUtils.map(userLoginDto, Map.class);
parameters.put("username",userLoginDto.getUserIdentification());
parameters.put("password",userLoginDto.getPwdOrVerifyCode());
parameters.put("grant_type", "password");
ClientDetails authenticatedClient = clientDetails.loadClientByClientId(clientId);
if (authenticatedClient == null) {
throw new AuthRuntimeException(HttpCode.INTERNAL_SERVER_ERROR, "客户端获取token失败");
}
try{
TokenRequest tokenRequest = oAuth2RequestFactory.createTokenRequest(parameters, authenticatedClient);
OAuth2AccessToken token = tokenGranter.grant(tokenRequest.getGrantType(), tokenRequest);
return OAuth2AccessTokenVo.TransferToken(token);
}catch (Exception e){
throw new AuthRuntimeException(HttpCode.INTERNAL_SERVER_ERROR, e.getMessage());
}
}
@Override
public void logout() {
String token = BaseContext.getToken();
if (StringUtils.isEmpty(token)) {
return;
}
token = token.replace(HttpHeaderConstant.AUTHORIZATION_TYPE, "").trim();
OAuth2AccessToken oAuth2AccessToken = new DefaultOAuth2AccessToken(token);
tokenStore.removeAccessToken(oAuth2AccessToken);
}
}

View File

@ -1,20 +1,17 @@
package cn.zyjblogs.oauth.server.user.service.impl;
package cn.zyjblogs.server.user.service.impl;
import cn.zyjblogs.oauth.server.user.po.OauthUserDetails;
import cn.zyjblogs.oauth.server.user.po.UserPo;
import cn.zyjblogs.oauth.server.user.service.UserService;
import cn.zyjblogs.server.user.po.OauthUserDetails;
import cn.zyjblogs.server.user.po.UserPo;
import cn.zyjblogs.server.user.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author zhuyijun
*/
@ -25,7 +22,7 @@ public class OauthUserDetailsServiceImpl implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
LambdaQueryWrapper<UserPo> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.eq(UserPo::getUsername,s);
queryWrapper.eq(UserPo::getUsername,s).or().eq(UserPo::getEmail,s).or().eq(UserPo::getPhone,s);
UserPo userPo = userService.getBaseMapper().selectOne(queryWrapper);
if (userPo == null){
return null;

View File

@ -1,13 +1,16 @@
package cn.zyjblogs.oauth.server.user.service.impl;
package cn.zyjblogs.server.user.service.impl;
import cn.zyjblogs.oauth.server.user.mapper.UserMapper;
import cn.zyjblogs.oauth.server.user.po.UserPo;
import cn.zyjblogs.oauth.server.user.service.UserService;
import cn.zyjblogs.server.user.mapper.UserMapper;
import cn.zyjblogs.server.user.po.UserPo;
import cn.zyjblogs.server.user.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
/**
* @author zhuyijun
*/
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, UserPo> implements UserService {

View File

@ -1,8 +1,11 @@
package cn.zyjblogs.oauth.server.user.vo;
package cn.zyjblogs.server.user.vo;
import cn.zyjblogs.starter.common.entity.constant.ContextKeyConstant;
import cn.zyjblogs.starter.common.entity.context.BaseContext;
import cn.zyjblogs.starter.common.entity.dto.ContextDto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import java.io.Serializable;
import java.util.Collection;
@ -51,5 +54,20 @@ public class OAuth2AccessTokenVo implements Serializable {
this.jti = (String) addition.get("jti");
}
public static OAuth2AccessTokenVo TransferToken(OAuth2AccessToken token) {
OAuth2AccessTokenVo oAuth2AccessTokenVo = new OAuth2AccessTokenVo(
token.getValue(),
token.getTokenType(),
token.getRefreshToken().getValue(),
token.getExpiresIn(),
token.getScope(),
token.getAdditionalInformation());
BaseContext.set(ContextDto.builder()
.userId(oAuth2AccessTokenVo.getUserId())
.username(oAuth2AccessTokenVo.getUsername())
.token(oAuth2AccessTokenVo.getValue())
.build());
return oAuth2AccessTokenVo;
}
}

View File

@ -29,4 +29,10 @@ spring:
group: public
logging:
config: classpath:logback-spring.xml
config: classpath:logback-spring.xml
security:
oauth2:
client:
client-id: ${spring.application.name}
client-secret: secret

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.zyjblogs.server.user.mapper.UserMapper">
<select id="findUserByname" resultType="cn.zyjblogs.server.user.po.UserPo">
select *
from user
where deleted = 0
and username like CONCAT('%', #{username}, '%')
<if test="tenantId != null and tenantId != '' ">
and tenant_id = #{tenantId}
</if>
</select>
</mapper>

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.rbac;
package cn.zyjblogs;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

View File

@ -1,9 +1,9 @@
package cn.zyjblogs.rbac.server.role.controller;
package cn.zyjblogs.server.role.controller;
import cn.zyjblogs.rbac.server.role.dto.RolePageDto;
import cn.zyjblogs.rbac.server.role.po.RolePo;
import cn.zyjblogs.rbac.server.role.service.RoleService;
import cn.zyjblogs.rbac.server.role.vo.RoleVo;
import cn.zyjblogs.server.role.dto.RolePageDto;
import cn.zyjblogs.server.role.po.RolePo;
import cn.zyjblogs.server.role.service.RoleService;
import cn.zyjblogs.server.role.vo.RoleVo;
import cn.zyjblogs.starter.common.entity.response.ResponseObject;
import cn.zyjblogs.starter.common.entity.response.ResponseResult;
import cn.zyjblogs.starter.common.utils.bean.BeanUtils;

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.rbac.server.role.dto;
package cn.zyjblogs.server.role.dto;
import cn.zyjblogs.starter.common.entity.dto.PageDto;
import com.alibaba.fastjson.annotation.JSONField;

View File

@ -1,8 +1,8 @@
package cn.zyjblogs.rbac.server.role.mapper;
package cn.zyjblogs.server.role.mapper;
import cn.zyjblogs.rbac.server.role.dto.RolePageDto;
import cn.zyjblogs.rbac.server.role.po.RolePo;
import cn.zyjblogs.rbac.server.role.vo.RoleVo;
import cn.zyjblogs.server.role.dto.RolePageDto;
import cn.zyjblogs.server.role.po.RolePo;
import cn.zyjblogs.server.role.vo.RoleVo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Mapper;

View File

@ -1,9 +1,12 @@
package cn.zyjblogs.rbac.server.role.po;
package cn.zyjblogs.server.role.po;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@ -36,14 +39,16 @@ public class RolePo implements Serializable {
@TableField("create_user_id")
private String createUserId;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField("create_time")
private LocalDateTime createTime;
@TableField("edit_user_id")
private String editUserId;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField("edit_time")
private LocalDateTime editTime;
@TableField("tenant_id")

View File

@ -1,8 +1,8 @@
package cn.zyjblogs.rbac.server.role.service;
package cn.zyjblogs.server.role.service;
import cn.zyjblogs.rbac.server.role.dto.RolePageDto;
import cn.zyjblogs.rbac.server.role.po.RolePo;
import cn.zyjblogs.rbac.server.role.vo.RoleVo;
import cn.zyjblogs.server.role.dto.RolePageDto;
import cn.zyjblogs.server.role.po.RolePo;
import cn.zyjblogs.server.role.vo.RoleVo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;

View File

@ -1,10 +1,10 @@
package cn.zyjblogs.rbac.server.role.service.impl;
package cn.zyjblogs.server.role.service.impl;
import cn.zyjblogs.rbac.server.role.dto.RolePageDto;
import cn.zyjblogs.rbac.server.role.mapper.RoleMapper;
import cn.zyjblogs.rbac.server.role.po.RolePo;
import cn.zyjblogs.rbac.server.role.service.RoleService;
import cn.zyjblogs.rbac.server.role.vo.RoleVo;
import cn.zyjblogs.server.role.dto.RolePageDto;
import cn.zyjblogs.server.role.mapper.RoleMapper;
import cn.zyjblogs.server.role.po.RolePo;
import cn.zyjblogs.server.role.service.RoleService;
import cn.zyjblogs.server.role.vo.RoleVo;
import cn.zyjblogs.starter.common.entity.context.BaseContext;
import cn.zyjblogs.starter.common.utils.bean.BeanUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;

View File

@ -1,9 +1,12 @@
package cn.zyjblogs.rbac.server.role.vo;
package cn.zyjblogs.server.role.vo;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@ -36,14 +39,16 @@ public class RoleVo implements Serializable {
@TableField("create_user_id")
private String createUserId;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField("create_time")
private LocalDateTime createTime;
@TableField("edit_user_id")
private String editUserId;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField("edit_time")
private LocalDateTime editTime;
@TableField("tenant_id")

View File

@ -1,9 +1,9 @@
package cn.zyjblogs.rbac.server.user.controller;
package cn.zyjblogs.server.user.controller;
import cn.zyjblogs.rbac.server.user.dto.UserPageDto;
import cn.zyjblogs.rbac.server.user.po.UserPo;
import cn.zyjblogs.rbac.server.user.service.UserService;
import cn.zyjblogs.rbac.server.user.vo.UserVo;
import cn.zyjblogs.server.user.dto.UserPageDto;
import cn.zyjblogs.server.user.po.UserPo;
import cn.zyjblogs.server.user.service.UserService;
import cn.zyjblogs.server.user.vo.UserVo;
import cn.zyjblogs.starter.common.entity.response.ResponseObject;
import cn.zyjblogs.starter.common.entity.response.ResponseResult;
import com.baomidou.mybatisplus.core.metadata.IPage;

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.rbac.server.user.dto;
package cn.zyjblogs.server.user.dto;
import cn.zyjblogs.starter.common.entity.dto.PageDto;
import lombok.Builder;

View File

@ -1,8 +1,8 @@
package cn.zyjblogs.rbac.server.user.mapper;
package cn.zyjblogs.server.user.mapper;
import cn.zyjblogs.rbac.server.user.dto.UserPageDto;
import cn.zyjblogs.rbac.server.user.po.UserPo;
import cn.zyjblogs.rbac.server.user.vo.UserVo;
import cn.zyjblogs.server.user.dto.UserPageDto;
import cn.zyjblogs.server.user.po.UserPo;
import cn.zyjblogs.server.user.vo.UserVo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Mapper;

View File

@ -1,16 +1,20 @@
package cn.zyjblogs.rbac.server.user.po;
package cn.zyjblogs.server.user.po;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.sql.Timestamp;
import java.time.LocalDateTime;
/**
@ -20,7 +24,7 @@ import java.time.LocalDateTime;
@AllArgsConstructor
@NoArgsConstructor
@Builder
@TableName("user")
@TableName("users")
public class UserPo implements Serializable {
@TableId(value = "id", type = IdType.ASSIGN_UUID)
@ -68,7 +72,8 @@ public class UserPo implements Serializable {
@TableField("create_user_id")
private String createUserId;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField("create_time")
private LocalDateTime createTime;
@ -76,7 +81,8 @@ public class UserPo implements Serializable {
private String editUserId;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField("edit_time")
private LocalDateTime editTime;

View File

@ -1,8 +1,8 @@
package cn.zyjblogs.rbac.server.user.service;
package cn.zyjblogs.server.user.service;
import cn.zyjblogs.rbac.server.user.dto.UserPageDto;
import cn.zyjblogs.rbac.server.user.po.UserPo;
import cn.zyjblogs.rbac.server.user.vo.UserVo;
import cn.zyjblogs.server.user.dto.UserPageDto;
import cn.zyjblogs.server.user.po.UserPo;
import cn.zyjblogs.server.user.vo.UserVo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;

View File

@ -1,11 +1,11 @@
package cn.zyjblogs.rbac.server.user.service.impl;
package cn.zyjblogs.server.user.service.impl;
import cn.zyjblogs.rbac.server.user.dto.UserPageDto;
import cn.zyjblogs.rbac.server.user.mapper.UserMapper;
import cn.zyjblogs.rbac.server.user.po.UserPo;
import cn.zyjblogs.rbac.server.user.service.UserService;
import cn.zyjblogs.rbac.server.user.vo.UserVo;
import cn.zyjblogs.server.user.dto.UserPageDto;
import cn.zyjblogs.server.user.mapper.UserMapper;
import cn.zyjblogs.server.user.po.UserPo;
import cn.zyjblogs.server.user.service.UserService;
import cn.zyjblogs.server.user.vo.UserVo;
import cn.zyjblogs.starter.common.entity.context.BaseContext;
import cn.zyjblogs.starter.common.utils.bean.BeanUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;

View File

@ -1,12 +1,16 @@
package cn.zyjblogs.rbac.server.user.vo;
package cn.zyjblogs.server.user.vo;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.sql.Timestamp;
import java.time.LocalDateTime;
/**
@ -46,13 +50,15 @@ public class UserVo implements Serializable {
private String createUserId;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
private String editUserId;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime editTime;
private String tenantId;

View File

@ -27,6 +27,12 @@ spring:
logging:
config: classpath:logback-spring.xml
security:
oauth2:
client:
client-id: ${spring.application.name}
client-secret: secret
# 配置了公钥和私钥的位置
rsa:
key:

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.zyjblogs.rbac.server.role.mapper.RoleMapper">
<select id="findPage" resultType="cn.zyjblogs.rbac.server.role.vo.RoleVo">
<mapper namespace="cn.zyjblogs.server.role.mapper.RoleMapper">
<select id="findPage" resultType="cn.zyjblogs.server.role.vo.RoleVo">
select * from role
where deleted = 0
<if test="rolePageDto.username != null and rolePageDto.username!='' ">

View File

@ -1,17 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.zyjblogs.rbac.server.user.mapper.UserMapper">
<select id="findUserByname" resultType="cn.zyjblogs.rbac.server.user.po.UserPo">
<mapper namespace="cn.zyjblogs.server.user.mapper.UserMapper">
<select id="findUserByname" resultType="cn.zyjblogs.server.user.po.UserPo">
select *
from user
from users
where deleted = 0
and username like CONCAT('%', #{username}, '%')
<if test="tenantId != null and tenantId != '' ">
and tenant_id = #{tenantId}
</if>
</select>
<select id="findPage" resultType="cn.zyjblogs.rbac.server.user.vo.UserVo">
select * from user
<select id="findPage" resultType="cn.zyjblogs.server.user.vo.UserVo">
select * from users
where deleted = 0
<if test="userPageDto.username != null and userPageDto.username!='' ">
and username concat('%',#{userPageDto.username},'%')
</if>
<if test="userPageDto.name != null and userPageDto.name!='' ">
and name concat('%',#{name},'%')
</if>
<if test="userPageDto.phone != null and userPageDto.phone!='' ">
and phone concat('%',#{phone},'%')
</if>
<if test="userPageDto.email != null and userPageDto.email!='' ">
and email concat('%',#{email},'%')
</if>
<if test="userPageDto.email != null ">
and status = #{userPageDto.status}
</if>
<if test="tenantId != null and tenantId != '' ">
and tenant_id = #{tenantId}
</if>
order by create_time desc
</select>
<select id="findPage" resultType="cn.zyjblogs.server.user.vo.UserVo" databaseId="postgresql">
select * from users
where deleted = 0
<if test="userPageDto.username != null and userPageDto.username!='' ">
and username concat('%',#{userPageDto.username},'%')
@ -34,5 +57,4 @@
order by create_time desc
</select>
</mapper>

View File

@ -38,6 +38,10 @@
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>

View File

@ -1,4 +1,4 @@
package cn.zyjblogs.starter.mybatisplus.config;
package cn.zyjblogs.starter.mybatisplus.autoconfigure;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;

View File

@ -1,2 +1,2 @@
org.springframework.boot.cn.zyjblogs.starter.feign.autoconfigure.EnableAutoConfiguration=\
cn.zyjblogs.starter.mybatisplus.config.MyBatisPlusConfig
cn.zyjblogs.starter.mybatisplus.autoconfigure.MyBatisPlusConfig

View File

@ -36,6 +36,10 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>

View File

@ -0,0 +1,65 @@
package cn.zyjblogs.starter.redis.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.cache.support.NullValue;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.io.IOException;
/**
* @author zhuyijun
*/
public class GenericJackson2JsonRedisSerializerEx implements RedisSerializer<Object> {
protected GenericJackson2JsonRedisSerializer serializer = null;
public GenericJackson2JsonRedisSerializerEx() {
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.registerModule(new JavaTimeModule());
this.serializer = new GenericJackson2JsonRedisSerializer(om);
}
public GenericJackson2JsonRedisSerializerEx(ObjectMapper om) {
this.serializer = new GenericJackson2JsonRedisSerializer(om);
}
@Override
public byte[] serialize(Object o) throws SerializationException {
return serializer.serialize(o);
}
@Override
public Object deserialize(byte[] bytes) throws SerializationException {
return serializer.deserialize(bytes);
}
protected class NullValueSerializer extends StdSerializer<NullValue> {
private static final long serialVersionUID = 1999052150548658807L;
private final String classIdentifier="@class";
NullValueSerializer() {
super(NullValue.class);
}
@Override
public void serialize(NullValue value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
jgen.writeStartObject();
jgen.writeStringField(this.classIdentifier, NullValue.class.getName());
jgen.writeEndObject();
}
}
}

View File

@ -2,8 +2,11 @@ package cn.zyjblogs.starter.redis.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
@ -35,11 +38,14 @@ public class RedisConfig {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL);
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(om);
// //解决查询缓存转换异常的问题
// ObjectMapper om = new ObjectMapper();
// om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// //注册java时间处理模块
// om.registerModule(new JavaTimeModule());
// GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(om);
GenericJackson2JsonRedisSerializerEx genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializerEx();
//序列号key value
redisTemplate.setKeySerializer(new StringRedisSerializer());

View File

@ -41,6 +41,10 @@
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -0,0 +1,21 @@
package cn.zyjblogs.starter.web.autoconfig;
import cn.zyjblogs.starter.web.hander.GlobalExceptionHandler;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author zhuyijun
*/
@Configuration
public class GlobalExceptionHandlerAutoConfiguration {
@Bean
@ConditionalOnMissingBean(
name = {"globalExceptionHandler"}
)
public GlobalExceptionHandler globalExceptionHandler(){
return new GlobalExceptionHandler();
}
}

View File

@ -14,10 +14,14 @@ import java.util.List;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import cn.zyjblogs.starter.common.exception.AuthRuntimeException;
import ma.glasnost.orika.MappingException;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
@ -30,45 +34,40 @@ import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException;
/**
* @author zhuyijun
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
private static final String TYPE_MISMATCH = "typeMismatch";
@ExceptionHandler({NoHandlerFoundException.class})
@ResponseStatus(org.springframework.http.HttpStatus.NOT_FOUND)
public ResponseObject<?> handleNoHandlerFoundException(NoHandlerFoundException exception) {
log.error("NoHandlerFound", exception);
String i18nCode = "web_starter_not_found";
return ResponseResult.error(HttpCode.NOT_FOUND, i18nCode, i18nCode);
return ResponseResult.error(HttpCode.NOT_FOUND, i18nCode);
}
@ExceptionHandler({HttpRequestMethodNotSupportedException.class})
public ResponseObject<?> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException exception) {
log.error("HttpRequestMethodNotSupported", exception);
String i18nCode = "web_starter_method_not_allowed";
return ResponseResult.error(HttpCode.METHOD_NOT_ALLOWED, i18nCode, i18nCode);
return ResponseResult.error(HttpCode.METHOD_NOT_ALLOWED, i18nCode);
}
@ExceptionHandler({HttpMediaTypeNotSupportedException.class})
public ResponseObject<?> handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException exception) {
log.error("HttpMediaTypeNotSupported", exception);
String i18nCode = "web_starter_unsupported_media_type";
return ResponseResult.error(HttpCode.UNSUPPORTED_MEDIA_TYPE, i18nCode, i18nCode);
}
@ExceptionHandler({Exception.class})
public ResponseObject<?> handleException(Exception exception) {
log.error("", exception);
String i18nCode = "web_starter_internal_server_error";
return ResponseResult.error(HttpCode.INTERNAL_SERVER_ERROR, i18nCode, i18nCode);
return ResponseResult.error(HttpCode.UNSUPPORTED_MEDIA_TYPE, i18nCode);
}
@ExceptionHandler({MethodArgumentTypeMismatchException.class})
public ResponseObject<String> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException exception) {
String i18nCode = "web_starter_property_format_error";
return ResponseResult.error(HttpCode.BAD_REQUEST, i18nCode, i18nCode);
return ResponseResult.error(HttpCode.BAD_REQUEST, i18nCode);
}
@ExceptionHandler({ConstraintViolationException.class})
@ -78,10 +77,10 @@ public class GlobalExceptionHandler {
if (CollectionUtils.isEmpty(constraintViolations)) {
log.warn("全局异常捕获到了ConstraintViolationException但是没有发现错误", exception);
i18nCode = "web_starter_bad_request";
return ResponseResult.error(HttpCode.BAD_REQUEST, i18nCode, i18nCode);
return ResponseResult.error(HttpCode.BAD_REQUEST, i18nCode);
} else {
i18nCode = constraintViolations.stream().findFirst().get().getMessage();
return ResponseResult.error(HttpCode.BAD_REQUEST, i18nCode, i18nCode);
return ResponseResult.error(HttpCode.BAD_REQUEST, i18nCode);
}
}
@ -93,14 +92,26 @@ public class GlobalExceptionHandler {
@ExceptionHandler({AbstractFrameworkException.class})
public ResponseObject<?> handleFrameworkException(AbstractFrameworkException exception) {
log.error("系统异常:", exception);
log.error("全局异常捕获 系统异常:{}", exception.getMessage());
return ResponseResult.error(HttpCode.INTERNAL_SERVER_ERROR, exception.getMessage());
}
@ExceptionHandler({AuthRuntimeException.class})
public ResponseObject<?> handleBusinessException(AuthRuntimeException exception) {
log.error("全局异常捕获 系统异常:", exception);
return ResponseResult.error(HttpCode.INTERNAL_SERVER_ERROR, exception.getMessage());
}
@ExceptionHandler({AbstractBusinessException.class})
public ResponseObject<?> handleBusinessException(AbstractBusinessException exception) {
log.error("系统异常:", exception);
log.error("全局异常捕获 系统异常:", exception);
return ResponseResult.error(HttpCode.INTERNAL_SERVER_ERROR, exception.getMessage());
}
@ExceptionHandler({BadSqlGrammarException.class})
public ResponseObject<?> handleSqlException(Exception exception) {
log.error("全局异常捕获 SQL执行异常{}", exception.getMessage());
return ResponseResult.error(HttpCode.INTERNAL_SERVER_ERROR, "SQL执行异常",exception.getMessage());
}
@ExceptionHandler({BindException.class})
public ResponseObject<?> handleBindException(BindException exception) {
BindingResult bindingResult = exception.getBindingResult();
@ -109,18 +120,30 @@ public class GlobalExceptionHandler {
@ExceptionHandler({HttpMessageNotReadableException.class})
public ResponseObject<?> handleHttpMessageNotReadableException(HttpMessageNotReadableException exception) {
log.error("参数格式不正确", exception);
log.error("全局异常捕获 参数格式不正确", exception);
return ResponseResult.error(HttpCode.BAD_REQUEST, exception.getMessage());
}
private ResponseObject<?> getByBindingResult(BindingResult bindingResult) {
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
if (fieldErrors.isEmpty()) {
log.error("捕获到了参数校验错误,{}", bindingResult);
log.error("全局异常捕获 捕获到了参数校验错误,{}", bindingResult);
return ResponseResult.error(HttpCode.BAD_REQUEST, bindingResult.toString());
} else {
FieldError fieldError = fieldErrors.get(0);
return ResponseResult.error(HttpCode.BAD_REQUEST, fieldError.getDefaultMessage());
}
}
@ExceptionHandler({MappingException.class})
public ResponseObject<?> handleMappingException(Exception exception) {
log.error("全局异常捕获:对象转化{}", exception.getMessage());
return ResponseResult.error(HttpCode.INTERNAL_SERVER_ERROR, exception.getMessage());
}
@ExceptionHandler({Exception.class})
public ResponseObject<?> handleException(Exception exception) {
log.error("全局异常捕获:{}", exception.getMessage());
return ResponseResult.error(HttpCode.INTERNAL_SERVER_ERROR, exception.getMessage());
}
}

View File

@ -1,3 +1,3 @@
## Auto Configure
#org.springframework.boot.cn.zyjblogs.starter.feign.autoconfigure.EnableAutoConfiguration=\
# cn.zyjblogs.starter.web.config.Knife4jAutoConfigurationConfig
org.springframework.boot.cn.zyjblogs.starter.feign.autoconfigure.EnableAutoConfiguration=\
cn.zyjblogs.starter.web.autoconfig.GlobalExceptionHandlerAutoConfiguration