getAtomicValue(String path, RetryNTimes retryNTimes) {
try {
distributedAtomicInteger = new DistributedAtomicInteger(client, path, retryNTimes);
return distributedAtomicInteger.get();
} catch (Exception e) {
log.error("getAtomicValue={}", e.getMessage(), e);
}
return null;
}
/**
* Add cache data.
*
* @param cachePath the cache path
*/
@Override
public void addCacheData(final String cachePath) {
TreeCache cache = new TreeCache(client, cachePath);
try {
cache.start();
//CHECKSTYLE:OFF
} catch (final Exception ex) {
//CHECKSTYLE:ON
RegExceptionHandler.handleException(ex);
}
caches.put(cachePath + "/", cache);
}
/**
* Evict cache data.
*
* @param cachePath the cache path
*/
@Override
public void evictCacheData(final String cachePath) {
TreeCache cache = caches.remove(cachePath + "/");
if (null != cache) {
cache.close();
}
}
/**
* Gets raw cache.
*
* @param cachePath the cache path
*
* @return the raw cache
*/
@Override
public Object getRawCache(final String cachePath) {
return caches.get(cachePath + "/");
}
/**
* Register mq.
*
* @param app the app
* @param host the host
* @param producerGroup the producer group
* @param consumerGroup the consumer group
* @param namesrvAddr the namesrv addr
*/
@Override
public void registerMq(final String app, final String host, final String producerGroup, final String consumerGroup, String namesrvAddr) {
// 注册生产者
final String producerRootPath = GlobalConstant.ZK_REGISTRY_PRODUCER_ROOT_PATH + GlobalConstant.Symbol.SLASH + app;
final String consumerRootPath = GlobalConstant.ZK_REGISTRY_CONSUMER_ROOT_PATH + GlobalConstant.Symbol.SLASH + app;
ReliableMessageRegisterDto dto;
if (StringUtils.isNotEmpty(producerGroup)) {
dto = new ReliableMessageRegisterDto().setProducerGroup(producerGroup).setNamesrvAddr(namesrvAddr);
String producerJson = JSON.toJSONString(dto);
this.persist(producerRootPath, producerJson);
this.persistEphemeral(producerRootPath + GlobalConstant.Symbol.SLASH + host, DateUtil.now());
}
// 注册消费者
if (StringUtils.isNotEmpty(consumerGroup)) {
dto = new ReliableMessageRegisterDto().setConsumerGroup(consumerGroup).setNamesrvAddr(namesrvAddr);
String producerJson = JSON.toJSONString(dto);
this.persist(consumerRootPath, producerJson);
this.persistEphemeral(consumerRootPath + GlobalConstant.Symbol.SLASH + host, DateUtil.now());
}
}
}
================================================
FILE: paascloud-common/paascloud-common-zk/src/test/java/.gitkeep
================================================
================================================
FILE: paascloud-common/paascloud-security-app/pom.xml
================================================
4.0.0
paascloud-security-app
com.liuzm.paascloud.common
paascloud-common
1.0
com.liuzm.paascloud.common
paascloud-security-core
${paascloud.security.version}
================================================
FILE: paascloud-common/paascloud-security-app/src/main/java/com/paascloud/security/app/AppSecretException.java
================================================
/*
* Copyright (c) 2018. paascloud.net All Rights Reserved.
* 项目名称:paascloud快速搭建企业级分布式微服务平台
* 类名称:AppSecretException.java
* 创建人:刘兆明
* 联系方式:paascloud.net@gmail.com
* 开源地址: https://github.com/paascloud
* 博客地址: http://blog.paascloud.net
* 项目官网: http://paascloud.net
*/
package com.paascloud.security.app;
/**
* The class App secret exception.
*
* @author paascloud.net @gmail.com
*/
public class AppSecretException extends RuntimeException {
private static final long serialVersionUID = -1629364510827838114L;
/**
* Instantiates a new App secret exception.
*
* @param msg the msg
*/
public AppSecretException(String msg) {
super(msg);
}
}
================================================
FILE: paascloud-common/paascloud-security-app/src/main/java/com/paascloud/security/app/AppSecurityController.java
================================================
/*
* Copyright (c) 2018. paascloud.net All Rights Reserved.
* 项目名称:paascloud快速搭建企业级分布式微服务平台
* 类名称:AppSecurityController.java
* 创建人:刘兆明
* 联系方式:paascloud.net@gmail.com
* 开源地址: https://github.com/paascloud
* 博客地址: http://blog.paascloud.net
* 项目官网: http://paascloud.net
*/
package com.paascloud.security.app;
import com.paascloud.security.app.social.AppSingUpUtils;
import com.paascloud.security.core.properties.SecurityConstants;
import com.paascloud.security.core.social.BaseSocialController;
import com.paascloud.security.core.social.support.SocialUserInfo;
import org.springframework.http.HttpStatus;
import org.springframework.social.connect.Connection;
import org.springframework.social.connect.web.ProviderSignInUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
/**
* The class App security controller.
*
* @author paascloud.net@gmail.comg
*/
@RestController
public class AppSecurityController extends BaseSocialController {
@Resource
private ProviderSignInUtils providerSignInUtils;
@Resource
private AppSingUpUtils appSingUpUtils;
/**
* 需要注册时跳到这里,返回401和用户信息给前端
*
* @param request the request
*
* @return social user info
*/
@GetMapping(SecurityConstants.DEFAULT_SOCIAL_USER_INFO_URL)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public SocialUserInfo getSocialUserInfo(HttpServletRequest request) {
Connection> connection = providerSignInUtils.getConnectionFromSession(new ServletWebRequest(request));
appSingUpUtils.saveConnectionData(new ServletWebRequest(request), connection.createData());
return buildSocialUserInfo(connection);
}
}
================================================
FILE: paascloud-common/paascloud-security-app/src/main/java/com/paascloud/security/app/authentication/openid/OpenIdAuthenticationFilter.java
================================================
/*
* Copyright (c) 2018. paascloud.net All Rights Reserved.
* 项目名称:paascloud快速搭建企业级分布式微服务平台
* 类名称:OpenIdAuthenticationFilter.java
* 创建人:刘兆明
* 联系方式:paascloud.net@gmail.com
* 开源地址: https://github.com/paascloud
* 博客地址: http://blog.paascloud.net
* 项目官网: http://paascloud.net
*/
package com.paascloud.security.app.authentication.openid;
import com.paascloud.security.core.properties.SecurityConstants;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.Assert;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* The class Open id authentication filter.
*
* @author paascloud.net@gmail.com
*/
public class OpenIdAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
// ~ Static fields/initializers
// =====================================================================================
private String openIdParameter = SecurityConstants.DEFAULT_PARAMETER_NAME_OPENID;
private String providerIdParameter = SecurityConstants.DEFAULT_PARAMETER_NAME_PROVIDERID;
private boolean postOnly = true;
private static final String POST = "POST";
// ~ Constructors
// ===================================================================================================
/**
* Instantiates a new Open id authentication filter.
*/
OpenIdAuthenticationFilter() {
super(new AntPathRequestMatcher(SecurityConstants.DEFAULT_SIGN_IN_PROCESSING_URL_OPENID, "POST"));
}
// ~ Methods
// ========================================================================================================
/**
* Attempt authentication authentication.
*
* @param request the request
* @param response the response
*
* @return the authentication
*
* @throws AuthenticationException the authentication exception
*/
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
if (postOnly && !POST.equals(request.getMethod())) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
String openid = obtainOpenId(request);
String providerId = obtainProviderId(request);
if (openid == null) {
openid = "";
}
if (providerId == null) {
providerId = "";
}
openid = openid.trim();
providerId = providerId.trim();
OpenIdAuthenticationToken authRequest = new OpenIdAuthenticationToken(openid, providerId);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
/**
* 获取openId
*
* @param request the request
*
* @return the string
*/
protected String obtainOpenId(HttpServletRequest request) {
return request.getParameter(openIdParameter);
}
/**
* 获取提供商id
*
* @param request the request
*
* @return the string
*/
protected String obtainProviderId(HttpServletRequest request) {
return request.getParameter(providerIdParameter);
}
/**
* Provided so that subclasses may configure what is put into the
* authentication request's details property.
*
* @param request that an authentication request is being created for
* @param authRequest the authentication request object that should have its details set
*/
protected void setDetails(HttpServletRequest request, OpenIdAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}
/**
* Sets the parameter name which will be used to obtain the username from
* the login request.
*
* @param openIdParameter the open id parameter
*/
public void setOpenIdParameter(String openIdParameter) {
Assert.hasText(openIdParameter, "Username parameter must not be empty or null");
this.openIdParameter = openIdParameter;
}
/**
* Defines whether only HTTP POST requests will be allowed by this filter.
* If set to true, and an authentication request is received which is not a
* POST request, an exception will be raised immediately and authentication
* will not be attempted. The unsuccessfulAuthentication() method
* will be called as if handling a failed authentication.
*
* Defaults to true but may be overridden by subclasses.
*
* @param postOnly the post only
*/
public void setPostOnly(boolean postOnly) {
this.postOnly = postOnly;
}
/**
* Gets open id parameter.
*
* @return the open id parameter
*/
public final String getOpenIdParameter() {
return openIdParameter;
}
/**
* Gets provider id parameter.
*
* @return the provider id parameter
*/
public String getProviderIdParameter() {
return providerIdParameter;
}
/**
* Sets provider id parameter.
*
* @param providerIdParameter the provider id parameter
*/
public void setProviderIdParameter(String providerIdParameter) {
this.providerIdParameter = providerIdParameter;
}
}
================================================
FILE: paascloud-common/paascloud-security-app/src/main/java/com/paascloud/security/app/authentication/openid/OpenIdAuthenticationProvider.java
================================================
/*
* Copyright (c) 2018. paascloud.net All Rights Reserved.
* 项目名称:paascloud快速搭建企业级分布式微服务平台
* 类名称:OpenIdAuthenticationProvider.java
* 创建人:刘兆明
* 联系方式:paascloud.net@gmail.com
* 开源地址: https://github.com/paascloud
* 博客地址: http://blog.paascloud.net
* 项目官网: http://paascloud.net
*/
package com.paascloud.security.app.authentication.openid;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.security.SocialUserDetailsService;
import java.util.HashSet;
import java.util.Set;
/**
* The class Open id authentication provider.
*
* @author paascloud.net@gmail.com
*/
public class OpenIdAuthenticationProvider implements AuthenticationProvider {
private SocialUserDetailsService userDetailsService;
private UsersConnectionRepository usersConnectionRepository;
/**
* Authenticate authentication.
*
* @param authentication the authentication
*
* @return the authentication
*
* @throws AuthenticationException the authentication exception
*/
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
OpenIdAuthenticationToken authenticationToken = (OpenIdAuthenticationToken) authentication;
Set providerUserIds = new HashSet<>();
providerUserIds.add((String) authenticationToken.getPrincipal());
Set userIds = usersConnectionRepository.findUserIdsConnectedTo(authenticationToken.getProviderId(), providerUserIds);
if (CollectionUtils.isEmpty(userIds) || userIds.size() != 1) {
throw new InternalAuthenticationServiceException("无法获取用户信息");
}
String userId = userIds.iterator().next();
UserDetails user = userDetailsService.loadUserByUserId(userId);
if (user == null) {
throw new InternalAuthenticationServiceException("无法获取用户信息");
}
OpenIdAuthenticationToken authenticationResult = new OpenIdAuthenticationToken(user, user.getAuthorities());
authenticationResult.setDetails(authenticationToken.getDetails());
return authenticationResult;
}
/**
* Supports boolean.
*
* @param authentication the authentication
*
* @return the boolean
*/
@Override
public boolean supports(Class> authentication) {
return OpenIdAuthenticationToken.class.isAssignableFrom(authentication);
}
/**
* Gets user details service.
*
* @return the user details service
*/
public SocialUserDetailsService getUserDetailsService() {
return userDetailsService;
}
/**
* Sets user details service.
*
* @param userDetailsService the user details service
*/
public void setUserDetailsService(SocialUserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
/**
* Gets users connection repository.
*
* @return the users connection repository
*/
public UsersConnectionRepository getUsersConnectionRepository() {
return usersConnectionRepository;
}
/**
* Sets users connection repository.
*
* @param usersConnectionRepository the users connection repository
*/
public void setUsersConnectionRepository(UsersConnectionRepository usersConnectionRepository) {
this.usersConnectionRepository = usersConnectionRepository;
}
}
================================================
FILE: paascloud-common/paascloud-security-app/src/main/java/com/paascloud/security/app/authentication/openid/OpenIdAuthenticationSecurityConfig.java
================================================
/*
* Copyright (c) 2018. paascloud.net All Rights Reserved.
* 项目名称:paascloud快速搭建企业级分布式微服务平台
* 类名称:OpenIdAuthenticationSecurityConfig.java
* 创建人:刘兆明
* 联系方式:paascloud.net@gmail.com
* 开源地址: https://github.com/paascloud
* 博客地址: http://blog.paascloud.net
* 项目官网: http://paascloud.net
*/
package com.paascloud.security.app.authentication.openid;
import org.springframework.beans.factory.annotation.Autowired;
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.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.security.SocialUserDetailsService;
import org.springframework.stereotype.Component;
/**
* The class Open id authentication security config.
*
* @author paascloud.net@gmail.com
*/
@Component
public class OpenIdAuthenticationSecurityConfig extends SecurityConfigurerAdapter {
private final AuthenticationSuccessHandler pcAuthenticationSuccessHandler;
private final AuthenticationFailureHandler pcAuthenticationFailureHandler;
private final SocialUserDetailsService userDetailsService;
private final UsersConnectionRepository usersConnectionRepository;
@Autowired
public OpenIdAuthenticationSecurityConfig(AuthenticationSuccessHandler pcAuthenticationSuccessHandler, AuthenticationFailureHandler pcAuthenticationFailureHandler, SocialUserDetailsService userDetailsService, UsersConnectionRepository usersConnectionRepository) {
this.pcAuthenticationSuccessHandler = pcAuthenticationSuccessHandler;
this.pcAuthenticationFailureHandler = pcAuthenticationFailureHandler;
this.userDetailsService = userDetailsService;
this.usersConnectionRepository = usersConnectionRepository;
}
/**
* Configure.
*
* @param http the http
*/
@Override
public void configure(HttpSecurity http) {
OpenIdAuthenticationFilter openIdAuthenticationFilter = new OpenIdAuthenticationFilter();
openIdAuthenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
openIdAuthenticationFilter.setAuthenticationSuccessHandler(pcAuthenticationSuccessHandler);
openIdAuthenticationFilter.setAuthenticationFailureHandler(pcAuthenticationFailureHandler);
OpenIdAuthenticationProvider openIdAuthenticationProvider = new OpenIdAuthenticationProvider();
openIdAuthenticationProvider.setUserDetailsService(userDetailsService);
openIdAuthenticationProvider.setUsersConnectionRepository(usersConnectionRepository);
http.authenticationProvider(openIdAuthenticationProvider)
.addFilterAfter(openIdAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
}
================================================
FILE: paascloud-common/paascloud-security-app/src/main/java/com/paascloud/security/app/authentication/openid/OpenIdAuthenticationToken.java
================================================
/*
* Copyright (c) 2018. paascloud.net All Rights Reserved.
* 项目名称:paascloud快速搭建企业级分布式微服务平台
* 类名称:OpenIdAuthenticationToken.java
* 创建人:刘兆明
* 联系方式:paascloud.net@gmail.com
* 开源地址: https://github.com/paascloud
* 博客地址: http://blog.paascloud.net
* 项目官网: http://paascloud.net
*/
package com.paascloud.security.app.authentication.openid;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;
import java.util.Collection;
/**
* The class Open id authentication token.
*
* @author paascloud.net@gmail.com
*/
public class OpenIdAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
// ~ Instance fields
// ================================================================================================
private final Object principal;
private String providerId;
// ~ Constructors
// ===================================================================================================
/**
* This constructor can be safely used by any code that wishes to create a
* UsernamePasswordAuthenticationToken, as the {@link #isAuthenticated()}
* will return false.
*
* @param openId the open id
* @param providerId the provider id
*/
public OpenIdAuthenticationToken(String openId, String providerId) {
super(null);
this.principal = openId;
this.providerId = providerId;
setAuthenticated(false);
}
/**
* This constructor should only be used by AuthenticationManager or
* AuthenticationProvider implementations that are satisfied with
* producing a trusted (i.e. {@link #isAuthenticated()} = true)
* authentication token.
*
* @param principal the principal
* @param authorities the authorities
*/
public OpenIdAuthenticationToken(Object principal, Collection extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
// must use super, as we override
super.setAuthenticated(true);
}
// ~ Methods
// ========================================================================================================
/**
* Gets credentials.
*
* @return the credentials
*/
@Override
public Object getCredentials() {
return null;
}
/**
* Gets principal.
*
* @return the principal
*/
@Override
public Object getPrincipal() {
return this.principal;
}
/**
* Gets provider id.
*
* @return the provider id
*/
public String getProviderId() {
return providerId;
}
/**
* Sets authenticated.
*
* @param isAuthenticated the is authenticated
*
* @throws IllegalArgumentException the illegal argument exception
*/
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
if (isAuthenticated) {
throw new IllegalArgumentException(
"Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
}
super.setAuthenticated(false);
}
/**
* Erase credentials.
*/
@Override
public void eraseCredentials() {
super.eraseCredentials();
}
}
================================================
FILE: paascloud-common/paascloud-security-app/src/main/java/com/paascloud/security/app/social/AppSingUpUtils.java
================================================
/*
* Copyright (c) 2018. paascloud.net All Rights Reserved.
* 项目名称:paascloud快速搭建企业级分布式微服务平台
* 类名称:AppSingUpUtils.java
* 创建人:刘兆明
* 联系方式:paascloud.net@gmail.com
* 开源地址: https://github.com/paascloud
* 博客地址: http://blog.paascloud.net
* 项目官网: http://paascloud.net
*/
package com.paascloud.security.app.social;
import com.paascloud.security.app.AppSecretException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.social.connect.Connection;
import org.springframework.social.connect.ConnectionData;
import org.springframework.social.connect.ConnectionFactoryLocator;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.WebRequest;
import java.util.concurrent.TimeUnit;
/**
* app环境下替换providerSignInUtils,避免由于没有session导致读不到社交用户信息的问题
*
* @author paascloud.net @gmail.com
*/
@Component
public class AppSingUpUtils {
private final RedisTemplate redisTemplate;
private final UsersConnectionRepository usersConnectionRepository;
private final ConnectionFactoryLocator connectionFactoryLocator;
/**
* Instantiates a new App sing up utils.
*
* @param redisTemplate the redis template
* @param usersConnectionRepository the users connection repository
* @param connectionFactoryLocator the connection factory locator
*/
@Autowired
public AppSingUpUtils(RedisTemplate redisTemplate, UsersConnectionRepository usersConnectionRepository, ConnectionFactoryLocator connectionFactoryLocator) {
this.redisTemplate = redisTemplate;
this.usersConnectionRepository = usersConnectionRepository;
this.connectionFactoryLocator = connectionFactoryLocator;
}
/**
* 缓存社交网站用户信息到redis
*
* @param request the request
* @param connectionData the connection data
*/
public void saveConnectionData(WebRequest request, ConnectionData connectionData) {
redisTemplate.opsForValue().set(getKey(request), connectionData, 10, TimeUnit.MINUTES);
}
/**
* 将缓存的社交网站用户信息与系统注册用户信息绑定
*
* @param request the request
* @param userId the user id
*/
public void doPostSignUp(WebRequest request, String userId) {
String key = getKey(request);
if (!redisTemplate.hasKey(key)) {
throw new AppSecretException("无法找到缓存的用户社交账号信息");
}
ConnectionData connectionData = (ConnectionData) redisTemplate.opsForValue().get(key);
Connection> connection = connectionFactoryLocator.getConnectionFactory(connectionData.getProviderId())
.createConnection(connectionData);
usersConnectionRepository.createConnectionRepository(userId).addConnection(connection);
redisTemplate.delete(key);
}
/**
* 获取redis key
*/
private String getKey(WebRequest request) {
String deviceId = request.getHeader("deviceId");
if (StringUtils.isBlank(deviceId)) {
throw new AppSecretException("设备id参数不能为空");
}
return "pc:security:social.connect." + deviceId;
}
}
================================================
FILE: paascloud-common/paascloud-security-app/src/main/java/com/paascloud/security/app/social/AppSocialAuthenticationFilterPostProcessor.java
================================================
/*
* Copyright (c) 2018. paascloud.net All Rights Reserved.
* 项目名称:paascloud快速搭建企业级分布式微服务平台
* 类名称:AppSocialAuthenticationFilterPostProcessor.java
* 创建人:刘兆明
* 联系方式:paascloud.net@gmail.com
* 开源地址: https://github.com/paascloud
* 博客地址: http://blog.paascloud.net
* 项目官网: http://paascloud.net
*/
package com.paascloud.security.app.social;
import com.paascloud.security.core.social.support.SocialAuthenticationFilterPostProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.social.security.SocialAuthenticationFilter;
import org.springframework.stereotype.Component;
/**
* The type App social authentication filter post processor.
* @author paascloud
*/
@Component
public class AppSocialAuthenticationFilterPostProcessor implements SocialAuthenticationFilterPostProcessor{
private final AuthenticationSuccessHandler pcAuthenticationSuccessHandler;
@Autowired
public AppSocialAuthenticationFilterPostProcessor(AuthenticationSuccessHandler pcAuthenticationSuccessHandler) {
this.pcAuthenticationSuccessHandler = pcAuthenticationSuccessHandler;
}
@Override
public void process(final SocialAuthenticationFilter socialAuthenticationFilter) {
socialAuthenticationFilter.setAuthenticationSuccessHandler(pcAuthenticationSuccessHandler);
}
}
================================================
FILE: paascloud-common/paascloud-security-app/src/main/java/com/paascloud/security/app/social/SpringSocialConfigurerPostProcessor.java
================================================
/*
* Copyright (c) 2018. paascloud.net All Rights Reserved.
* 项目名称:paascloud快速搭建企业级分布式微服务平台
* 类名称:SpringSocialConfigurerPostProcessor.java
* 创建人:刘兆明
* 联系方式:paascloud.net@gmail.com
* 开源地址: https://github.com/paascloud
* 博客地址: http://blog.paascloud.net
* 项目官网: http://paascloud.net
*/
package com.paascloud.security.app.social;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
import com.paascloud.security.core.properties.SecurityConstants;
import com.paascloud.security.core.social.support.PcSpringSocialConfigurer;
/**
* The class Spring social configurer post processor.
*
* @author paascloud.net@gmail.com
*/
@Component
public class SpringSocialConfigurerPostProcessor implements BeanPostProcessor {
/**
* Post process before initialization object.
*
* @param bean the bean
* @param beanName the bean name
*
* @return the object
*
* @throws BeansException the beans exception
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
/**
* Post process after initialization object.
*
* @param bean the bean
* @param beanName the bean name
*
* @return the object
*
* @throws BeansException the beans exception
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
String pcSocialSecurityConfig = "pcSocialSecurityConfig";
if (StringUtils.equals(beanName, pcSocialSecurityConfig)) {
PcSpringSocialConfigurer config = (PcSpringSocialConfigurer) bean;
config.signupUrl(SecurityConstants.DEFAULT_SOCIAL_USER_INFO_URL);
return config;
}
return bean;
}
}
================================================
FILE: paascloud-common/paascloud-security-app/src/main/java/com/paascloud/security/server/PcAccessDeniedHandler.java
================================================
/*
* Copyright (c) 2018. paascloud.net All Rights Reserved.
* 项目名称:paascloud快速搭建企业级分布式微服务平台
* 类名称:PcAccessDeniedHandler.java
* 创建人:刘兆明
* 联系方式:paascloud.net@gmail.com
* 开源地址: https://github.com/paascloud
* 博客地址: http://blog.paascloud.net
* 项目官网: http://paascloud.net
*/
package com.paascloud.security.server;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* The class Pc access denied handler.
*
* @author paascloud.net @gmail.com
*/
@Slf4j
@Configuration
public class PcAccessDeniedHandler implements AccessDeniedHandler {
@Resource
private ObjectMapper objectMapper;
/**
* Handle.
*
* @param request the request
* @param response the response
* @param e the e
*
* @throws JsonProcessingException the json processing exception
*/
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException {
log.info("处理权限异常. e={}", e);
Map result = new HashMap<>(3);
result.put("code", 99990401);
result.put("message", "无访问权限");
String json = objectMapper.writeValueAsString(result);
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(json);
}
}
================================================
FILE: paascloud-common/paascloud-security-app/src/main/java/com/paascloud/security/server/PcResourceServerConfig.java
================================================
/*
* Copyright (c) 2018. paascloud.net All Rights Reserved.
* 项目名称:paascloud快速搭建企业级分布式微服务平台
* 类名称:PcResourceServerConfig.java
* 创建人:刘兆明
* 联系方式:paascloud.net@gmail.com
* 开源地址: https://github.com/paascloud
* 博客地址: http://blog.paascloud.net
* 项目官网: http://paascloud.net
*/
package com.paascloud.security.server;
import com.paascloud.security.app.authentication.openid.OpenIdAuthenticationSecurityConfig;
import com.paascloud.security.core.authentication.FormAuthenticationConfig;
import com.paascloud.security.core.authentication.mobile.SmsCodeAuthenticationSecurityConfig;
import com.paascloud.security.core.authorize.AuthorizeConfigManager;
import com.paascloud.security.core.validate.code.ValidateCodeSecurityConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
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.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.social.security.SpringSocialConfigurer;
import javax.annotation.Resource;
import javax.sql.DataSource;
/**
* 资源服务器配置
*
* @author paascloud.net @gmail.com
*/
@Configuration
@EnableResourceServer
public class PcResourceServerConfig extends ResourceServerConfigurerAdapter {
@Autowired
private OAuth2WebSecurityExpressionHandler pcSecurityExpressionHandler;
@Autowired
private AccessDeniedHandler pcAccessDeniedHandler;
@Autowired
protected AuthenticationSuccessHandler pcAuthenticationSuccessHandler;
@Autowired
protected AuthenticationFailureHandler pcAuthenticationFailureHandler;
@Autowired
private SmsCodeAuthenticationSecurityConfig smsCodeAuthenticationSecurityConfig;
@Autowired
private ValidateCodeSecurityConfig validateCodeSecurityConfig;
@Autowired
private SpringSocialConfigurer pcSocialSecurityConfig;
@Autowired
private AuthorizeConfigManager authorizeConfigManager;
@Autowired
private FormAuthenticationConfig formAuthenticationConfig;
@Autowired
private OpenIdAuthenticationSecurityConfig openIdAuthenticationSecurityConfig;
@Resource
private DataSource dataSource;
/**
* 记住我功能的token存取器配置
*
* @return the persistent token repository
*/
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
tokenRepository.setDataSource(dataSource);
// tokenRepository.setCreateTableOnStartup(true); // 第一次启动创建
return tokenRepository;
}
/**
* Configure.
*
* @param http the http
*
* @throws Exception the exception
*/
@Override
public void configure(HttpSecurity http) throws Exception {
formAuthenticationConfig.configure(http);
http.headers().frameOptions().disable();
http.apply(validateCodeSecurityConfig)
.and()
.apply(smsCodeAuthenticationSecurityConfig)
.and()
.apply(pcSocialSecurityConfig)
.and()
.apply(openIdAuthenticationSecurityConfig)
.and()
.headers().frameOptions().disable()
.and()
.exceptionHandling().accessDeniedHandler(pcAccessDeniedHandler)
.and()
.csrf().disable();
authorizeConfigManager.config(http.authorizeRequests());
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.expressionHandler(pcSecurityExpressionHandler);
}
}
================================================
FILE: paascloud-common/paascloud-security-app/src/main/java/com/paascloud/security/server/PcWebResponseExceptionTranslator.java
================================================
/*
* Copyright (c) 2018. paascloud.net All Rights Reserved.
* 项目名称:paascloud快速搭建企业级分布式微服务平台
* 类名称:PcWebResponseExceptionTranslator.java
* 创建人:刘兆明
* 联系方式:paascloud.net@gmail.com
* 开源地址: https://github.com/paascloud
* 博客地址: http://blog.paascloud.net
* 项目官网: http://paascloud.net
*/
package com.paascloud.security.server;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
/**
* The class Pc web response exception translator.
*
* @author paascloud.net @gmail.com
*/
public class PcWebResponseExceptionTranslator implements WebResponseExceptionTranslator {
/**
* Translate response entity.
*
* @param e the e
*
* @return the response entity
*
* @throws Exception the exception
*/
@Override
public ResponseEntity translate(Exception e) throws Exception {
return null;
}
}
================================================
FILE: paascloud-common/paascloud-security-app/src/main/java/com/paascloud/security/server/TokenJwtEnhancer.java
================================================
/*
* Copyright (c) 2018. paascloud.net All Rights Reserved.
* 项目名称:paascloud快速搭建企业级分布式微服务平台
* 类名称:TokenJwtEnhancer.java
* 创建人:刘兆明
* 联系方式:paascloud.net@gmail.com
* 开源地址: https://github.com/paascloud
* 博客地址: http://blog.paascloud.net
* 项目官网: http://paascloud.net
*/
package com.paascloud.security.server;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import java.util.HashMap;
import java.util.Map;
/**
* The class Token jwt enhancer.
*
* @author paascloud.net @gmail.com
*/
public class TokenJwtEnhancer implements TokenEnhancer {
/**
* Enhance o auth 2 access token.
*
* @param accessToken the access token
* @param oAuth2Authentication the o auth 2 authentication
*
* @return the o auth 2 access token
*/
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication oAuth2Authentication) {
Map info = new HashMap<>(8);
info.put("timestamp", System.currentTimeMillis());
Authentication authentication = oAuth2Authentication.getUserAuthentication();
if (authentication != null && authentication.getPrincipal() instanceof UserDetails) {
Object principal = authentication.getPrincipal();
info.put("loginName", ((UserDetails) principal).getUsername());
}
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);
return accessToken;
}
}
================================================
FILE: paascloud-common/paascloud-security-app/src/main/java/com/paascloud/security/server/TokenStoreConfig.java
================================================
/*
* Copyright (c) 2018. paascloud.net All Rights Reserved.
* 项目名称:paascloud快速搭建企业级分布式微服务平台
* 类名称:TokenStoreConfig.java
* 创建人:刘兆明
* 联系方式:paascloud.net@gmail.com
* 开源地址: https://github.com/paascloud
* 博客地址: http://blog.paascloud.net
* 项目官网: http://paascloud.net
*/
package com.paascloud.security.server;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import com.paascloud.security.core.properties.SecurityProperties;
/**
* The class Token store config.
*
* @author paascloud.net @gmail.com
*/
@Configuration
public class TokenStoreConfig {
/**
* 使用redis存储token的配置,只有在paascloud.security.oauth2.tokenStore配置为redis时生效
*/
@Configuration
@ConditionalOnProperty(prefix = "paascloud.security.oauth2", name = "tokenStore", havingValue = "redis")
public static class RedisConfig {
@Autowired
private RedisConnectionFactory redisConnectionFactory;
/**
* Redis token store token store.
*
* @return token store
*/
@Bean
public TokenStore redisTokenStore() {
return new RedisTokenStore(redisConnectionFactory);
}
}
/**
* 使用jwt时的配置,默认生效
*
* @author paascloud.net @gmail.com
*/
@Configuration
@ConditionalOnProperty(prefix = "paascloud.security.oauth2", name = "tokenStore", havingValue = "jwt", matchIfMissing = true)
public static class JwtConfig {
@Autowired
private SecurityProperties securityProperties;
/**
* Jwt token store token store.
*
* @return the token store
*/
@Bean
public TokenStore jwtTokenStore() {
return new JwtTokenStore(jwtAccessTokenConverter());
}
/**
* Jwt access token converter jwt access token converter.
*
* @return the jwt access token converter
*/
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(securityProperties.getOauth2().getJwtSigningKey());
return converter;
}
/**
* Jwt token enhancer token enhancer.
*
* @return the token enhancer
*/
@Bean
@ConditionalOnBean(TokenEnhancer.class)
public TokenEnhancer jwtTokenEnhancer() {
return new TokenJwtEnhancer();
}
}
}
================================================
FILE: paascloud-common/paascloud-security-core/pom.xml
================================================
4.0.0
paascloud-security-core
com.liuzm.paascloud.common
paascloud-common
1.0
org.springframework.cloud
spring-cloud-starter-oauth2
org.springframework.boot
spring-boot-starter-data-redis
org.springframework.boot
spring-boot-starter-jdbc
mysql
mysql-connector-java
org.springframework.social
spring-social-config
org.springframework.social
spring-social-core
org.springframework.social
spring-social-security
org.springframework.social
spring-social-web
commons-lang
commons-lang
commons-collections
commons-collections
commons-beanutils
commons-beanutils
org.springframework.boot
spring-boot-configuration-processor
com.github.penggle
kaptcha
com.fasterxml.jackson.core
jackson-annotations
com.fasterxml.jackson.core
jackson-databind
com.fasterxml.jackson.core
jackson-core
com.fasterxml.jackson.datatype
jackson-datatype-jsr310
com.liuzm.paascloud.common
paascloud-common-util
================================================
FILE: paascloud-common/paascloud-security-core/src/main/java/com/paascloud/security/core/SecurityCoreConfig.java
================================================
/*
* Copyright (c) 2018. paascloud.net All Rights Reserved.
* 项目名称:paascloud快速搭建企业级分布式微服务平台
* 类名称:SecurityCoreConfig.java
* 创建人:刘兆明
* 联系方式:paascloud.net@gmail.com
* 开源地址: https://github.com/paascloud
* 博客地址: http://blog.paascloud.net
* 项目官网: http://paascloud.net
*/
package com.paascloud.security.core;
import com.paascloud.security.core.properties.SecurityProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* The class Security core config.
*
* @author paascloud.net@gmail.com
*/
@Configuration
@EnableConfigurationProperties(SecurityProperties.class)
public class SecurityCoreConfig {
}
================================================
FILE: paascloud-common/paascloud-security-core/src/main/java/com/paascloud/security/core/SecurityResult.java
================================================
/*
* Copyright (c) 2018. paascloud.net All Rights Reserved.
* 项目名称:paascloud快速搭建企业级分布式微服务平台
* 类名称:SecurityResult.java
* 创建人:刘兆明
* 联系方式:paascloud.net@gmail.com
* 开源地址: https://github.com/paascloud
* 博客地址: http://blog.paascloud.net
* 项目官网: http://paascloud.net
*/
package com.paascloud.security.core;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
/**
* The class Security result.
*
* @author paascloud.net @gmail.com
*/
@Data
@NoArgsConstructor
public class SecurityResult {
/**
* 成功码.
*/
public static final int SUCCESS_CODE = 200;
/**
* 成功信息.
*/
public static final String SUCCESS_MESSAGE = "操作成功";
/**
* 错误码.
*/
public static final int ERROR_CODE = 500;
/**
* 错误信息.
*/
public static final String ERROR_MESSAGE = "内部异常";
/**
* 状态码
*/
private Integer code;
/**
* 提示信息
*/
private String message;
/**
* 结果
*/
private Object result;
public static SecurityResult ok(Object data) {
return new SecurityResult(data);
}
public static SecurityResult ok() {
return new SecurityResult(null);
}
public static SecurityResult error(String message) {
return error(message, null);
}
public static SecurityResult error(String message, Object data) {
return new SecurityResult(ERROR_CODE, StringUtils.isEmpty(message) ? ERROR_MESSAGE : message, data);
}
public SecurityResult(Integer code, String message, Object result) {
this.code = code;
this.message = message;
this.result = result;
}
private SecurityResult(Object result) {
this.code = SUCCESS_CODE;
this.message = SUCCESS_MESSAGE;
this.result = result;
}
}
================================================
FILE: paascloud-common/paascloud-security-core/src/main/java/com/paascloud/security/core/SecurityUser.java
================================================
/*
* Copyright (c) 2018. paascloud.net All Rights Reserved.
* 项目名称:paascloud快速搭建企业级分布式微服务平台
* 类名称:SecurityUser.java
* 创建人:刘兆明
* 联系方式:paascloud.net@gmail.com
* 开源地址: https://github.com/paascloud
* 博客地址: http://blog.paascloud.net
* 项目官网: http://paascloud.net
*/
package com.paascloud.security.core;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
/**
* The class Security user.
*
* @author paascloud.net @gmail.com
*/
public class SecurityUser implements UserDetails {
private static final long serialVersionUID = 4872628781561412463L;
private static final String ENABLE = "ENABLE";
private Collection authorities;
private Long userId;
private String nickName;
private String loginName;
private String loginPwd;
private String status;
private Long groupId;
private String groupName;
public SecurityUser(Long userId, String loginName, String loginPwd, String nickName, Long groupId, String groupName) {
this.setUserId(userId);
this.setLoginName(loginName);
this.setLoginPwd(loginPwd);
this.setNickName(nickName);
this.setGroupId(groupId);
this.setGroupName(groupName);
}
public SecurityUser(Long userId, String loginName, String loginPwd, String nickName, Long groupId, String groupName, String status, Collection grantedAuthorities) {
this.setUserId(userId);
this.setLoginName(loginName);
this.setLoginPwd(loginPwd);
this.setNickName(nickName);
this.setGroupId(groupId);
this.setGroupName(groupName);
this.setStatus(status);
this.authorities = grantedAuthorities;
}
@Override
public Collection extends GrantedAuthority> getAuthorities() {
return this.authorities;
}
@Override
public String getPassword() {
return this.getLoginPwd();
}
@Override
public String getUsername() {
return this.getLoginName();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return StringUtils.equals(this.status, ENABLE);
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getLoginPwd() {
return loginPwd;
}
public void setLoginPwd(String loginPwd) {
this.loginPwd = loginPwd;
}
public Long getGroupId() {
return groupId;
}
public void setGroupId(Long groupId) {
this.groupId = groupId;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
}
================================================
FILE: paascloud-common/paascloud-security-core/src/main/java/com/paascloud/security/core/authentication/AuthenticationBeanConfig.java
================================================
package com.paascloud.security.core.authentication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.social.security.SocialUserDetailsService;
/**
* 认证相关的扩展点配置。配置在这里的bean,业务系统都可以通过声明同类型或同名的bean来覆盖安全
* 模块默认的配置。
*
* @author paascloud.net @gmail.com
*/
@Configuration
public class AuthenticationBeanConfig {
/**
* 默认密码处理器
*
* @return 密码加密器
*/
@Bean
@ConditionalOnMissingBean(PasswordEncoder.class)
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* 默认认证器
*
* @return user details service
*/
@Bean
@ConditionalOnMissingBean(UserDetailsService.class)
public UserDetailsService userDetailsService() {
return new DefaultUserDetailsServiceImpl();
}
/**
* 默认认证器
*
* @return social user details service
*/
@Bean
@ConditionalOnMissingBean(SocialUserDetailsService.class)
public SocialUserDetailsService socialUserDetailsService() {
return new DefaultSocialUserDetailsServiceImpl();
}
}
================================================
FILE: paascloud-common/paascloud-security-core/src/main/java/com/paascloud/security/core/authentication/DefaultSocialUserDetailsServiceImpl.java
================================================
package com.paascloud.security.core.authentication;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.social.security.SocialUserDetails;
import org.springframework.social.security.SocialUserDetailsService;
/**
* 默认的SocialUserDetailsService实现
* 不做任何处理,只在控制台打印一句日志,然后抛出异常,提醒业务系统自己配置SocialUserDetailsService。
*
* @author paascloud.net @gmail.com
*/
@Slf4j
public class DefaultSocialUserDetailsServiceImpl implements SocialUserDetailsService {
/**
* Load user by user id social user details.
*
* @param userId the user id
*
* @return the social user details
*
* @throws UsernameNotFoundException the username not found exception
*/
@Override
public SocialUserDetails loadUserByUserId(String userId) throws UsernameNotFoundException {
log.warn("请配置 SocialUserDetailsService 接口的实现.");
throw new UsernameNotFoundException(userId);
}
}
================================================
FILE: paascloud-common/paascloud-security-core/src/main/java/com/paascloud/security/core/authentication/DefaultUserDetailsServiceImpl.java
================================================
package com.paascloud.security.core.authentication;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
/**
* 默认的 UserDetailsService 实现
* 不做任何处理,只在控制台打印一句日志,然后抛出异常,提醒业务系统自己配置 UserDetailsService。
*
* @author paascloud.net @gmail.com
*/
@Slf4j
public class DefaultUserDetailsServiceImpl implements UserDetailsService {
/**
* Load user by username user details.
*
* @param username the username
*
* @return the user details
*
* @throws UsernameNotFoundException the username not found exception
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
log.warn("请配置 UserDetailsService 接口的实现.");
throw new UsernameNotFoundException(username);
}
}
================================================
FILE: paascloud-common/paascloud-security-core/src/main/java/com/paascloud/security/core/authentication/FormAuthenticationConfig.java
================================================
package com.paascloud.security.core.authentication;
import com.paascloud.security.core.properties.SecurityConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
/**
* 表单登录配置
*
* @author paascloud.net @gmail.com
*/
@Component
public class FormAuthenticationConfig {
/**
* The Pc authentication success handler.
*/
protected final AuthenticationSuccessHandler pcAuthenticationSuccessHandler;
/**
* The Pc authentication failure handler.
*/
protected final AuthenticationFailureHandler pcAuthenticationFailureHandler;
/**
* Instantiates a new Form authentication config.
*
* @param pcAuthenticationSuccessHandler the pc authentication success handler
* @param pcAuthenticationFailureHandler the pc authentication failure handler
*/
@Autowired
public FormAuthenticationConfig(AuthenticationSuccessHandler pcAuthenticationSuccessHandler, AuthenticationFailureHandler pcAuthenticationFailureHandler) {
this.pcAuthenticationSuccessHandler = pcAuthenticationSuccessHandler;
this.pcAuthenticationFailureHandler = pcAuthenticationFailureHandler;
}
/**
* Configure.
*
* @param http the http
*
* @throws Exception the exception
*/
public void configure(HttpSecurity http) throws Exception {
http.formLogin()
.loginPage(SecurityConstants.DEFAULT_UNAUTHENTICATION_URL)
.loginProcessingUrl(SecurityConstants.DEFAULT_SIGN_IN_PROCESSING_URL_FORM)
.successHandler(pcAuthenticationSuccessHandler)
.failureHandler(pcAuthenticationFailureHandler);
}
}
================================================
FILE: paascloud-common/paascloud-security-core/src/main/java/com/paascloud/security/core/authentication/mobile/SmsCodeAuthenticationFilter.java
================================================
package com.paascloud.security.core.authentication.mobile;
import com.paascloud.security.core.properties.SecurityConstants;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.Assert;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 短信登录过滤器
*
* @author paascloud.net @gmail.com
*/
public class SmsCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
private static final String POST = "POST";
// ~ Static fields/initializers
// =====================================================================================
private String mobileParameter = SecurityConstants.DEFAULT_PARAMETER_NAME_MOBILE;
private boolean postOnly = true;
// ~ Constructors
// ===================================================================================================
/**
* Instantiates a new Sms code authentication filter.
*/
public SmsCodeAuthenticationFilter() {
super(new AntPathRequestMatcher(SecurityConstants.DEFAULT_SIGN_IN_PROCESSING_URL_MOBILE, "POST"));
}
// ~ Methods
// ========================================================================================================
/**
* Attempt authentication authentication.
*
* @param request the request
* @param response the response
*
* @return the authentication
*
* @throws AuthenticationException the authentication exception
*/
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
if (postOnly && !POST.equals(request.getMethod())) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
String mobile = obtainMobile(request);
if (mobile == null) {
mobile = "";
}
mobile = mobile.trim();
SmsCodeAuthenticationToken authRequest = new SmsCodeAuthenticationToken(mobile);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
/**
* 获取手机号
*
* @param request the request
*
* @return the string
*/
protected String obtainMobile(HttpServletRequest request) {
return request.getParameter(mobileParameter);
}
/**
* Provided so that subclasses may configure what is put into the
* authentication request's details property.
*
* @param request that an authentication request is being created for
* @param authRequest the authentication request object that should have its details set
*/
protected void setDetails(HttpServletRequest request, SmsCodeAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}
/**
* Sets the parameter name which will be used to obtain the username from
* the login request.
*
* @param usernameParameter the parameter name. Defaults to "username".
*/
public void setMobileParameter(String usernameParameter) {
Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
this.mobileParameter = usernameParameter;
}
/**
* Defines whether only HTTP POST requests will be allowed by this filter.
* If set to true, and an authentication request is received which is not a
* POST request, an exception will be raised immediately and authentication
* will not be attempted. The unsuccessfulAuthentication() method
* will be called as if handling a failed authentication.
*
* Defaults to true but may be overridden by subclasses.
*
* @param postOnly the post only
*/
public void setPostOnly(boolean postOnly) {
this.postOnly = postOnly;
}
/**
* Gets mobile parameter.
*
* @return the mobile parameter
*/
public final String getMobileParameter() {
return mobileParameter;
}
}
================================================
FILE: paascloud-common/paascloud-security-core/src/main/java/com/paascloud/security/core/authentication/mobile/SmsCodeAuthenticationProvider.java
================================================
package com.paascloud.security.core.authentication.mobile;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
/**
* 短信登录验证逻辑
*
* 由于短信验证码的验证在过滤器里已完成,这里直接读取用户信息即可。
*
* @author paascloud.net @gmail.com
*/
public class SmsCodeAuthenticationProvider implements AuthenticationProvider {
private UserDetailsService userDetailsService;
/**
* Authenticate authentication.
*
* @param authentication the authentication
*
* @return the authentication
*
* @throws AuthenticationException the authentication exception
*/
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
SmsCodeAuthenticationToken authenticationToken = (SmsCodeAuthenticationToken) authentication;
UserDetails user = userDetailsService.loadUserByUsername((String) authenticationToken.getPrincipal());
if (user == null) {
throw new InternalAuthenticationServiceException("无法获取用户信息");
}
SmsCodeAuthenticationToken authenticationResult = new SmsCodeAuthenticationToken(user, user.getAuthorities());
authenticationResult.setDetails(authenticationToken.getDetails());
return authenticationResult;
}
/**
* Supports boolean.
*
* @param authentication the authentication
*
* @return the boolean
*/
@Override
public boolean supports(Class> authentication) {
return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication);
}
/**
* Gets user details service.
*
* @return the user details service
*/
public UserDetailsService getUserDetailsService() {
return userDetailsService;
}
/**
* Sets user details service.
*
* @param userDetailsService the user details service
*/
public void setUserDetailsService(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
}
================================================
FILE: paascloud-common/paascloud-security-core/src/main/java/com/paascloud/security/core/authentication/mobile/SmsCodeAuthenticationSecurityConfig.java
================================================
package com.paascloud.security.core.authentication.mobile;
import org.springframework.beans.factory.annotation.Autowired;
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.core.userdetails.UserDetailsService;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.stereotype.Component;
import java.util.UUID;
/**
* 短信登录配置
*
* @author paascloud.net @gmail.com
*/
@Component
public class SmsCodeAuthenticationSecurityConfig extends SecurityConfigurerAdapter {
@Autowired
private AuthenticationSuccessHandler pcAuthenticationSuccessHandler;
@Autowired
private AuthenticationFailureHandler pcAuthenticationFailureHandler;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private PersistentTokenRepository persistentTokenRepository;
/**
* Configure.
*
* @param http the http
*/
@Override
public void configure(HttpSecurity http) {
SmsCodeAuthenticationFilter smsCodeAuthenticationFilter = new SmsCodeAuthenticationFilter();
smsCodeAuthenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
smsCodeAuthenticationFilter.setAuthenticationSuccessHandler(pcAuthenticationSuccessHandler);
smsCodeAuthenticationFilter.setAuthenticationFailureHandler(pcAuthenticationFailureHandler);
String key = UUID.randomUUID().toString();
smsCodeAuthenticationFilter.setRememberMeServices(new PersistentTokenBasedRememberMeServices(key, userDetailsService, persistentTokenRepository));
SmsCodeAuthenticationProvider smsCodeAuthenticationProvider = new SmsCodeAuthenticationProvider();
smsCodeAuthenticationProvider.setUserDetailsService(userDetailsService);
http.authenticationProvider(smsCodeAuthenticationProvider)
.addFilterAfter(smsCodeAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
//
}
}
================================================
FILE: paascloud-common/paascloud-security-core/src/main/java/com/paascloud/security/core/authentication/mobile/SmsCodeAuthenticationToken.java
================================================
package com.paascloud.security.core.authentication.mobile;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;
import java.util.Collection;
/**
* 短信登录验证信息封装类
*
* @author paascloud.net @gmail.com
*/
public class SmsCodeAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
private final Object principal;
SmsCodeAuthenticationToken(String mobile) {
super(null);
this.principal = mobile;
setAuthenticated(false);
}
SmsCodeAuthenticationToken(Object principal, Collection extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
super.setAuthenticated(true);
}
@Override
public Object getCredentials() {
return null;
}
@Override
public Object getPrincipal() {
return this.principal;
}
@Override
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);
}
}
================================================
FILE: paascloud-common/paascloud-security-core/src/main/java/com/paascloud/security/core/authorize/AuthorizeConfigManager.java
================================================
package com.paascloud.security.core.authorize;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
/**
* 授权信息管理器
* 用于收集系统中所有 AuthorizeConfigProvider 并加载其配置
*
* @author paascloud.net @gmail.com
*/
public interface AuthorizeConfigManager {
/**
* Config.
*
* @param config the config
*/
void config(ExpressionUrlAuthorizationConfigurer