mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-09 04:49:02 +08:00
✨ 添加新特性。 定制 entrypoint 未绑定异常返回
This commit is contained in:
1 parent
c79d8f76e2
commit
a56875aa90
16 files changed
+154
-14
No files matched your search
+3
-3
@@ -94,15 +94,15 @@ public class PigxUserDetailsServiceImpl implements PigxUserDetailsService {
|
||||
String url = String.format(WX_AUTHORIZATION_CODE_URL
|
||||
, wxSocialConfig.getAppid(), wxSocialConfig.getSecret(), code);
|
||||
String result = restTemplate.getForObject(url, String.class);
|
||||
log.debug("微信响应报文:{}", result);
|
||||
log.warn("微信响应报文:{}", result);
|
||||
|
||||
Object obj = JSONUtil.parseObj(result).get("openid");
|
||||
if (obj != null) {
|
||||
userInfo = remoteUserService.social(EnumLoginType.WECHAT.getType(), obj.toString());
|
||||
} else {
|
||||
throw new UsernameNotFoundException("获取用户openid失败");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return getUserDetails(userInfo);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,4 +20,4 @@ eureka:
|
||||
prefer-ip-address: true
|
||||
client:
|
||||
service-url:
|
||||
defaultZone: http://pig:pig@pigx-eureka:1025/eureka/
|
||||
defaultZone: http://pig:pig@localhost:1025/eureka/
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.security.mobile;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.springframework.security.oauth2.provider.error.AbstractOAuth2SecurityExceptionHandler;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/8/16
|
||||
* 手机号登录异常处理
|
||||
*/
|
||||
public class MobileAuthenticationEntryPoint extends AbstractOAuth2SecurityExceptionHandler implements
|
||||
AuthenticationEntryPoint {
|
||||
private static final String WWW_AUTHENTICATE = "WWW-Authenticate";
|
||||
private static final String SUFFIX = ",";
|
||||
|
||||
@Override
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
|
||||
throws IOException, ServletException {
|
||||
doHandle(request, response, authException);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<OAuth2Exception> enhanceResponse(ResponseEntity<OAuth2Exception> response, Exception exception) {
|
||||
HttpHeaders headers = response.getHeaders();
|
||||
String existing = null;
|
||||
if (headers.containsKey(WWW_AUTHENTICATE)) {
|
||||
existing = extractTypePrefix(headers.getFirst("WWW-Authenticate"));
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String typeName = OAuth2AccessToken.BEARER_TYPE;
|
||||
builder.append(typeName + " ");
|
||||
String realmName = "oauth";
|
||||
builder.append("realm=\"" + realmName + "\"");
|
||||
if (existing != null) {
|
||||
builder.append(", " + existing);
|
||||
}
|
||||
HttpHeaders update = new HttpHeaders();
|
||||
update.putAll(response.getHeaders());
|
||||
update.set("WWW-Authenticate", builder.toString());
|
||||
return new ResponseEntity<>(response.getBody(), update, HttpStatus.EXPECTATION_FAILED);
|
||||
}
|
||||
|
||||
private String extractTypePrefix(String header) {
|
||||
String existing = header;
|
||||
String[] tokens = existing.split(" +");
|
||||
if (tokens.length > 1 && !tokens[0].endsWith(SUFFIX)) {
|
||||
existing = StringUtils.arrayToDelimitedString(tokens, " ").substring(existing.indexOf(" ") + 1);
|
||||
}
|
||||
return existing;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+37
-1
@@ -21,10 +21,17 @@ import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.authentication.AuthenticationEventPublisher;
|
||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -37,6 +44,8 @@ import javax.servlet.http.HttpServletResponse;
|
||||
*/
|
||||
public class MobileAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
|
||||
private static final String SPRING_SECURITY_FORM_MOBILE_KEY = "mobile";
|
||||
private AuthenticationEventPublisher eventPublisher = new MobileAuthenticationFilter.NullEventPublisher();
|
||||
private AuthenticationEntryPoint authenticationEntryPoint = new MobileAuthenticationEntryPoint();
|
||||
@Getter
|
||||
@Setter
|
||||
private String mobileParameter = SPRING_SECURITY_FORM_MOBILE_KEY;
|
||||
@@ -68,7 +77,24 @@ public class MobileAuthenticationFilter extends AbstractAuthenticationProcessing
|
||||
|
||||
setDetails(request, mobileAuthenticationToken);
|
||||
|
||||
return this.getAuthenticationManager().authenticate(mobileAuthenticationToken);
|
||||
try {
|
||||
return this.getAuthenticationManager().authenticate(mobileAuthenticationToken);
|
||||
|
||||
} catch (Exception failed) {
|
||||
SecurityContextHolder.clearContext();
|
||||
logger.debug("Authentication request failed: " + failed);
|
||||
|
||||
eventPublisher.publishAuthenticationFailure(new BadCredentialsException(failed.getMessage(), failed),
|
||||
new PreAuthenticatedAuthenticationToken("access-token", "N/A"));
|
||||
|
||||
try {
|
||||
authenticationEntryPoint.commence(request, response,
|
||||
new UsernameNotFoundException(failed.getMessage(), failed));
|
||||
} catch (Exception e) {
|
||||
logger.error("authenticationEntryPoint handle error:{}", failed);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String obtainMobile(HttpServletRequest request) {
|
||||
@@ -79,5 +105,15 @@ public class MobileAuthenticationFilter extends AbstractAuthenticationProcessing
|
||||
MobileAuthenticationToken authRequest) {
|
||||
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
|
||||
}
|
||||
|
||||
private static final class NullEventPublisher implements AuthenticationEventPublisher {
|
||||
@Override
|
||||
public void publishAuthenticationFailure(AuthenticationException exception, Authentication authentication) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishAuthenticationSuccess(Authentication authentication) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
@@ -20,10 +20,16 @@ package com.pig4cloud.pigx.common.security.mobile;
|
||||
import com.pig4cloud.pigx.common.security.util.PigxUserDetailsService;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
import org.springframework.security.authentication.AuthenticationEventPublisher;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.SpringSecurityMessageSource;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
@@ -31,7 +37,9 @@ import org.springframework.security.core.userdetails.UserDetails;
|
||||
* 手机登录校验逻辑
|
||||
* 验证码登录、社交登录
|
||||
*/
|
||||
@Slf4j
|
||||
public class MobileAuthenticationProvider implements AuthenticationProvider {
|
||||
private MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
|
||||
@Getter
|
||||
@Setter
|
||||
private PigxUserDetailsService userDetailsService;
|
||||
@@ -42,7 +50,14 @@ public class MobileAuthenticationProvider implements AuthenticationProvider {
|
||||
|
||||
String principal = mobileAuthenticationToken.getPrincipal().toString();
|
||||
UserDetails userDetails = userDetailsService.loadUserBySocial(principal);
|
||||
if (userDetails == null) {
|
||||
log.debug("Authentication failed: no credentials provided");
|
||||
|
||||
throw new BadCredentialsException(messages.getMessage(
|
||||
"AbstractUserDetailsAuthenticationProvider.noopBindAccount",
|
||||
"Noop Bind Account"));
|
||||
|
||||
}
|
||||
|
||||
MobileAuthenticationToken authenticationToken = new MobileAuthenticationToken(userDetails, userDetails.getAuthorities());
|
||||
authenticationToken.setDetails(mobileAuthenticationToken.getDetails());
|
||||
|
||||
+1
@@ -20,6 +20,7 @@ AbstractAccessDecisionManager.accessDenied=\u4E0D\u5141\u8BB8\u8BBF\u95EE
|
||||
AbstractLdapAuthenticationProvider.emptyPassword=\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A
|
||||
AbstractSecurityInterceptor.authenticationNotFound=\u672A\u5728SecurityContext\u4E2D\u67E5\u627E\u5230\u8BA4\u8BC1\u5BF9\u8C61
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials=\u7528\u6237\u540D\u4E0D\u5B58\u5728\u6216\u8005\u5BC6\u7801\u9519\u8BEF
|
||||
AbstractUserDetailsAuthenticationProvider.noopBindAccount=\u672A\u7ED1\u5B9A\u767B\u5F55\u8D26\u53F7\uFF0C\u8BF7\u4F7F\u7528\u5BC6\u7801\u767B\u5F55\u540E\u7ED1\u5B9A
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired=\u7528\u6237\u51ED\u8BC1\u5DF2\u8FC7\u671F
|
||||
AbstractUserDetailsAuthenticationProvider.disabled=\u7528\u6237\u672A\u6FC0\u6D3B
|
||||
AbstractUserDetailsAuthenticationProvider.expired=\u7528\u6237\u5E10\u53F7\u5DF2\u8FC7\u671F
|
||||
|
||||
@@ -19,7 +19,7 @@ eureka:
|
||||
prefer-ip-address: true
|
||||
client:
|
||||
service-url:
|
||||
defaultZone: http://pig:pig@pigx-eureka:1025/eureka/
|
||||
defaultZone: http://pig:pig@localhost:1025/eureka/
|
||||
|
||||
# 暴露监控端点
|
||||
management:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
spring:
|
||||
redis:
|
||||
password:
|
||||
host: redis
|
||||
host: localhost
|
||||
# 暴露监控端点
|
||||
management:
|
||||
endpoints:
|
||||
|
||||
@@ -12,3 +12,9 @@ social:
|
||||
wx:
|
||||
appid: wxd1678d3f83b1d83a
|
||||
secret: 6ddb043f94da5d2172926abe8533504f
|
||||
|
||||
# 社交登录配置新
|
||||
social:
|
||||
wx:
|
||||
appid: wxd1678d3f83b1d83a
|
||||
secret: 6ddb043f94da5d2172926abe8533504f
|
||||
@@ -13,7 +13,7 @@ spring:
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
username: root
|
||||
password: root
|
||||
url: jdbc:mysql://mysql:3306/pigx?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
|
||||
url: jdbc:mysql://114.116.45.246:13306/pigx?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
|
||||
jackson:
|
||||
time-zone: GMT+8
|
||||
date-format: yyyy-MM-dd HH:mm:ss
|
||||
|
||||
@@ -13,7 +13,7 @@ spring:
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
username: root
|
||||
password: root
|
||||
url: jdbc:mysql://mysql:3306/pigx?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
|
||||
url: jdbc:mysql://114.116.45.246:13306/pigx?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
|
||||
|
||||
# mybaits 模块配置
|
||||
mybatis-plus:
|
||||
|
||||
@@ -22,6 +22,6 @@ eureka:
|
||||
prefer-ip-address: true
|
||||
client:
|
||||
service-url:
|
||||
defaultZone: http://pig:pig@pigx-eureka:1025/eureka/
|
||||
defaultZone: http://pig:pig@localhost:1025/eureka/
|
||||
|
||||
|
||||
@@ -23,4 +23,4 @@ eureka:
|
||||
prefer-ip-address: true
|
||||
client:
|
||||
service-url:
|
||||
defaultZone: http://pig:pig@pigx-eureka:1025/eureka/
|
||||
defaultZone: http://pig:pig@localhost:1025/eureka/
|
||||
@@ -20,7 +20,7 @@ eureka:
|
||||
prefer-ip-address: true
|
||||
client:
|
||||
service-url:
|
||||
defaultZone: http://pig:pig@pigx-eureka:1025/eureka/
|
||||
defaultZone: http://pig:pig@localhost:1025/eureka/
|
||||
logging:
|
||||
level:
|
||||
root: debug
|
||||
@@ -20,4 +20,4 @@ eureka:
|
||||
prefer-ip-address: true
|
||||
client:
|
||||
service-url:
|
||||
defaultZone: http://pig:pig@pigx-eureka:1025/eureka/
|
||||
defaultZone: http://pig:pig@localhost:1025/eureka/
|
||||
@@ -20,4 +20,4 @@ eureka:
|
||||
prefer-ip-address: true
|
||||
client:
|
||||
service-url:
|
||||
defaultZone: http://pig:pig@pigx-eureka:1025/eureka/
|
||||
defaultZone: http://pig:pig@localhost:1025/eureka/
|
||||
Reference in new issue
Block a user