1. fixed: 服务未上线,日志空指针问题

2. 优化:spring security 异常转化
This commit is contained in:
wangiegie@gmail.com 2017-12-29 18:57:35 +08:00
parent f6645eb23d
commit b4c3286578
10 changed files with 169 additions and 20 deletions

View File

@ -56,9 +56,7 @@
LEFT JOIN sys_user_role AS ur ON ur.user_id = `user`.user_id
LEFT JOIN sys_role AS r ON r.role_id = ur.role_id
WHERE
`user`.del_flag = 0
AND r.del_flag = 0
AND `user`.username = #{username}
`user`.username = #{username}
</select>
<select id="selectUserVoPage" resultMap="userVoResultMap" >
SELECT

View File

@ -0,0 +1,44 @@
package com.github.pig.auth.component;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator;
import org.springframework.stereotype.Component;
/**
* @author lengleng
* @date 2017/12/29
* spring security 异常转化器
* 默认的国际化的异常信息在 spring-security-code下messages_zh_CN
* LdapAuthenticationProvider.badCredentials=坏的凭证
* LdapAuthenticationProvider.credentialsExpired=用户凭证已过期
* LdapAuthenticationProvider.disabled=用户已失效
* LdapAuthenticationProvider.expired=用户帐号已过期
* LdapAuthenticationProvider.locked=用户帐号已被锁定
* LdapAuthenticationProvider.emptyUsername=用户名不允许为空
* LdapAuthenticationProvider.onlySupports=仅仅支持UsernamePasswordAuthenticationToken
* PasswordComparisonAuthenticator.badCredentials=坏的凭证
*/
@Component
public class PigWebResponseExceptionTranslator extends DefaultWebResponseExceptionTranslator {
/**
* @param e spring security内部异常
* @return 经过处理的异常信息
* @throws Exception 通用异常
*/
@Override
public ResponseEntity<OAuth2Exception> translate(Exception e) throws Exception {
OAuth2Exception oAuth2Exception;
if (e instanceof InvalidGrantException && StringUtils.equals("坏的凭证",e.getMessage())) {
oAuth2Exception = new InvalidGrantException("密码错误", e);
} else if (e instanceof InternalAuthenticationServiceException) {
oAuth2Exception = new InvalidGrantException("用户名不存在", e);
} else {
oAuth2Exception = (OAuth2Exception) e;
}
return super.translate(oAuth2Exception);
}
}

View File

@ -1,19 +1,24 @@
package com.github.pig.auth.config;
import com.github.pig.auth.component.PigWebResponseExceptionTranslator;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.constant.SecurityConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
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.provider.error.WebResponseExceptionTranslator;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
@ -38,6 +43,9 @@ public class PigAuthorizationConfig extends AuthorizationServerConfigurerAdapter
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Autowired
private PigWebResponseExceptionTranslator pigWebResponseExceptionTranslator;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
@ -53,6 +61,7 @@ public class PigAuthorizationConfig extends AuthorizationServerConfigurerAdapter
.tokenStore(new RedisTokenStore(redisConnectionFactory))
.accessTokenConverter(jwtAccessTokenConverter())
.authenticationManager(authenticationManager)
.exceptionTranslator(pigWebResponseExceptionTranslator)
.reuseRefreshTokens(false)
.userDetailsService(userDetailsService);
}

View File

@ -21,13 +21,13 @@ public class UserDetailsImpl implements UserDetails {
private String username;
private String password;
private String statusLock;
private String status;
private List<SysRole> roleList = new ArrayList<>();
public UserDetailsImpl(UserVo userVo) {
this.username = userVo.getUsername();
this.password = userVo.getPassword();
this.statusLock = userVo.getDelFlag();
this.status = userVo.getDelFlag();
roleList = userVo.getRoleList();
}
@ -57,7 +57,7 @@ public class UserDetailsImpl implements UserDetails {
@Override
public boolean isAccountNonLocked() {
return StringUtils.equals(CommonConstant.STATUS_LOCK, statusLock) ? false : true;
return StringUtils.equals(CommonConstant.STATUS_LOCK, status) ? false : true;
}
@Override
@ -67,7 +67,7 @@ public class UserDetailsImpl implements UserDetails {
@Override
public boolean isEnabled() {
return true;
return StringUtils.equals(CommonConstant.STATUS_NORMAL, status) ? false : true;
}
public void setUsername(String username) {
@ -86,11 +86,11 @@ public class UserDetailsImpl implements UserDetails {
this.roleList = roleList;
}
public String getStatusLock() {
return statusLock;
public String getStatus() {
return status;
}
public void setStatusLock(String statusLock) {
this.statusLock = statusLock;
public void setStatus(String status) {
this.status = status;
}
}

View File

@ -37,7 +37,7 @@ public class R<T> implements Serializable {
public R(Throwable e) {
super();
this.msg = e.toString();
this.msg = e.getMessage();
this.code = FAIL;
}

View File

@ -0,0 +1,31 @@
package com.github.pig.common.util.exception;
/**
* @author lengleng
* @date 2017-12-29 17:05:10
* 403 授权拒绝
*/
public class PigDeniedException extends RuntimeException {
private static final long serialVersionUID = 1L;
public PigDeniedException() {
}
public PigDeniedException(String message) {
super(message);
}
public PigDeniedException(Throwable cause) {
super(cause);
}
public PigDeniedException(String message, Throwable cause) {
super(message, cause);
}
public PigDeniedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@ -0,0 +1,53 @@
package com.github.pig.gateway.componet;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.util.R;
import com.github.pig.common.util.exception.PigDeniedException;
import org.apache.http.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author lengleng
* @date 2017/12/29
* 授权拒绝处理器覆盖默认的OAuth2AccessDeniedHandler
* 包装失败信息到PigDeniedException
*/
@Component
public class PigAccessDeniedHandler extends OAuth2AccessDeniedHandler {
private static Logger logger = LoggerFactory.getLogger(PigAccessDeniedHandler.class);
@Autowired
private ObjectMapper objectMapper;
/**
* 授权拒绝处理使用R包装
*
* @param request request
* @param response response
* @param authException authException
* @throws IOException IOException
* @throws ServletException ServletException
*/
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException authException) throws IOException, ServletException {
logger.info("授权失败,禁止访问");
response.setCharacterEncoding(CommonConstant.UTF8);
response.setContentType(CommonConstant.CONTENT_TYPE);
R<String> result = new R<>(new PigDeniedException("授权失败,禁止访问"));
response.setStatus(HttpStatus.SC_FORBIDDEN);
PrintWriter printWriter = response.getWriter();
printWriter.append(objectMapper.writeValueAsString(result));
}
}

View File

@ -1,18 +1,26 @@
package com.github.pig.gateway.config;
import com.github.pig.gateway.componet.PigAccessDeniedHandler;
import com.github.pig.gateway.filter.ValidateCodeFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
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.expression.OAuth2WebSecurityExpressionHandler;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author lengleng
* @date 2017/10/27
@ -25,6 +33,8 @@ public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter
@Autowired
private OAuth2WebSecurityExpressionHandler expressionHandler;
@Autowired
private PigAccessDeniedHandler pigAccessDeniedHandler;
@Autowired
private ValidateCodeFilter validateCodeFilter;
@Override
@ -40,11 +50,12 @@ public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.expressionHandler(expressionHandler);
}
public void configure(ResourceServerSecurityConfigurer resources) {
resources.expressionHandler(expressionHandler);
resources.accessDeniedHandler(pigAccessDeniedHandler);
}
/**
/**
* 配置解决 spring-security-oauth问题
* https://github.com/spring-projects/spring-security-oauth/issues/730
*

View File

@ -1,6 +1,7 @@
package com.github.pig.gateway.filter;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.constant.SecurityConstants;
import com.github.pig.common.util.R;
@ -36,6 +37,8 @@ public class ValidateCodeFilter extends OncePerRequestFilter {
private boolean isValidate;
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private ObjectMapper objectMapper;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
@ -48,11 +51,10 @@ public class ValidateCodeFilter extends OncePerRequestFilter {
logger.info("登录失败:{}", e.getMessage());
response.setCharacterEncoding(CommonConstant.UTF8);
response.setContentType(CommonConstant.CONTENT_TYPE);
R<String> result = new R<>(e.getMessage());
result.setCode(478);
R<String> result = new R<>(e);
response.setStatus(478);
printWriter = response.getWriter();
printWriter.append(JSONObject.toJSONString(result));
printWriter.append(objectMapper.writeValueAsString(result));
} finally {
IOUtils.closeQuietly(printWriter);
}

View File

@ -64,7 +64,8 @@ public class LogSendServiceImpl implements LogSendService {
}
//正常发送服务异常解析
if (requestContext.getResponseStatusCode() != HttpStatus.SC_OK) {
if (requestContext.getResponseStatusCode() != HttpStatus.SC_OK
&& requestContext.getResponseDataStream() != null) {
InputStream inputStream = requestContext.getResponseDataStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream stream1 = null;