diff --git a/pig-auth-service/src/main/java/com/github/pig/auth/component/mobile/MobileAuthenticationFilter.java b/pig-auth-service/src/main/java/com/github/pig/auth/component/mobile/MobileAuthenticationFilter.java
new file mode 100644
index 00000000..0608fe14
--- /dev/null
+++ b/pig-auth-service/src/main/java/com/github/pig/auth/component/mobile/MobileAuthenticationFilter.java
@@ -0,0 +1,76 @@
+package com.github.pig.auth.component.mobile;
+
+import com.github.pig.common.constant.SecurityConstants;
+import org.springframework.http.HttpMethod;
+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 javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author lengleng
+ * @date 2018/1/9
+ * 手机号登录验证filter
+ */
+public class MobileAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
+ public static final String SPRING_SECURITY_FORM_MOBILE_KEY = "mobile";
+
+ private String mobileParameter = SPRING_SECURITY_FORM_MOBILE_KEY;
+ private boolean postOnly = true;
+
+ public MobileAuthenticationFilter() {
+ super(new AntPathRequestMatcher(SecurityConstants.MOBILE_TOKEN_URL, "POST"));
+ }
+
+ public Authentication attemptAuthentication(HttpServletRequest request,
+ HttpServletResponse response) throws AuthenticationException {
+ if (postOnly && !request.getMethod().equals(HttpMethod.POST.name())) {
+ throw new AuthenticationServiceException(
+ "Authentication method not supported: " + request.getMethod());
+ }
+
+ String mobile = obtainMobile(request);
+
+ if (mobile == null) {
+ mobile = "";
+ }
+
+ mobile = mobile.trim();
+
+ MobileAuthenticationToken mobileAuthenticationToken = new MobileAuthenticationToken(mobile);
+
+ setDetails(request, mobileAuthenticationToken);
+
+ return this.getAuthenticationManager().authenticate(mobileAuthenticationToken);
+ }
+
+ protected String obtainMobile(HttpServletRequest request) {
+ return request.getParameter(mobileParameter);
+ }
+
+ protected void setDetails(HttpServletRequest request,
+ MobileAuthenticationToken authRequest) {
+ authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
+ }
+
+ public void setPostOnly(boolean postOnly) {
+ this.postOnly = postOnly;
+ }
+
+ public String getMobileParameter() {
+ return mobileParameter;
+ }
+
+ public void setMobileParameter(String mobileParameter) {
+ this.mobileParameter = mobileParameter;
+ }
+
+ public boolean isPostOnly() {
+ return postOnly;
+ }
+}
+
diff --git a/pig-auth-service/src/main/java/com/github/pig/auth/component/mobile/MobileAuthenticationProvider.java b/pig-auth-service/src/main/java/com/github/pig/auth/component/mobile/MobileAuthenticationProvider.java
new file mode 100644
index 00000000..3f52d8d1
--- /dev/null
+++ b/pig-auth-service/src/main/java/com/github/pig/auth/component/mobile/MobileAuthenticationProvider.java
@@ -0,0 +1,50 @@
+package com.github.pig.auth.component.mobile;
+
+import com.github.pig.auth.feign.UserService;
+import com.github.pig.auth.util.UserDetailsImpl;
+import com.github.pig.common.vo.UserVo;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.InternalAuthenticationServiceException;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+
+/**
+ * @author lengleng
+ * @date 2018/1/9
+ * 手机号登录校验逻辑
+ */
+public class MobileAuthenticationProvider implements AuthenticationProvider {
+ private UserService userService;
+
+ @Override
+ public Authentication authenticate(Authentication authentication) throws AuthenticationException {
+ MobileAuthenticationToken mobileAuthenticationToken = (MobileAuthenticationToken) authentication;
+ UserVo userVo = userService.findUserByMobile((String) mobileAuthenticationToken.getPrincipal());
+
+ UserDetailsImpl userDetails = buildUserDeatils(userVo);
+ if (userDetails == null) {
+ throw new InternalAuthenticationServiceException("手机号不存在:" + mobileAuthenticationToken.getPrincipal());
+ }
+
+ MobileAuthenticationToken authenticationToken = new MobileAuthenticationToken(userDetails, userDetails.getAuthorities());
+ authenticationToken.setDetails(mobileAuthenticationToken.getDetails());
+ return authenticationToken;
+ }
+
+ private UserDetailsImpl buildUserDeatils(UserVo userVo) {
+ return new UserDetailsImpl(userVo);
+ }
+
+ @Override
+ public boolean supports(Class> authentication) {
+ return MobileAuthenticationToken.class.isAssignableFrom(authentication);
+ }
+
+ public UserService getUserService() {
+ return userService;
+ }
+
+ public void setUserService(UserService userService) {
+ this.userService = userService;
+ }
+}
diff --git a/pig-auth-service/src/main/java/com/github/pig/auth/component/mobile/MobileAuthenticationToken.java b/pig-auth-service/src/main/java/com/github/pig/auth/component/mobile/MobileAuthenticationToken.java
new file mode 100644
index 00000000..860cc068
--- /dev/null
+++ b/pig-auth-service/src/main/java/com/github/pig/auth/component/mobile/MobileAuthenticationToken.java
@@ -0,0 +1,56 @@
+package com.github.pig.auth.component.mobile;
+
+import org.springframework.security.authentication.AbstractAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.SpringSecurityCoreVersion;
+
+import java.util.Collection;
+
+/**
+ * @author lengleng
+ * @date 2018/1/9
+ * 手机号登录令牌
+ */
+public class MobileAuthenticationToken extends AbstractAuthenticationToken {
+
+ private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
+
+ private final Object principal;
+
+ public MobileAuthenticationToken(String mobile) {
+ super(null);
+ this.principal = mobile;
+ setAuthenticated(false);
+ }
+
+ public MobileAuthenticationToken(Object principal,
+ Collection extends GrantedAuthority> authorities) {
+ super(authorities);
+ this.principal = principal;
+ super.setAuthenticated(true);
+ }
+
+ public Object getPrincipal() {
+ return this.principal;
+ }
+
+ @Override
+ public Object getCredentials() {
+ return null;
+ }
+
+ 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);
+ }
+
+ @Override
+ public void eraseCredentials() {
+ super.eraseCredentials();
+ }
+}
+
diff --git a/pig-auth-service/src/main/java/com/github/pig/auth/component/mobile/MobileLoginSuccessHandler.java b/pig-auth-service/src/main/java/com/github/pig/auth/component/mobile/MobileLoginSuccessHandler.java
new file mode 100644
index 00000000..125bb679
--- /dev/null
+++ b/pig-auth-service/src/main/java/com/github/pig/auth/component/mobile/MobileLoginSuccessHandler.java
@@ -0,0 +1,113 @@
+package com.github.pig.auth.component.mobile;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.pig.common.constant.CommonConstant;
+import com.xiaoleilu.hutool.util.MapUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.crypto.codec.Base64;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
+import org.springframework.security.oauth2.common.exceptions.UnapprovedClientAuthenticationException;
+import org.springframework.security.oauth2.provider.*;
+import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @author lengleng
+ * @date 2018/1/8
+ * 手机号登录成功,返回oauth token
+ */
+@Component
+public class MobileLoginSuccessHandler implements org.springframework.security.web.authentication.AuthenticationSuccessHandler {
+ private Logger logger = LoggerFactory.getLogger(getClass());
+ @Autowired
+ private ObjectMapper objectMapper;
+ @Autowired
+ private ClientDetailsService clientDetailsService;
+ @Autowired
+ private AuthorizationServerTokenServices authorizationServerTokenServices;
+
+ /**
+ * Called when a user has been successfully authenticated.
+ * 调用spring security oauth API 生成 oAuth2AccessToken
+ *
+ * @param request the request which caused the successful authentication
+ * @param response the response
+ * @param authentication the Authentication object which was created during
+ */
+ @Override
+ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
+ String header = request.getHeader("Authorization");
+
+ if (header == null || !header.startsWith("Basic ")) {
+ throw new UnapprovedClientAuthenticationException("请求头中client信息为空");
+ }
+
+ try {
+ String[] tokens = extractAndDecodeHeader(header);
+ assert tokens.length == 2;
+ String clientId = tokens[0];
+ String clientSecret = tokens[1];
+
+ JSONObject params = new JSONObject();
+ params.put("clientId", clientId);
+ params.put("clientSecret", clientSecret);
+ params.put("authentication", authentication);
+
+ ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
+ TokenRequest tokenRequest = new TokenRequest(MapUtil.newHashMap(), clientId, clientDetails.getScope(), "mobile");
+ OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
+
+ OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
+ OAuth2AccessToken oAuth2AccessToken = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);
+ logger.info("获取token 成功:{}", oAuth2AccessToken.getValue());
+
+ response.setCharacterEncoding(CommonConstant.UTF8);
+ response.setContentType(CommonConstant.CONTENT_TYPE);
+ PrintWriter printWriter = response.getWriter();
+ printWriter.append(objectMapper.writeValueAsString(oAuth2AccessToken));
+ } catch (IOException e) {
+ throw new BadCredentialsException(
+ "Failed to decode basic authentication token");
+ }
+ }
+
+ /**
+ * Decodes the header into a username and password.
+ *
+ * @throws BadCredentialsException if the Basic header is not present or is not valid
+ * Base64
+ */
+ private String[] extractAndDecodeHeader(String header)
+ throws IOException {
+
+ byte[] base64Token = header.substring(6).getBytes("UTF-8");
+ byte[] decoded;
+ try {
+ decoded = Base64.decode(base64Token);
+ } catch (IllegalArgumentException e) {
+ throw new BadCredentialsException(
+ "Failed to decode basic authentication token");
+ }
+
+ String token = new String(decoded, CommonConstant.UTF8);
+
+ int delim = token.indexOf(":");
+
+ if (delim == -1) {
+ throw new BadCredentialsException("Invalid basic authentication token");
+ }
+ return new String[]{token.substring(0, delim), token.substring(delim + 1)};
+ }
+
+
+}
diff --git a/pig-auth-service/src/main/java/com/github/pig/auth/component/mobile/MobileSecurityConfigurer.java b/pig-auth-service/src/main/java/com/github/pig/auth/component/mobile/MobileSecurityConfigurer.java
new file mode 100644
index 00000000..2a60dfe6
--- /dev/null
+++ b/pig-auth-service/src/main/java/com/github/pig/auth/component/mobile/MobileSecurityConfigurer.java
@@ -0,0 +1,35 @@
+package com.github.pig.auth.component.mobile;
+
+import com.github.pig.auth.feign.UserService;
+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.UsernamePasswordAuthenticationFilter;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author lengleng
+ * @date 2018/1/9
+ * 手机号登录配置入口
+ */
+@Component
+public class MobileSecurityConfigurer extends SecurityConfigurerAdapter {
+ @Autowired
+ private MobileLoginSuccessHandler mobileLoginSuccessHandler;
+ @Autowired
+ private UserService userService;
+
+ @Override
+ public void configure(HttpSecurity http) throws Exception {
+ MobileAuthenticationFilter mobileAuthenticationFilter = new MobileAuthenticationFilter();
+ mobileAuthenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
+ mobileAuthenticationFilter.setAuthenticationSuccessHandler(mobileLoginSuccessHandler);
+
+ MobileAuthenticationProvider mobileAuthenticationProvider = new MobileAuthenticationProvider();
+ mobileAuthenticationProvider.setUserService(userService);
+ http.authenticationProvider(mobileAuthenticationProvider)
+ .addFilterAfter(mobileAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
+ }
+}