Commit ed65a030 authored by fangxinjiang's avatar fangxinjiang

鉴权-fxj

parent 524b3d31
......@@ -21,6 +21,7 @@ import com.yifu.cloud.plus.v1.yifu.auth.filter.PasswordDecoderFilter;
import com.yifu.cloud.plus.v1.yifu.auth.filter.WxLoginAuthenticationFilter;
import com.yifu.cloud.plus.v1.yifu.auth.handler.YifuAuthenticationFailureHandlerImpl;
import com.yifu.cloud.plus.v1.yifu.auth.handler.YifuClientLoginSuccessHandler;
import com.yifu.cloud.plus.v1.yifu.auth.handler.YifuWxLoginSuccessHandler;
import com.yifu.cloud.plus.v1.yifu.common.security.component.CasAuthenticationProvider;
import com.yifu.cloud.plus.v1.yifu.common.security.component.WxAuthenticationProvider;
import com.yifu.cloud.plus.v1.yifu.common.security.component.YifuDaoAuthenticationProvider;
......@@ -201,7 +202,7 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
} catch (Exception e) {
log.error("WebSecurityConfigurer>>>>",e);
}
filter.setAuthenticationSuccessHandler(yifuClientLoginSuccessHandler());
filter.setAuthenticationSuccessHandler(authenticationSuccessHandler());
filter.setAuthenticationFailureHandler(yifuAuthenticationFailureHandler());
return filter;
}
......@@ -210,7 +211,15 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
return YifuAuthenticationFailureHandlerImpl.builder()
.objectMapper(objectMapper).build();
}
private AuthenticationSuccessHandler authenticationSuccessHandler() {
return YifuWxLoginSuccessHandler.builder()
.objectMapper(objectMapper)
.clientDetailsService(clientDetailsService)
.passwordEncoder(passwordEncoder())
.cacheManager(cacheManager)
.tokenStore(tokenStore)
.defaultAuthorizationServerTokenServices(defaultAuthorizationServerTokenServices).build();
}
private AuthenticationSuccessHandler yifuClientLoginSuccessHandler() {
return YifuClientLoginSuccessHandler.builder()
.objectMapper(objectMapper)
......
package com.yifu.cloud.plus.v1.yifu.auth.handler;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.CharsetUtil;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yifu.cloud.plus.v1.yifu.auth.constants.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.util.WebUtils;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.security.exception.InvalidException;
import com.yifu.cloud.plus.v1.yifu.common.security.util.AuthUtils;
import com.yifu.cloud.plus.v1.yifu.common.security.vo.UserAndToke;
import lombok.Builder;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MarkerFactory;
import org.springframework.cache.CacheManager;
import org.springframework.http.HttpHeaders;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestValidator;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
/**
* @author fxj * @date 2022年05月30日 14:55 @description
*/
@Slf4j
@Builder
public class YifuWxLoginSuccessHandler implements AuthenticationSuccessHandler {
private ObjectMapper objectMapper;
private PasswordEncoder passwordEncoder;
private ClientDetailsService clientDetailsService;
private AuthorizationServerTokenServices defaultAuthorizationServerTokenServices;
private TokenStore tokenStore;
private final CacheManager cacheManager;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
String header = request.getHeader(SecurityConstants.CLIENT_HEADER_KEY_NEW);
if(Common.isEmpty(header)){
header = request.getHeader(SecurityConstants.CLIENT_HEADER_KEY);
//兼容老逻辑
if(Common.isEmpty(header)){
header = request.getHeader(HttpHeaders.AUTHORIZATION);
}
}
YifuUser user = null;
try {
user = (YifuUser)authentication.getPrincipal();
if (header == null) {
throw new InvalidClientException("请求头中client信息为空");
}
String[] tokens = AuthUtils.extractAndDecodeHeader(header);
assert tokens.length == 2;
String clientId = tokens[0];
ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
//校验secret
if (!passwordEncoder.matches(tokens[1], clientDetails.getClientSecret())) {
throw new InvalidClientException("请求头中client信息验证异常");
}
TokenRequest tokenRequest = new TokenRequest(MapUtil.newHashMap(), clientId, clientDetails.getScope(), "password");
//校验scope
new DefaultOAuth2RequestValidator().validateScope(tokenRequest, clientDetails);
OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
OAuth2AccessToken oAuth2AccessToken = null;
oAuth2AccessToken = defaultAuthorizationServerTokenServices.getAccessToken(oAuth2Authentication);
if(null == oAuth2AccessToken){
oAuth2AccessToken = defaultAuthorizationServerTokenServices.createAccessToken(oAuth2Authentication);
}else{
Map<String, Object> additionalInformation = clientDetails.getAdditionalInformation();
if(null != additionalInformation && null != additionalInformation.get(SecurityConstants.MUTUALLY_EXCLUSIVE_LOGIN)){
//单点刷新老的token生成新token
tokenStore.removeAccessToken(oAuth2AccessToken);
oAuth2AccessToken = defaultAuthorizationServerTokenServices.createAccessToken(oAuth2Authentication);
}
}
log.info("获取token 成功:{}", oAuth2AccessToken.getValue());
R<UserAndToke> result = new R<>(new UserAndToke(oAuth2AccessToken,user));
backResult(response, result);
} catch (Exception e) {
if (e instanceof InvalidException){
throw (InvalidException)e ;
}else if(e instanceof InvalidClientException){
String ip = WebUtils.getIP(request);
if( null != ip && !ip.startsWith("127") && !ip.startsWith("192.168")){
log.error(MarkerFactory.getMarker("MAIL"),"{}({})登录错误(触发黑名单逻辑)ip:{},头部信息为:{}",null==user?"":user.getUsername(),null==user?"":user.getUsername(),ip, JSONObject.toJSON(WebUtils.getHeadersInfo(request)));
}else{
log.error(MarkerFactory.getMarker("MAIL"),"{}({})登录错误ip:{},头部信息为:{}",null==user?"":user.getUsername(),null==user?"":user.getUsername(),ip, JSONObject.toJSON(WebUtils.getHeadersInfo(request)));
}
throw (InvalidClientException)e;
}else{
log.error(MarkerFactory.getMarker("MAIL"),"{}({})登录错误ip:{},头部信息为:{}",null==user?"":user.getUsername(),null==user?"":user.getUsername(),WebUtils.getIP(request), JSONObject.toJSON(WebUtils.getHeadersInfo(request)));
throw new InvalidException("未知异常请联系管理员!",e);
}
}
}
private void backResult(HttpServletResponse response, R result) throws IOException {
response.setCharacterEncoding(CharsetUtil.UTF_8);
response.setContentType(CommonConstants.CONTENT_TYPE);
PrintWriter printWriter = response.getWriter();
printWriter.append(objectMapper.writeValueAsString(result));
}
}
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