Spring Security oauth2. 0 wechat applet login

Time:2022-2-13

Wechat applet preliminary development preparation, you can refer to this articlePreliminary preparation of wechat applet
1. Studied spring security oauth2 0 knows that it has four login modes to choose from
Authorization code (authorization code mode)
Implicit (simplified mode)
Resource owner password credentials
Client credentialsSpring Security oauth2. 0 wechat applet login
The first three modes require the user’s password to authenticate successfully. Although the client mode does not require a password, it will not be bound to the user. Therefore, it is also inconsistent. After we go to wechat to get the user’s authentication, we need to pass our own system authentication, and then return the token to the front end. If the system adopts oauth2 0 to do authentication. At this time, we can’t get the user’s plaintext password. And the general password is encrypted with bcryptpasswordencoder, which is irreversible. At this time, although we have passed the authentication of wechat, how to pass the authentication of our own system is a problem. Then you need to customize oauth2 0, and the authentication is completed through the user’s unique ID returned by wechat.
The method here is applicable to any third-party login:
First, we need an Interceptor:
The login interface is as follows

Port 9999 is the gateway gateway port. Auth is gateway routing
http://192.168.2.171:9999/auth/custom/token/social?grant_type=custom&custom=WXCUSTOM @{this is followed by the code obtained by wechat}
Header information: basic d3hnaw5pqxbwq3vzdg9tond4twluaufwcen1c3rvbq = = (this is followed by Base64 encrypted information)

Login URL interceptor

Note that here is the filter to take over the request, not to the controller)

import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
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.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;
import javax.servlet.http.HttpServletResponse;

/**
 * @author Mylucy
 * @Date 2022-01-18 10:15
 *Customer wechat applet login
 */
public class SocialAuthenticationFilter extends AbstractAuthenticationProcessingFilter {


	private static final String SPRING_SECURITY_FORM_CUSTOM_KEY = "custom";

	@Getter
	@Setter
	private String customWxLogin = SPRING_SECURITY_FORM_CUSTOM_KEY;

	@Getter
	@Setter
	private AuthenticationEventPublisher eventPublisher;
	@Getter
	@Setter
	private boolean postOnly = true;

//	@Getter
//	@Setter
//	private AuthenticationEventPublisher eventPublisher;

	@Getter
	@Setter
	private AuthenticationEntryPoint authenticationEntryPoint;

	public SocialAuthenticationFilter() {
		super(new AntPathRequestMatcher(SecurityConstants.CUSTOM_TOKE_URL, "POST"));
	}

	/**
	 * Performs actual authentication.
	 * <p>
	 * The implementation should do one of the following:
	 * <ol>
	 * <li>Return a populated authentication token for the authenticated user, indicating
	 * successful authentication</li>
	 * <li>Return null, indicating that the authentication process is still in progress.
	 * Before returning, the implementation should perform any additional work required to
	 * complete the process.</li>
	 * <li>Throw an <tt>AuthenticationException</tt> if the authentication process
	 * fails</li>
	 * </ol>
	 *
	 * @param request  from which to extract parameters and perform the authentication
	 * @param response the response, which may be needed if the implementation has to do a
	 *                 redirect as part of a multi-stage authentication process (such as OpenID).
	 * @return the authenticated user token, or null if authentication is incomplete.
	 * @throws AuthenticationException if authentication fails.
	 */
	@Override
	@SneakyThrows
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)  {
		if (postOnly && !request.getMethod().equals(HttpMethod.POST.name())) {
			throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
		}

		String mobile = obtainMobile(request);

		if (mobile == null) {
			mobile = "";
		}

		mobile = mobile.trim();

		SocialAuthenticationToken socialAuthenticationToken = new SocialAuthenticationToken(mobile);

		setDetails(request, socialAuthenticationToken);

		Authentication authResult = null;
		try {
			authResult = this.getAuthenticationManager().authenticate(socialAuthenticationToken);

			logger.debug("Authentication success: " + authResult);
			SecurityContextHolder.getContext().setAuthentication(authResult);

		} 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 authResult;
	}

	private String obtainMobile(HttpServletRequest request) {
		return request.getParameter(customWxLogin);
	}

	private void setDetails(HttpServletRequest request, SocialAuthenticationToken authRequest) {
		authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
	}

}

Note: there are some constants in it. I also give the method code here

public interface SecurityConstants {

	/**
	 *Check inner annotation security at startup
	 */
	boolean INNER_CHECK = true;

	/**
	 *Refresh
	 */
	String REFRESH_TOKEN = "refresh_token";

	/**
	 *Validity of verification code
	 */
	int CODE_TIME = 60;

	/**
	 *Verification code length
	 */
	String CODE_SIZE = "4";

	/**
	 *Role prefix
	 */
	String ROLE = "ROLE_";

	/**
	 *Prefix
	 */
	String PIGX_PREFIX = "pigx_";

	/**
	 *Token related prefix
	 */
	String TOKEN_PREFIX = "token:";

	/**
	 *OAuth related prefix
	 */
	String OAUTH_PREFIX = "oauth:";

	/**
	 *Authorization code mode code key prefix
	 */
	String OAUTH_CODE_PREFIX = "oauth:code:";

	/**
	 *License of the project
	 */
	String PIGX_LICENSE = "made by HuaBing";

	/**
	 *Inside
	 */
	String FROM_IN = "Y";

	/**
	 *Sign
	 */
	String FROM = "from";

	/**
	 * OAUTH URL
	 */
	String OAUTH_TOKEN_URL = "/oauth/token";

	/**
	 *Mobile number login URL
	 */
	String SMS_TOKEN_URL = "/mobile/token/sms";

	/**
	 *Social login URL
	 */
	String SOCIAL_TOKEN_URL = "/mobile/token/social";

	/**
	 *Custom login URL
	 */
	String MOBILE_TOKEN_URL = "/mobile/token/*";

	/**
	 *Customer social login
	 */
	String CUSTOM_TOKEN = "/custom/token/social";
	/**
	 *Customer wechat login
	 */
	String CUSTOM_TOKE_URL = "/custom/token/*";

	/**
	 *Wechat obtains openid
	 */
	String WX_AUTHORIZATION_CODE_URL = "https://api.weixin.qq.com/sns/oauth2/access_token"
			+ "?appid=%s&secret=%s&code=%s&grant_type=authorization_code";

	/**
	 *Wechat applet openid
	 */
	String MINI_APP_AUTHORIZATION_CODE_URL = "https://api.weixin.qq.com/sns/jscode2session"
			+ "?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";

	/**
	 *Customer wechat applet login
	 */
	String CUSTOM_WX_MINI_LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";
	/**
	 *Customer wechat applet login
	 */
	String CUSTOM_WX_MINI_LOGIN_TYPE = "authorization_code";

	String CUSTOM_APPID = "wx94e1329ed5419b55";
	String CUSTOM_SECRET="6d09e94f564d263340da3a3ede4ca6ab";

	/**
	 *Get token from code cloud
	 */
	String GITEE_AUTHORIZATION_CODE_URL = "https://gitee.com/oauth/token?grant_type="
			+ "authorization_code&code=%S&client_id=%s&redirect_uri=" + "%s&client_secret=%s";

	/**
	 *Open source China obtains token
	 */
	String OSC_AUTHORIZATION_CODE_URL = "https://www.oschina.net/action/openapi/token";

	/**
	 *Code cloud to obtain user information
	 */
	String GITEE_USER_INFO_URL = "https://gitee.com/api/v5/user?access_token=%s";

	/**
	 *Open source Chinese user information
	 */
	String OSC_USER_INFO_URL = "https://www.oschina.net/action/openapi/user?access_token=%s&dataType=json";

	/**
	 *{bcrypt} encrypted signature
	 */
	String BCRYPT = "{bcrypt}";

	/**
	 * sys_ oauth_ client_ The fields of the details table, excluding the client_ id、client_ secret
	 */
	String CLIENT_FIELDS = "client_id, CONCAT('{noop}',client_secret) as client_secret, resource_ids, scope, "
			+ "authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, "
			+ "refresh_token_validity, additional_information, autoapprove";

	/**
	 *Jdbcclientdetailsservice query statement
	 */
	String BASE_FIND_STATEMENT = "select " + CLIENT_FIELDS + " from sys_oauth_client_details";

	/**
	 *By condition client_ ID query
	 */
	String DEFAULT_SELECT_STATEMENT = BASE_FIND_STATEMENT + " where client_id = ? and del_flag = 0 and tenant_id = %s";

	/**
	 *Resource server default bean name
	 */
	String RESOURCE_SERVER_CONFIGURER = "resourceServerConfigurerAdapter";

	/**
	 *Client mode
	 */
	String CLIENT_CREDENTIALS = "client_credentials";

	/**
	 *Client number
	 */
	String CLIENT_ID = "client_id";

	/**
	 *User ID field
	 */
	String DETAILS_USER_ID = "id";

	/**
	 *User name
	 */
	String DETAILS_USERNAME = "username";

	/**
	 *Basic user information
	 */
	String DETAILS_USER = "user_info";

	/**
	 *User namephone
	 */
	String DETAILS_PHONE = "phone";

	/**
	 *Avatar
	 */
	String DETAILS_AVATAR = "avatar";

	/**
	 *User department field
	 */
	String DETAILS_DEPT_ID = "deptId";

	/**
	 *Tenant ID field
	 */
	String DETAILS_TENANT_ID = "tenantId";

	/**
	 *Protocol field
	 */
	String DETAILS_LICENSE = "license";

	/**
	 *The activation field is compatible with peripheral system access
	 */
	String ACTIVE = "active";

	/**
	 *AES encryption
	 */
	String AES = "aes";

}

Get customer login information

Note: I’m divided into background user login and foreground customer login. Different users can query two different tables

package com.pig4cloud.pigx.common.security.custom;

/**
 * @author Mylucy
 * @Date 2022-01-18 10:24
 */

import com.pig4cloud.pigx.common.security.component.PigxPreAuthenticationChecks;
import com.pig4cloud.pigx.common.security.service.PigxUserDetailsService;
import com.pig4cloud.pigx.common.security.util.PigxSecurityMessageSourceUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsChecker;

/**
 *Social login
 */
@Slf4j
public class SocialAuthenticationProvider implements AuthenticationProvider {

	private MessageSourceAccessor messages = PigxSecurityMessageSourceUtil.getAccessor();

	private UserDetailsChecker detailsChecker = new PigxPreAuthenticationChecks();

	@Getter
	@Setter
	private PigxUserDetailsService userDetailsService;

	@Override
	@SneakyThrows
	public Authentication authenticate(Authentication authentication) {
		SocialAuthenticationToken socialAuthenticationToken = (SocialAuthenticationToken) authentication;

		String principal = socialAuthenticationToken.getPrincipal().toString();
		//Here is the way to get customer information
		UserDetails userDetails = userDetailsService.customLoadBySocial(principal);
		if (userDetails == null) {
			log.debug("Authentication failed: no credentials provided");

			throw new BadCredentialsException(messages
					.getMessage("AbstractUserDetailsAuthenticationProvider.noopBindAccount", "Noop Bind Account"));
		}

		//Check account status
		detailsChecker.check(userDetails);

		SocialAuthenticationToken authenticationToken = new SocialAuthenticationToken(userDetails,
				userDetails.getAuthorities());
		authenticationToken.setDetails(socialAuthenticationToken.getDetails());
		return authenticationToken;
	}

	@Override
	public boolean supports(Class<?> authentication) {
		return SocialAuthenticationToken.class.isAssignableFrom(authentication);
	}

}

Method of obtaining user information

/**
Here you can expand your own user query method
* @author lengleng
* @date 2018/8/15
*/
public interface PigxUserDetailsService extends UserDetailsService {
/**
*Customer social login
*
*@ param codeunique identifier obtained from wechat by the front end
* @return
* @throws UsernameNotFoundException
*/
UserDetails customLoadBySocial(String code) throws UsernameNotFoundException;
}
==============================================Split================================================
/**
*User details
*
* @author lengleng
*/
@Slf4j
@Primary
@RequiredArgsConstructor
public class PigxUserDetailsServiceImpl implements PigxUserDetailsService {
private final RemoteUserService remoteUserService;
private final RemoteCustomService remoteCustomService;
private final CacheManager cacheManager;
private final TokenStore tokenStore;
/**
*Customer social login
*
* @param code
* @return
* @throws UsernameNotFoundException
*/
@Override
@SneakyThrows
public UserDetails customLoadBySocial(String code) {
//Here, the customer table information can be queried remotely
FoodMacCustom customSocialInfo = remoteCustomService.getCustomSocialInfo(code, SecurityConstants.FROM_IN).getData();
UserDetails customDetails = getCustomDetails(customSocialInfo);
return customDetails;
}
/**
*Build customer informationcustomdetails
*
* @param foodMacCustom
*/
private UserDetails getCustomDetails(FoodMacCustom foodMacCustom) {
if (foodMacCustom == null) {
Throw new usernamenotfoundexception ("customer not registered");
}
boolean is_lock = false;
if (CommonConstants.CUSTOM_LOCK.equals(foodMacCustom.getStatus())) {
is_lock = true;
}
if (is_lock == false) {
Throw new pigxauth2exception ("account has been locked");
}
log. Debug ("user information: {}", foodmaccustom. Getusername());
PigxCustomUser pigxCustomUser = new PigxCustomUser(foodMacCustom.getId(), 1, foodMacCustom.getMobile(), foodMacCustom.getAvatar(), foodMacCustom.getTenantId(),
foodMacCustom.getUsername(), "{noop}" + foodMacCustom.getPassword(), true, true,
true, is_lock, AuthorityUtils.NO_AUTHORITIES);
return pigxCustomUser;
}
}
===================================================Split==============================================================
/**
*System social login account table
*
* @author Mylucy
* @date 2021-08-16 21:30:41
*/
public interface SysSocialDetailsService extends IService<SysSocialDetails> {
/**
*Query customer information according to input parameters
*
* @param code
* @return
*/
FoodMacCustom getCustomSocialInfo(String code);
}
===================================================Split==============================================================
/**
* @author Mylucy
*@ date August 16, 2021
*/
@Slf4j
@AllArgsConstructor
@Service("sysSocialDetailsService")
public class SysSocialDetailsServiceImpl extends ServiceImpl<SysSocialDetailsMapper, SysSocialDetails>
implements SysSocialDetailsService {
//Pay attention to this method. This has done a lot of shame
private final Map<String, CustomLoginHandle> customLoginHandlerMap;
private final CacheManager cacheManager;
private final SysUserMapper sysUserMapper;
/**
*Query customer information according to input parameters
*
* @param code
* @return
*/
@Override
public FoodMacCustom getCustomSocialInfo(String code) {
String[] inStrs = code.split(StringPool.AT);
String type = inStrs[0];
String loginStr = inStrs[1];
FoodMacCustom foodMacCustom = customLoginHandlerMap.get(type).handle(loginStr);
return foodMacCustom;
}
}
===================================================Split==============================================================
/**
* @author Mylucy
* @Date 2022-01-18 11:02
*/
public interface CustomLoginHandle {
/***
*Data validity verification
*@ param loginstr get wechat unique ID through user incoming
* @return
*/
Boolean check(String loginStr);
/**
*Get wechat unique ID through user incoming
* @param loginStr
* @return
*/
String identify(String loginStr);
/**
*Get user information through wechat openid
* @param identify
* @return
*/
FoodMacCustom customInfo(String identify);
/**
*Treatment method
*@ param loginstr login parameters
* @return
*/
FoodMacCustom handle(String loginStr);
}
===================================================Split==============================================================
/**
* @author Mylucy
* @Date 2022-01-18 11:04
*/
public abstract class AbstractCustomLoginHandler implements CustomLoginHandle {
/***
*Data validity verification
*@ param loginstr obtains the unique ID through user incoming
*@ return no verification by default
*/
@Override
public Boolean check(String loginStr) {
return true;
}
/**
*Treatment method
*
*@ param loginstr login parameters
* @return
*/
@Override
public FoodMacCustom handle(String loginStr) {
if (!check(loginStr)) {
return null;
}
String identify = identify(loginStr);
FoodMacCustom foodMacCustom = customInfo(identify);
return foodMacCustom;
}
}
===================================================Split==============================================================
/**
* @author Mylucy
* @Date 2022-01-18 11:03
*/
@Slf4j
@Component("WXCUSTOM")
@AllArgsConstructor
public class CustomWeChatLoginHandler extends AbstractCustomLoginHandler {
private final IFoodMacCustomService foodMacCustomService;
private final SysSocialDetailsMapper sysSocialDetailsMapper;
private final StringRedisTemplate stringRedisTemplate;
private static final String REDIS_KEY = "WX:CUSTOM:LOGIN:";
private final Sequence sequence;
/**
*Two hours overdue
*/
private static final long EXPIRE_TIME = 7200000;
/**
*Wechat login incoming code
* <p>
*Call QQ through code to obtain unique identification
*
* @param code
* @return
*/
@Override
public String identify(String code) {
String sessionKeyOpenId = (String) stringRedisTemplate.opsForValue().get(REDIS_KEY + code);
if (StrUtil.isEmpty(sessionKeyOpenId)) {
SysSocialDetails condition = new SysSocialDetails();
condition.setType(LoginTypeEnum.WECHAT.getType());
SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition));
/**String url = String.format(SecurityConstants.MINI_APP_AUTHORIZATION_CODE_URL, socialDetails.getAppId(),socialDetails.getAppSecret(), code);
String result = HttpUtil.get(sendUrl);**/
log. Debug ("customer -- > {}", code);
String result = sendGet(SecurityConstants.CUSTOM_WX_MINI_LOGIN_URL,
"appid=" + socialDetails.getAppId() + "&" +
"secret=" + socialDetails.getAppSecret() + "&" +
"js_code=" + code + "&" +
"grant_type=" + SecurityConstants.CUSTOM_WX_MINI_LOGIN_TYPE);
log. Info ("wechat response message: {}", result);
JSONObject jsonObject = JSON.parseObject(result);
String openId = jsonObject.getString("openid");
String sessionKey = jsonObject.getString("session_key");
log. Info ("wechat openid:: {}", openid);
log. Info ("wechat sessionkey:: {}", sessionkey);
if (openId != null && !"".equals(openId)) {
//Save the information in redis
log. Info ("wechat key + + + + + + {}", sessionkey);
String redisKey = REDIS_KEY + code;
StringBuilder stringBuilder = new StringBuilder();
String openIdSessionKey = stringBuilder.append(sessionKey).append("@").append(openId).toString();
//				String  openIdSessionKey= sessionKey + "#" + openId;
stringRedisTemplate.opsForValue().set(redisKey,openIdSessionKey,EXPIRE_TIME, TimeUnit.SECONDS);
}
return openId;
} else if (StrUtil.isNotEmpty(sessionKeyOpenId)) {
String[] split = sessionKeyOpenId.split("@");
String session = split[0];
String openId = split[1];
return openId;
}
return null;
}
/**
*Openid get user information
*
* @param openId
* @return
*/
@Override
public FoodMacCustom customInfo(String openId) {
FoodMacCustom custom = foodMacCustomService.getOne(Wrappers.<FoodMacCustom>query().lambda()
.eq(FoodMacCustom::getWechatopenid, openId));
if (custom == null) {
log. Info ("wechat Unbound: {}", openid);
return null;
}
return custom;
}
/**
*Sends a request for the get method to the specified URL
*
*@ param URL URL to send the request
*@ param param request parameter. The request parameter should be in the form of name1 = value1 & Name2 = Value2.
*@ return the response result of the remote resource represented by the URL
*/
public static String sendGet(String url, String param) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = url + "?" + param;
URL realUrl = new URL(urlNameString);
//Open connection between and URL
URLConnection connection = realUrl.openConnection();
//Set common request properties
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
//Establish actual connection
connection.connect();
//Get all response header fields
Map<String, List<String>> map = connection.getHeaderFields();
//Traverse all response header fields
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
//Define BufferedReader input stream to read the response of URL
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System. out. Println ("exception in sending get request!"+ e);
e.printStackTrace();
}
//Use the finally input block to close
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
}

Screenshot of remote calling controller and fegin calling methods
Spring Security oauth2. 0 wechat applet login
Spring Security oauth2. 0 wechat applet login

Generate token token:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.SneakyThrows;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;
import java.util.Collection;
/**
*Third party login token
*
* @author Mylucy
* @Date 2022-01-18 10:23
*/
public class SocialAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
private final Object principal;
public SocialAuthenticationToken(String mobile) {
super(null);
this.principal = mobile;
setAuthenticated(false);
}
@JsonCreator
public SocialAuthenticationToken(@JsonProperty("principal") Object principal,
@JsonProperty("authorities") Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
super.setAuthenticated(true);
}
@Override
public Object getPrincipal() {
return this.principal;
}
@Override
public Object getCredentials() {
return null;
}
@Override
@SneakyThrows
public void setAuthenticated(boolean isAuthenticated) {
if (isAuthenticated) {
throw new IllegalArgumentException(
"Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
}
super.setAuthenticated(false);
}
@Override
public void eraseCredentials() {
super.eraseCredentials();
}
}

Third party resource allocation portal:

```java
package com.pig4cloud.pigx.common.security.custom;
/**
* @author Mylucy
* @Date 2022-01-18 10:27
*/
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pig4cloud.pigx.common.security.component.PigxCommenceAuthExceptionEntryPoint;
import com.pig4cloud.pigx.common.security.handler.CustomLoginSuccessHandler;
import com.pig4cloud.pigx.common.security.service.PigxUserDetailsService;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationEventPublisher;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
*
*Third party login configuration portal
* @author Mylucy
*/
@Getter
@Setter
public class SocialSecurityConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
@Autowired
private ObjectMapper objectMapper;
@Autowired
private AuthenticationEventPublisher defaultAuthenticationEventPublisher;
/**
* @Qualifier("socialLoginSuccessHandler")
*/
@Autowired
private CustomLoginSuccessHandler socialLoginSuccessHandler;
@Autowired
private PigxUserDetailsService userDetailsService;
@Override
public void configure(HttpSecurity http) {
SocialAuthenticationFilter socialAuthenticationFilter = new SocialAuthenticationFilter();
socialAuthenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
socialAuthenticationFilter.setAuthenticationSuccessHandler(socialLoginSuccessHandler);
socialAuthenticationFilter.setEventPublisher(defaultAuthenticationEventPublisher);
socialAuthenticationFilter.setAuthenticationEntryPoint(new PigxCommenceAuthExceptionEntryPoint(objectMapper));
SocialAuthenticationProvider socialAuthenticationProvider = new SocialAuthenticationProvider();
socialAuthenticationProvider.setUserDetailsService(userDetailsService);
http.authenticationProvider(socialAuthenticationProvider).addFilterAfter(socialAuthenticationFilter,
UsernamePasswordAuthenticationFilter.class);
}
}