diff --git a/pom.xml b/pom.xml
index 5885e3a..3490cc0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -195,6 +195,21 @@
simplecaptcha
1.2.2
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+ com.qms.utils
+ QmsUtils
+ 1.1.6.RELEASE
+
+
+ org.projectlombok
+ lombok
+ 1.16.14
+
diff --git a/src/main/java/com/blueskykong/auth/AuthApplication.java b/src/main/java/com/blueskykong/auth/AuthApplication.java
index f518d61..6c04b5f 100644
--- a/src/main/java/com/blueskykong/auth/AuthApplication.java
+++ b/src/main/java/com/blueskykong/auth/AuthApplication.java
@@ -1,11 +1,12 @@
package com.blueskykong.auth;
-
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
+import org.springframework.core.annotation.Order;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
*
@@ -14,9 +15,10 @@
*/
@SpringBootApplication
-//@EnableFeignClients
+@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
+@EnableFeignClients
//@EnableDiscoveryClient
-public class AuthApplication {
+public class AuthApplication extends WebSecurityConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(AuthApplication.class, args);
diff --git a/src/main/java/com/blueskykong/auth/client/fallback/UserFallbackClient.java b/src/main/java/com/blueskykong/auth/client/fallback/UserFallbackClient.java
deleted file mode 100644
index 81fabe9..0000000
--- a/src/main/java/com/blueskykong/auth/client/fallback/UserFallbackClient.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.blueskykong.auth.client.fallback;
-
-import com.blueskykong.auth.client.feign.UserClient;
-import com.blueskykong.auth.exception.ErrorCodes;
-import com.blueskykong.auth.exception.RemoteException;
-import org.springframework.stereotype.Component;
-
-import java.util.Map;
-
-/**
- * @author keets
- * @date 2017/9/25
- */
-@Component
-public class UserFallbackClient implements UserClient {
-
- @Override
- public Map checkUsernameAndPassword(Map userMap) {
- throw new RemoteException(ErrorCodes.USER_SERVICE_CALL_FAILURE);
- }
-
- @Override
- public Map getUserInformation(Map userCheck) {
- throw new RemoteException(ErrorCodes.USER_SERVICE_CALL_FAILURE);
- }
-
-}
diff --git a/src/main/java/com/blueskykong/auth/client/feign/UserClient.java b/src/main/java/com/blueskykong/auth/client/feign/UserClient.java
index da5dbe9..ff50707 100644
--- a/src/main/java/com/blueskykong/auth/client/feign/UserClient.java
+++ b/src/main/java/com/blueskykong/auth/client/feign/UserClient.java
@@ -1,24 +1,27 @@
package com.blueskykong.auth.client.feign;
-import com.blueskykong.auth.client.fallback.UserFallbackClient;
+import com.blueskykong.auth.dto.UserInfoDTO;
+import com.qms.utils.entity.GeneralVO;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
-
-import java.util.Map;
+import org.springframework.web.bind.annotation.RequestParam;
/**
* @author keets
* @date 2017/9/25
*/
-@FeignClient(name = "user", fallback = UserFallbackClient.class)
-public interface UserClient {
- @RequestMapping(method = RequestMethod.POST, value = "/api/users/exists", consumes = {"application/json"}, produces = {"application/json"})
- Map checkUsernameAndPassword(Map userMap);
-
- @RequestMapping(method = RequestMethod.POST, value = "/api/users/phoneExists", consumes = {"application/json"}, produces = {"application/json"})
- Map getUserInformation(Map userCheck);
+//@FeignClient(value = "user", url="https://test.meia8.com/qmsuser/user")
+@FeignClient(value = "user", url="http://localhost:8080/qmsuser/user")
+public interface UserClient {
+ /**
+ * 根据c端用户名查询用户详情
+ * @param userName
+ * @return
+ */
+ @RequestMapping(value="/queryInfoByName", method = { RequestMethod.POST})
+ GeneralVO queryUseInfoByUserName(@RequestParam("userName") String userName);
}
diff --git a/src/main/java/com/blueskykong/auth/config/oauth/OAuth2Config.java b/src/main/java/com/blueskykong/auth/config/oauth/Oauth2Config.java
similarity index 52%
rename from src/main/java/com/blueskykong/auth/config/oauth/OAuth2Config.java
rename to src/main/java/com/blueskykong/auth/config/oauth/Oauth2Config.java
index 96b0698..c2ddc48 100644
--- a/src/main/java/com/blueskykong/auth/config/oauth/OAuth2Config.java
+++ b/src/main/java/com/blueskykong/auth/config/oauth/Oauth2Config.java
@@ -1,49 +1,46 @@
package com.blueskykong.auth.config.oauth;
import com.blueskykong.auth.security.CustomAuthorizationTokenServices;
-import com.blueskykong.auth.security.CustomTokenEnhancer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
-import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
-import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
-import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
-
-import javax.sql.DataSource;
+import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
/**
- * Created by keets on 2017/9/25.
+ * 配置Oauth2.0
+ * 1. 配置token存储为redis
+ * 2. 配置用户username,password的数据库验证数据源
+ * 3. 配置内存clientId,secret用于验证请求的client是否合法
+ * @author figo
*/
-
@Configuration
@EnableAuthorizationServer
-public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
+public class Oauth2Config extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
- private DataSource dataSource;
+ private WebResponseExceptionTranslator webResponseExceptionTranslator;
@Autowired
- private WebResponseExceptionTranslator webResponseExceptionTranslator;
+ private RedisConnectionFactory redisConnectionFactory;
- @Bean
- public JdbcClientDetailsService clientDetailsService(DataSource dataSource) {
- return new JdbcClientDetailsService(dataSource);
- }
+ @Autowired
+ private RedisTokenStore redisTokenStore;
@Bean
- public JdbcTokenStore tokenStore(DataSource dataSource) {
- return new JdbcTokenStore(dataSource);
+ public RedisTokenStore tokenStore(RedisConnectionFactory redisConnectionFactory) {
+ return new RedisTokenStore(redisConnectionFactory);
}
@Override
@@ -53,33 +50,53 @@ public void configure(AuthorizationServerSecurityConfigurer security) throws Exc
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
- clients.withClientDetails(clientDetailsService(dataSource));
+ //配置客户端,用于password认证
+ clients.inMemory()
+ .withClient("frontend")
+ .authorizedGrantTypes("password", "refresh_token")
+ .scopes("select")
+ .authorities("client")
+ .secret("frontend")
+ .and()
+ .withClient("waiter")
+ .authorizedGrantTypes("password", "refresh_token")
+ .scopes("select")
+ .authorities("client")
+ .secret("waiter")
+ .and()
+ .withClient("shop")
+ .authorizedGrantTypes("password", "refresh_token")
+ .scopes("select")
+ .authorities("client")
+ .secret("shop")
+ .and()
+ .withClient("customer")
+ .authorizedGrantTypes("password", "refresh_token")
+ .scopes("select")
+ .authorities("client")
+ .secret("customer")
+ .and()
+ .withClient("platform")
+ .authorizedGrantTypes("password", "refresh_token")
+ .scopes("select")
+ .authorities("client")
+ .secret("platform");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager)
- .tokenStore(tokenStore(dataSource))
+ .tokenStore(redisTokenStore)
.tokenServices(authorizationServerTokenServices())
- .accessTokenConverter(accessTokenConverter())
.exceptionTranslator(webResponseExceptionTranslator);
}
- @Bean
- public JwtAccessTokenConverter accessTokenConverter() {
- JwtAccessTokenConverter converter = new CustomTokenEnhancer();
- converter.setSigningKey("secret");
- return converter;
- }
-
@Bean
public AuthorizationServerTokenServices authorizationServerTokenServices() {
CustomAuthorizationTokenServices customTokenServices = new CustomAuthorizationTokenServices();
- customTokenServices.setTokenStore(tokenStore(dataSource));
+ customTokenServices.setTokenStore(redisTokenStore);
+ customTokenServices.setAccessTokenValiditySeconds(-1);
customTokenServices.setSupportRefreshToken(true);
- customTokenServices.setReuseRefreshToken(true);
- customTokenServices.setClientDetailsService(clientDetailsService(dataSource));
- customTokenServices.setTokenEnhancer(accessTokenConverter());
return customTokenServices;
}
}
diff --git a/src/main/java/com/blueskykong/auth/config/oauth/ResourceServerConfig.java b/src/main/java/com/blueskykong/auth/config/oauth/ResourceServerConfig.java
index a8142f1..1af9514 100644
--- a/src/main/java/com/blueskykong/auth/config/oauth/ResourceServerConfig.java
+++ b/src/main/java/com/blueskykong/auth/config/oauth/ResourceServerConfig.java
@@ -1,7 +1,6 @@
package com.blueskykong.auth.config.oauth;
import com.blueskykong.auth.security.filter.CustomLogoutHandler;
-import com.blueskykong.auth.security.filter.CustomSecurityFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@@ -9,7 +8,6 @@
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.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;
/**
* @author keets
@@ -24,15 +22,13 @@ public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
- .requestMatchers().antMatchers("/**")
- .and().authorizeRequests()
- .antMatchers("/**").permitAll()
- .anyRequest().authenticated()
- .and().logout()
+ .antMatcher("/me")
+ .authorizeRequests().anyRequest().authenticated();
+ /*.and().logout()
.logoutUrl("/logout")
.clearAuthentication(true)
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
- .addLogoutHandler(customLogoutHandler());
+ .addLogoutHandler(customLogoutHandler());*/
//http.antMatcher("/api/**").addFilterAt(customSecurityFilter(), FilterSecurityInterceptor.class);
diff --git a/src/main/java/com/blueskykong/auth/dao/UserDao.java b/src/main/java/com/blueskykong/auth/dao/UserDao.java
new file mode 100644
index 0000000..4efa563
--- /dev/null
+++ b/src/main/java/com/blueskykong/auth/dao/UserDao.java
@@ -0,0 +1,35 @@
+package com.blueskykong.auth.dao;
+
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.Map;
+
+/**
+ * @author figo
+ */
+@Mapper
+public interface UserDao {
+
+ /**
+ * 获取店铺账户信息
+ * @param map
+ * @return
+ */
+ Map getShopAccount(Map map);
+
+
+ /**
+ * 获取服务员信息
+ * @param map
+ * @return
+ */
+ Map getWaiter(Map map);
+
+ /**
+ * 获取平台用户
+ * @param map
+ * @return
+ */
+ Map getPlatformUser(Map map);
+
+}
diff --git a/src/main/java/com/blueskykong/auth/dao/impl/MybatisClientSecretDAO.java b/src/main/java/com/blueskykong/auth/dao/impl/MybatisClientSecretDAOImpl.java
similarity index 97%
rename from src/main/java/com/blueskykong/auth/dao/impl/MybatisClientSecretDAO.java
rename to src/main/java/com/blueskykong/auth/dao/impl/MybatisClientSecretDAOImpl.java
index 432f64f..e030057 100644
--- a/src/main/java/com/blueskykong/auth/dao/impl/MybatisClientSecretDAO.java
+++ b/src/main/java/com/blueskykong/auth/dao/impl/MybatisClientSecretDAOImpl.java
@@ -13,7 +13,7 @@
import java.util.UUID;
@Repository
-public class MybatisClientSecretDAO implements ClientSecretDAO {
+public class MybatisClientSecretDAOImpl implements ClientSecretDAO {
@Autowired
private ClientSecretMapper mapper;
diff --git a/src/main/java/com/blueskykong/auth/dao/impl/UserDaoImpl.java b/src/main/java/com/blueskykong/auth/dao/impl/UserDaoImpl.java
new file mode 100644
index 0000000..7472d86
--- /dev/null
+++ b/src/main/java/com/blueskykong/auth/dao/impl/UserDaoImpl.java
@@ -0,0 +1,49 @@
+package com.blueskykong.auth.dao.impl;
+
+import com.blueskykong.auth.dao.UserDao;
+import com.blueskykong.auth.dao.mapper.UserMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+import java.util.Map;
+
+/**
+ * @author figo
+ */
+@Repository
+public class UserDaoImpl implements UserDao {
+
+ @Autowired
+ private UserMapper mapper;
+
+ /**
+ * 获取店铺账户信息
+ * @param map
+ * @return
+ */
+ @Override
+ public Map getShopAccount(Map map){
+ return mapper.getShopAccount(map);
+ }
+
+
+ /**
+ * 获取服务员信息
+ * @param map
+ * @return
+ */
+ @Override
+ public Map getWaiter(Map map){
+ return mapper.getWaiter(map);
+ }
+
+ /**
+ * 获取平台用户
+ * @param map
+ * @return
+ */
+ @Override
+ public Map getPlatformUser(Map map){
+ return mapper.getPlatformUser(map);
+ }
+}
diff --git a/src/main/java/com/blueskykong/auth/dao/mapper/UserMapper.java b/src/main/java/com/blueskykong/auth/dao/mapper/UserMapper.java
new file mode 100644
index 0000000..4cc5bdd
--- /dev/null
+++ b/src/main/java/com/blueskykong/auth/dao/mapper/UserMapper.java
@@ -0,0 +1,33 @@
+package com.blueskykong.auth.dao.mapper;
+
+import java.util.Map;
+
+/**
+ * 对用户信息的操作
+ * @author figo
+ */
+public interface UserMapper {
+
+ /**
+ * 获取店铺账户信息
+ * @param map
+ * @return
+ */
+ Map getShopAccount(Map map);
+
+
+ /**
+ * 获取服务员信息
+ * @param map
+ * @return
+ */
+ Map getWaiter(Map map);
+
+ /**
+ * 获取平台用户
+ * @param map
+ * @return
+ */
+ Map getPlatformUser(Map map);
+
+}
diff --git a/src/main/java/com/blueskykong/auth/dto/UserInfoDTO.java b/src/main/java/com/blueskykong/auth/dto/UserInfoDTO.java
new file mode 100644
index 0000000..43059ad
--- /dev/null
+++ b/src/main/java/com/blueskykong/auth/dto/UserInfoDTO.java
@@ -0,0 +1,68 @@
+package com.blueskykong.auth.dto;
+
+import com.qms.utils.entity.BaseEntity;
+import lombok.Data;
+
+/**
+ * @title: UserInfoVo
+ * @package: com.qms.user.entity.vo
+ * @description:
+ * @anther: dongzhanbiao
+ * @date: 2017-09-27 上午11:03
+ * @author figo
+ */
+@Data
+public class UserInfoDTO extends BaseEntity {
+
+ /**
+ * 用户标识ID
+ */
+ private String userId;
+ /**
+ * 用户名
+ */
+ private String userName;
+
+ /**
+ * 密码
+ */
+ private String passWord;
+
+ /**
+ * 真是姓名
+ */
+ private String realName;
+ /**
+ * 用户昵称
+ */
+ private String userNick;
+ /**
+ * 用户性别
+ */
+ private Integer userSex;
+ /**
+ * 用户生日
+ */
+ private String userBirthday;
+ /**
+ * 省
+ */
+ private String province;
+ /**
+ * 市
+ */
+ private String city;
+ /**
+ * 区
+ */
+ private String district;
+ /**
+ * 地址
+ */
+ private String address;
+ /**
+ * 用户头像地址
+ */
+ private String userHeadpic;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/blueskykong/auth/entity/ClientSecretStatus.java b/src/main/java/com/blueskykong/auth/entity/ClientSecretStatus.java
index 9d4d930..33d6c72 100644
--- a/src/main/java/com/blueskykong/auth/entity/ClientSecretStatus.java
+++ b/src/main/java/com/blueskykong/auth/entity/ClientSecretStatus.java
@@ -4,5 +4,9 @@
* Created by keets on 2016/12/5.
*/
public enum ClientSecretStatus {
- ACTIVE, INACTIVE
+ //活跃
+ ACTIVE,
+
+ //非活跃
+ INACTIVE
}
diff --git a/src/main/java/com/blueskykong/auth/rest/ClientSecretResource.java b/src/main/java/com/blueskykong/auth/rest/ClientSecretResource.java
index 730ceba..32fc262 100644
--- a/src/main/java/com/blueskykong/auth/rest/ClientSecretResource.java
+++ b/src/main/java/com/blueskykong/auth/rest/ClientSecretResource.java
@@ -1,24 +1,21 @@
package com.blueskykong.auth.rest;
-import com.blueskykong.auth.dto.ApiClientDTO;
-import com.blueskykong.auth.entity.ClientSecretStatus;
-import com.blueskykong.auth.service.ClientSecretService;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
-import javax.ws.rs.*;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import java.util.List;
-import java.util.UUID;
+import java.security.Principal;
+import java.util.LinkedHashMap;
+import java.util.Map;
/**
* @author keets
* @date 2017/9/18
*/
-@Path("/")
+@RestController
+@RequestMapping("/")
public class ClientSecretResource {
- @Autowired
+ /*@Autowired
private ClientSecretService clientSecretService;
@POST
@@ -47,5 +44,12 @@ public Response getClient(@PathParam("clientId") String clientId) {
public Response updateClient(@PathParam("clientId") String clientId, ApiClientDTO apiClientDTO) {
clientSecretService.updateClientSecret(apiClientDTO);
return Response.ok().build();
+ }*/
+
+ @RequestMapping({ "/user", "/me" })
+ public Map user(Principal principal) {
+ Map map = new LinkedHashMap<>();
+ map.put("username", principal.getName());
+ return map;
}
}
diff --git a/src/main/java/com/blueskykong/auth/rest/SecurityResource.java b/src/main/java/com/blueskykong/auth/rest/SecurityResource.java
index c5c4c26..e272536 100644
--- a/src/main/java/com/blueskykong/auth/rest/SecurityResource.java
+++ b/src/main/java/com/blueskykong/auth/rest/SecurityResource.java
@@ -32,7 +32,7 @@ public Response logout(@QueryParam("token") String token) {
OAuth2AccessToken existingAccessToken = tokenStore.readAccessToken(token);
OAuth2RefreshToken refreshToken;
- if (existingAccessToken != null) {
+ /*if (existingAccessToken != null) {
if (existingAccessToken.getRefreshToken() != null) {
LOGGER.info("remove refreshToken!");
refreshToken = existingAccessToken.getRefreshToken();
@@ -40,7 +40,7 @@ public Response logout(@QueryParam("token") String token) {
}
LOGGER.info("remove existingAccessToken!");
tokenStore.removeAccessToken(existingAccessToken);
- }
+ }*/
return Response.ok().build();
}
diff --git a/src/main/java/com/blueskykong/auth/security/CustomAuthenticationProvider.java b/src/main/java/com/blueskykong/auth/security/CustomAuthenticationProvider.java
index 1d9cecd..b28aeda 100644
--- a/src/main/java/com/blueskykong/auth/security/CustomAuthenticationProvider.java
+++ b/src/main/java/com/blueskykong/auth/security/CustomAuthenticationProvider.java
@@ -1,18 +1,20 @@
package com.blueskykong.auth.security;
-import com.blueskykong.auth.client.feign.UserClient;
import com.auth0.jwt.internal.org.apache.commons.lang3.StringUtils;
+import com.blueskykong.auth.service.UserService;
+import com.qms.utils.security.CustomAuthenticationToken;
+import com.qms.utils.security.CustomUserDetails;
import org.springframework.beans.factory.annotation.Autowired;
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.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
+import java.util.*;
/**
* @author keets
@@ -22,46 +24,56 @@
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
- private UserClient userClient;
+ private UserService userService;
+ /**
+ * 根据用户名、密码进行身份认证
+ * @param authentication
+ * @return
+ * @throws AuthenticationException
+ */
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password;
Map data = (Map) authentication.getDetails();
- String clientId = (String) data.get("client");
+ String clientId = (String) data.get("clientId");
Assert.hasText(clientId, "clientId must have value");
String type = (String) data.get("type");
Map map;
password = (String) authentication.getCredentials();
- //如果你是调用user服务,这边不用注掉
- //map = userClient.checkUsernameAndPassword(getUserServicePostObject(username, password, type));
- map = checkUsernameAndPassword(getUserServicePostObject(username, password, type));
+ //根据用户类型,验证用户的用户名密码,并返回用户对象信息。
+ map = userService.getUser(getUserServicePostObject(username, password, type));
-
- String userId = (String) map.get("userId");
+ //userId做非null及非空字符串判断,另外不同的用户类型,id可能为string/int/long等类型
+ String userId = "";
+ Object userIdObj = map.get("userId");
+ if (userIdObj != null) {
+ userId = userIdObj.toString();
+ }
if (StringUtils.isBlank(userId)) {
String errorCode = (String) map.get("code");
throw new BadCredentialsException(errorCode);
}
- CustomUserDetails customUserDetails = buildCustomUserDetails(username, password, userId, clientId);
+
+ CustomUserDetails customUserDetails = buildCustomUserDetails(username, password, userId, clientId, type);
return new CustomAuthenticationToken(customUserDetails);
}
- private CustomUserDetails buildCustomUserDetails(String username, String password, String userId, String clientId) {
- CustomUserDetails customUserDetails = new CustomUserDetails.CustomUserDetailsBuilder()
+ private CustomUserDetails buildCustomUserDetails(String username, String password, String userId, String clientId, String type) {
+ return new CustomUserDetails.CustomUserDetailsBuilder()
.withUserId(userId)
.withPassword(password)
.withUsername(username)
.withClientId(clientId)
+ .withAuthorities(getAuthorities(type))
.build();
- return customUserDetails;
}
private Map getUserServicePostObject(String username, String password, String type) {
Map requestParam = new HashMap();
- requestParam.put("userName", username);
+ requestParam.put("username", username);
requestParam.put("password", password);
if (type != null && StringUtils.isNotBlank(type)) {
requestParam.put("type", type);
@@ -69,19 +81,24 @@ private Map getUserServicePostObject(String username, String pas
return requestParam;
}
- //模拟调用user服务的方法
- private Map checkUsernameAndPassword(Map map) {
-
- //checkUsernameAndPassword
- Map ret = new HashMap();
- ret.put("userId", UUID.randomUUID().toString());
-
- return ret;
- }
-
@Override
public boolean supports(Class> aClass) {
return true;
}
+ /**
+ * 设置用户角色权限
+ * @param type
+ * @return
+ *
+ * // TODO: 06/12/2017 通过用户类型,简单设置用户的权限角色,后期需要在网关上扩展。
+ */
+ private Collection extends GrantedAuthority> getAuthorities(String type){
+ String authority = org.apache.commons.lang3.StringUtils.upperCase(type);
+ Set authSet = new HashSet<>();
+ authSet.add(new SimpleGrantedAuthority("ROLE_" + authority));
+
+ return authSet;
+ }
+
}
\ No newline at end of file
diff --git a/src/main/java/com/blueskykong/auth/security/CustomAuthenticationToken.java b/src/main/java/com/blueskykong/auth/security/CustomAuthenticationToken.java
deleted file mode 100644
index 961fd0c..0000000
--- a/src/main/java/com/blueskykong/auth/security/CustomAuthenticationToken.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.blueskykong.auth.security;
-
-import org.springframework.security.authentication.AbstractAuthenticationToken;
-
-/**
- * Created by keets on 2017/8/5.
- */
-public class CustomAuthenticationToken extends AbstractAuthenticationToken {
-
- private CustomUserDetails userDetails;
-
- public CustomAuthenticationToken(CustomUserDetails userDetails) {
- super(null);
- this.userDetails = userDetails;
- super.setAuthenticated(true);
- }
-
- public Object getPrincipal() {
- return this.userDetails;
- }
-
- public Object getCredentials() {
- return this.userDetails.getPassword();
- }
-
-}
\ No newline at end of file
diff --git a/src/main/java/com/blueskykong/auth/security/CustomAuthorizationTokenServices.java b/src/main/java/com/blueskykong/auth/security/CustomAuthorizationTokenServices.java
index 4ddeb2a..6e66885 100644
--- a/src/main/java/com/blueskykong/auth/security/CustomAuthorizationTokenServices.java
+++ b/src/main/java/com/blueskykong/auth/security/CustomAuthorizationTokenServices.java
@@ -22,12 +22,16 @@
/**
* Created by keets on 2017/8/5.
+ *
+ * @author figo
*/
public class CustomAuthorizationTokenServices implements AuthorizationServerTokenServices, ConsumerTokenServices {
- private int refreshTokenValiditySeconds = 60 * 60 * 24 * 30; // default 30 days.
+ // default 30 days.
+ private int refreshTokenValiditySeconds = 60 * 60 * 24 * 30;
- private int accessTokenValiditySeconds = 60 * 60 * 12; // default 12 hours.
+ // default 12 hours.
+ private int accessTokenValiditySeconds = 60 * 60 * 12;
private boolean supportRefreshToken = false;
@@ -49,7 +53,7 @@ public void afterPropertiesSet() throws Exception {
}
@Override
- @Transactional
+ @Transactional(rollbackFor = Exception.class)
public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) throws AuthenticationException {
OAuth2AccessToken existingAccessToken = tokenStore.getAccessToken(authentication);
diff --git a/src/main/java/com/blueskykong/auth/security/CustomTokenEnhancer.java b/src/main/java/com/blueskykong/auth/security/CustomTokenEnhancer.java
index bb7cdc8..512e77c 100644
--- a/src/main/java/com/blueskykong/auth/security/CustomTokenEnhancer.java
+++ b/src/main/java/com/blueskykong/auth/security/CustomTokenEnhancer.java
@@ -1,5 +1,6 @@
package com.blueskykong.auth.security;
+import com.qms.utils.security.CustomUserDetails;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
diff --git a/src/main/java/com/blueskykong/auth/security/CustomUserDetails.java b/src/main/java/com/blueskykong/auth/security/CustomUserDetails.java
deleted file mode 100644
index a7e6312..0000000
--- a/src/main/java/com/blueskykong/auth/security/CustomUserDetails.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package com.blueskykong.auth.security;
-
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-
-import java.util.Collection;
-
-/**
- * @author keets
- * @date 2017/8/5
- */
-public class CustomUserDetails implements UserDetails {
- static final long serialVersionUID = -7588980448693010399L;
- private String username;
-
- private String password;
-
- private boolean enabled = true;
-
- private String userId;
-
- private String clientId;
-
- private Collection extends GrantedAuthority> authorities;
-
- public String getClientId() {
- return clientId;
- }
-
- public void setClientId(String clientId) {
- this.clientId = clientId;
- }
-
- public String getUserId() {
- return userId;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
-
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- }
-
- public void setUserId(String userId) {
- this.userId = userId;
- }
-
-
- public void setAuthorities(Collection extends GrantedAuthority> authorities) {
- this.authorities = authorities;
- }
-
- @Override
- public Collection extends GrantedAuthority> getAuthorities() {
- return authorities;
- }
-
- @Override
- public String getPassword() {
- return this.password;
- }
-
- @Override
- public String getUsername() {
- return this.username;
- }
-
- @Override
- public boolean isAccountNonExpired() {
- return true;
- }
-
- @Override
- public boolean isAccountNonLocked() {
- return true;
- }
-
- @Override
- public boolean isCredentialsNonExpired() {
- return true;
- }
-
- @Override
- public boolean isEnabled() {
- return enabled;
- }
-
- public static class CustomUserDetailsBuilder {
- private CustomUserDetails userDetails = new CustomUserDetails();
-
- public CustomUserDetailsBuilder withUsername(String username) {
- userDetails.setUsername(username);
- userDetails.setAuthorities(null);
- return this;
- }
-
- public CustomUserDetailsBuilder withPassword(String password) {
- userDetails.setPassword(password);
- return this;
- }
-
- public CustomUserDetailsBuilder withClientId(String clientId) {
- userDetails.setClientId(clientId);
- return this;
- }
-
- public CustomUserDetailsBuilder withUserId(String userId) {
- userDetails.setUserId(userId);
- return this;
- }
-
- public CustomUserDetails build() {
- return userDetails;
- }
- }
-
-}
diff --git a/src/main/java/com/blueskykong/auth/service/UserService.java b/src/main/java/com/blueskykong/auth/service/UserService.java
new file mode 100644
index 0000000..eb7c9d1
--- /dev/null
+++ b/src/main/java/com/blueskykong/auth/service/UserService.java
@@ -0,0 +1,86 @@
+package com.blueskykong.auth.service;
+
+import com.blueskykong.auth.client.feign.UserClient;
+import com.blueskykong.auth.dao.UserDao;
+import com.blueskykong.auth.dto.UserInfoDTO;
+import com.qms.utils.ErrorListEnum;
+import com.qms.utils.entity.GeneralVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * 用户业务服务
+ * @author figo
+ * Created by figo on 01/12/2017.
+ */
+
+@Service
+public class UserService {
+
+ @Autowired
+ private UserDao userDao;
+
+ @Autowired
+ private UserClient userClient;
+
+ /**
+ * 根据客户端用户类型如C端用户/B端商户/W端服务员/P端管理员等,
+ * 分别到对应的数据表中进行用户名和密码的验证。
+ * @param map
+ * @return
+ */
+ public Map getUser(Map map){
+
+ String type = map.get("type");
+ switch (type){
+ case "customer":
+ map = getCustomer(map);
+ break;
+ case "shop":
+ map = userDao.getShopAccount(map);
+ break;
+ case "waiter":
+ map = userDao.getWaiter(map);
+ break;
+ case "platform":
+ map = userDao.getPlatformUser(map);
+ break;
+ default:{}
+ }
+
+ return map!=null ? map : new HashMap(0);
+ }
+
+ /**
+ * 获取C端用户信息
+ * @param map
+ * @return
+ */
+ private Map getCustomer(Map map){
+ String username = map.get("username");
+ String password = map.get("password");
+
+ GeneralVO result = userClient.queryUseInfoByUserName(username);
+ if (result == null) {
+ return new HashMap(0);
+ }
+ if (!Objects.equals(result.getCode(), ErrorListEnum.E200.getKey())){
+ return new HashMap(0);
+ }
+ if(result.getBody() == null){
+ return new HashMap(0);
+ }
+
+ UserInfoDTO userInfo = (UserInfoDTO) result.getBody();
+ if (Objects.equals(password, userInfo.getPassWord())){
+ map.put("userId", userInfo.getUserId());
+ return map;
+ }
+
+ return new HashMap(0);
+ }
+}
diff --git a/src/main/java/com/blueskykong/auth/utils/TimestampAdapter.java b/src/main/java/com/blueskykong/auth/utils/TimestampAdapter.java
index cb2a655..4b0de42 100644
--- a/src/main/java/com/blueskykong/auth/utils/TimestampAdapter.java
+++ b/src/main/java/com/blueskykong/auth/utils/TimestampAdapter.java
@@ -11,8 +11,8 @@
import java.text.SimpleDateFormat;
public class TimestampAdapter extends XmlAdapter {
- private static final DatatypeFactory df;
- private static final ThreadLocal simpleDateFormat = new ThreadLocal(){
+ private static final DatatypeFactory DF;
+ private static final ThreadLocal SIMPLE_DATE_FORMAT = new ThreadLocal(){
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@@ -21,7 +21,7 @@ protected DateFormat initialValue() {
static {
try {
- df = DatatypeFactory.newInstance();
+ DF = DatatypeFactory.newInstance();
} catch (DatatypeConfigurationException e) {
throw Throwables.propagate(e);
}
@@ -30,14 +30,14 @@ protected DateFormat initialValue() {
@Override
public String marshal(Timestamp v) throws Exception {
if (v != null) {
- return simpleDateFormat.get().format(v);
+ return SIMPLE_DATE_FORMAT.get().format(v);
}
return null;
}
@Override
public Timestamp unmarshal(String v) throws Exception {
- XMLGregorianCalendar cal = df.newXMLGregorianCalendar(v);
+ XMLGregorianCalendar cal = DF.newXMLGregorianCalendar(v);
try {
return new Timestamp(cal.toGregorianCalendar().getTimeInMillis());
} catch (Exception e) {
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 9ce03a7..162e3e2 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -6,36 +6,14 @@ spring:
maximum-pool-size: 5
pool-name: dbcp1
driver-class-name: com.mysql.jdbc.Driver
- url: jdbc:mysql://116.62.146.35:3307/auth?autoReconnect=true&useSSL=false
- username: ${AUTH_DB_PWD:root}
- password: ${AUTH_DB_USER:root123}
+ url: jdbc:mysql://rm-2ze2g7ns6cx4y9346o.mysql.rds.aliyuncs.com:3306/qmsdb
+ username: ${AUTH_DB_PWD:qmsdb}
+ password: ${AUTH_DB_USER:jk23RuF!@9isaHf23}
type: com.zaxxer.hikari.HikariDataSource
-
-############################# Redis config #############################
-cache:
- # pool config
- pool:
- maxIdle: 15
- maxTotal: 30
- maxWaitMillis: 6000
- minIdle: 1
- numTestsPerEvictionRun: 10
- testOnBorrow: true
- testOnReturn: true
- testWhileIdle: true
- timeBetweenEvictionRunsMillis: 6000
- # enable redis
redis:
- enabled: true
-# if flush all the cache when start up
-redis:
- database: 0
- host:
- address: ${REDIS_ADDRESS:116.62.146.35}
- password: ${REDIS_PWD:}
- port: ${REDIS_PORT:7000}
- setup:
- flushdb: true
+ port: ${REDIS_PORT:16339}
+ host: ${REDIS_ADDRESS:101.201.177.32}
+ password: ${REDIS_PWD:02681330-d47f-4e34-a0fc-4a2f8931c523}
ribbon:
ReadTimeout: 10000
@@ -48,4 +26,3 @@ hystrix:
strategy: THREAD
thread:
timeoutInMilliseconds: 10000
-
diff --git a/src/main/resources/bootstrap.yml b/src/main/resources/bootstrap.yml
index b77c380..9539368 100644
--- a/src/main/resources/bootstrap.yml
+++ b/src/main/resources/bootstrap.yml
@@ -1,5 +1,6 @@
server:
port: 9000
+ context-path: /auth
---
spring:
diff --git a/src/main/resources/mybatis/mapper/UserMapper.xml b/src/main/resources/mybatis/mapper/UserMapper.xml
new file mode 100644
index 0000000..814e9da
--- /dev/null
+++ b/src/main/resources/mybatis/mapper/UserMapper.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/com.blueskykong.auth.controller/TokenEndpointTest.java b/src/test/com.blueskykong.auth.controller/TokenEndpointTest.java
new file mode 100644
index 0000000..24eb907
--- /dev/null
+++ b/src/test/com.blueskykong.auth.controller/TokenEndpointTest.java
@@ -0,0 +1,138 @@
+package com.blueskykong.auth.controller;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.cloud.netflix.feign.FeignAutoConfiguration;
+import org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientAutoConfiguration;
+import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+
+/**
+ * Created by figo on 24/11/2017.
+ *
+ * @author figo
+ */
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@AutoConfigureMockMvc
+@ImportAutoConfiguration({RibbonAutoConfiguration.class, FeignRibbonClientAutoConfiguration.class, FeignAutoConfiguration.class})
+public class TokenEndpointTest {
+
+ @Autowired
+ private MockMvc mvc;
+
+ /**
+ * 测试获取C端用户账户token
+ * @throws Exception
+ */
+ @Test
+ public void getCustomerOauthToken() throws Exception {
+
+ MvcResult result = mvc.perform(MockMvcRequestBuilders.post("/oauth/token")
+ .contentType(MediaType.APPLICATION_FORM_URLENCODED)
+ .header("authorization", "Basic ZnJvbnRlbmQ6ZnJvbnRlbmQ=,")
+ .param("grant_type", "password")
+ .param("username", "18966922934")
+ .param("password", "E0369B31012DC0BCD11221B7D49C16AF")
+ .param("clientId", "frontend")
+ .param("type", "customer")
+ )
+ .andExpect(MockMvcResultMatchers.status().isOk())
+ .andReturn();
+
+ int statusCode = result.getResponse().getStatus();
+ Assert.assertEquals(statusCode, 200);
+ String body = result.getResponse().getContentAsString();
+ System.out.println("body:" + body);
+
+ }
+
+ /**
+ * 测试获取店铺账户token
+ * @throws Exception
+ */
+ @Test
+ public void getShopOauthToken() throws Exception {
+
+ MvcResult result = mvc.perform(MockMvcRequestBuilders.post("/oauth/token")
+ .contentType(MediaType.APPLICATION_FORM_URLENCODED)
+ .header("authorization", "Basic ZnJvbnRlbmQ6ZnJvbnRlbmQ=,")
+ .param("grant_type", "password")
+ .param("username", "13689248182")
+ .param("password", "E0369B31012DC0BCD11221B7D49C16AF")
+ .param("clientId", "frontend")
+ .param("type", "shop")
+ )
+ .andExpect(MockMvcResultMatchers.status().isOk())
+ .andReturn();
+
+ int statusCode = result.getResponse().getStatus();
+ Assert.assertEquals(statusCode, 200);
+ String body = result.getResponse().getContentAsString();
+ System.out.println("body:" + body);
+
+ }
+
+ /**
+ * 测试获取服务员token
+ * @throws Exception
+ */
+ @Test
+ public void getWaiterOauthToken() throws Exception {
+
+ MvcResult result = mvc.perform(MockMvcRequestBuilders.post("/oauth/token")
+ .contentType(MediaType.APPLICATION_FORM_URLENCODED)
+ .header("authorization", "Basic ZnJvbnRlbmQ6ZnJvbnRlbmQ=,")
+ .param("grant_type", "password")
+ .param("username", "15839396565")
+ .param("password", "123456")
+ .param("clientId", "frontend")
+ .param("type", "waiter")
+ )
+ .andExpect(MockMvcResultMatchers.status().isOk())
+ .andReturn();
+
+ int statusCode = result.getResponse().getStatus();
+ Assert.assertEquals(statusCode, 200);
+ String body = result.getResponse().getContentAsString();
+ System.out.println("body:" + body);
+
+ }
+
+ /**
+ * 测试获取平台用户token
+ * @throws Exception
+ */
+ @Test
+ public void getPlatformUserOauthToken() throws Exception {
+
+ MvcResult result = mvc.perform(MockMvcRequestBuilders.post("/oauth/token")
+ .contentType(MediaType.APPLICATION_FORM_URLENCODED)
+ .header("authorization", "Basic ZnJvbnRlbmQ6ZnJvbnRlbmQ=,")
+ .param("grant_type", "password")
+ .param("username", "admin")
+ .param("password", "123123")
+ .param("clientId", "frontend")
+ .param("type", "platform")
+ )
+ .andExpect(MockMvcResultMatchers.status().isOk())
+ .andReturn();
+
+ int statusCode = result.getResponse().getStatus();
+ Assert.assertEquals(statusCode, 200);
+ String body = result.getResponse().getContentAsString();
+ System.out.println("body:" + body);
+
+ }
+}