Quellcode durchsuchen

Merge branch 'dev' of chenweida/jw2.0 into dev

chenweida vor 7 Jahren
Ursprung
Commit
effd9f4915
22 geänderte Dateien mit 746 neuen und 87 gelöschten Zeilen
  1. 31 0
      base/common-security/pom.xml
  2. 0 13
      base/common-security/src/main/java/com.yihu.base.security/AuthorizationServerConfig.java
  3. 0 14
      base/common-security/src/main/java/com.yihu.base.security/ResourceServerConfig.java
  4. 17 0
      base/common-security/src/main/java/com.yihu.base.security/SercurityConfig.java
  5. 95 0
      base/common-security/src/main/java/com.yihu.base.security/config/AuthorizationServerConfig.java
  6. 60 0
      base/common-security/src/main/java/com.yihu.base.security/config/ResourceServerConfig.java
  7. 23 14
      base/common-security/src/main/java/com.yihu.base.security/hander/BaseAuthenticationSuccessHandler.java
  8. 15 0
      base/common-security/src/main/java/com.yihu.base.security/properties/SecurityProperties.java
  9. 9 0
      base/common-security/src/main/java/com.yihu.base.security/rbas/ClientServiceProvider.java
  10. 109 0
      base/common-security/src/main/java/com.yihu.base.security/sms/SmsCodeAuthenticationFilter.java
  11. 65 0
      base/common-security/src/main/java/com.yihu.base.security/sms/SmsCodeAuthenticationProvider.java
  12. 81 0
      base/common-security/src/main/java/com.yihu.base.security/sms/SmsCodeAuthenticationToken.java
  13. 17 0
      svr-lib-parent-pom/pom.xml
  14. 4 0
      svr/svr-demo/pom.xml
  15. 88 1
      svr/svr-demo/readme.MD
  16. 2 0
      svr/svr-demo/src/main/java/com/yihu/DemoApplication.java
  17. 2 1
      svr/svr-demo/src/main/java/com/yihu/jw/model/MyUser.java
  18. 80 2
      svr/svr-demo/src/main/java/com/yihu/jw/model/SaasDO.java
  19. 29 9
      svr/svr-demo/src/main/java/com/yihu/jw/service/ClientService.java
  20. 16 6
      svr/svr-demo/src/main/java/com/yihu/jw/service/UserService.java
  21. 2 1
      svr/svr-demo/src/main/resources/application.yml
  22. 1 26
      svr/svr-demo/src/main/resources/resources/denglu.html

+ 31 - 0
base/common-security/pom.xml

@ -19,10 +19,35 @@
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.0.14.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
@ -36,5 +61,11 @@
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.2.5</version>
        </dependency>
    </dependencies>
</project>

+ 0 - 13
base/common-security/src/main/java/com.yihu.base.security/AuthorizationServerConfig.java

@ -1,13 +0,0 @@
package com.yihu.base.security;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
/**
 * Created by chenweida on 2017/12/4.
 */
@Configuration
@EnableAuthorizationServer  //开启授权服务器
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
}

+ 0 - 14
base/common-security/src/main/java/com.yihu.base.security/ResourceServerConfig.java

@ -1,14 +0,0 @@
package com.yihu.base.security;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
/**
 * Created by chenweida on 2017/12/4.
 */
@Configuration
@EnableResourceServer  //开启资源服务器
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
}

+ 17 - 0
base/common-security/src/main/java/com.yihu.base.security/SercurityConfig.java

@ -0,0 +1,17 @@
package com.yihu.base.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
 * Created by chenweida on 2017/12/4.
 */
@Configuration
public class SercurityConfig   {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

+ 95 - 0
base/common-security/src/main/java/com.yihu.base.security/config/AuthorizationServerConfig.java

@ -0,0 +1,95 @@
package com.yihu.base.security.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.base.security.rbas.ClientServiceProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
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.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import javax.annotation.Resource;
import javax.sql.DataSource;
/**
 * Created by chenweida on 2017/12/4.
 */
@Configuration
@EnableAuthorizationServer  //开启授权服务器
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private ClientServiceProvider clientDetailsService;
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private DataSource dataSource;
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(oAuth2AuthenticationManager())
                .tokenStore(tokenStore())
                .userDetailsService(userDetailsService)
                .tokenServices(defaultTokenServices());
        //endpoints.setClientDetailsService(clientDetailsService);
    }
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.jdbc(dataSource)
                .passwordEncoder(passwordEncoder)
                .clients(clientDetailsService)
        ;
    }
    @Bean
    ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper;
    }
    @Bean
    @Primary
    OAuth2AuthenticationManager oAuth2AuthenticationManager() {
        OAuth2AuthenticationManager oAuth2AuthenticationManager = new OAuth2AuthenticationManager();
        oAuth2AuthenticationManager.setClientDetailsService(clientDetailsService);
        oAuth2AuthenticationManager.setTokenServices(defaultTokenServices());
        return oAuth2AuthenticationManager;
    }
    //==========================token相关配置=================================
    @Bean
    @Primary
    DefaultTokenServices defaultTokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        return defaultTokenServices;
    }
    @Bean
    @Primary
    TokenStore tokenStore() {
        RedisTokenStore redisTokenStore = new RedisTokenStore(redisConnectionFactory);
        redisTokenStore.setPrefix("spring:security:oauth2:");
        return redisTokenStore;
    }
}

+ 60 - 0
base/common-security/src/main/java/com.yihu.base.security/config/ResourceServerConfig.java

@ -0,0 +1,60 @@
package com.yihu.base.security.config;
import com.yihu.base.security.properties.SecurityProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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.authentication.OAuth2AuthenticationManager;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
/**
 * Created by chenweida on 2017/12/4.
 */
@Configuration
@EnableResourceServer  //开启资源服务器
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Autowired
    protected AuthenticationSuccessHandler authenticationSuccessHandler;
    @Autowired
    protected AuthenticationFailureHandler authenticationFailureHandler;
    @Autowired
    private OAuth2AuthenticationManager authenticationManager;
    @Autowired
    private TokenStore redisTokenStore;
    @Override
    public void configure(HttpSecurity http) throws Exception {
        //这是账号密码登陆
        http
                .formLogin()//设置验证码 账号密码登陆
                .loginPage(SecurityProperties.formLoginPage)
                .loginProcessingUrl(SecurityProperties.formLogin)
                .successHandler(authenticationSuccessHandler)
                .failureHandler(authenticationFailureHandler)
                .and()
                .authorizeRequests()
                .antMatchers(
                        SecurityProperties.formLogin,
                        SecurityProperties.formLoginPage,
                        SecurityProperties.mobileLogin).permitAll()
                .anyRequest().authenticated()
                .and()
                .csrf().disable();
    }
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.
                authenticationManager(authenticationManager).
                tokenStore(redisTokenStore);
    }
}

+ 23 - 14
base/common-security/src/main/java/com.yihu.base.security/hander/BaseAuthenticationSuccessHandler.java

@ -4,11 +4,13 @@
package com.yihu.base.security.hander;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.base.security.rbas.ClientServiceProvider;
import org.apache.commons.codec.binary.StringUtils;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.codec.Base64;
@ -16,9 +18,11 @@ 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.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -27,33 +31,38 @@ import java.io.UnsupportedEncodingException;
/**
 * @author chenweida
 * <p>
 * 账号密码提交需要在 head 中添加 Basic clientID:cliengSecurty
 *         <p>
 *         账号密码提交需要在 head 中添加 Basic clientID:cliengSecurty
 */
@Component("BaseAuthenticationSuccessHandler")
public class BaseAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
    private Logger logger = LoggerFactory.getLogger(getClass());
    private ObjectMapper objectMapper = new ObjectMapper();
    @Autowired
    private ClientDetailsService clientDetailsService;
    private ObjectMapper objectMapper;
    @Autowired
    private AuthorizationServerTokenServices authorizationServerTokenServices;
    private ClientServiceProvider clientDetailsService;
    @Autowired
    private AuthorizationServerTokenServices defaultTokenServices;
    public BaseAuthenticationSuccessHandler() {
        System.out.println(clientDetailsService);
    }
    /*
     * (non-Javadoc)
     *
     * @see org.springframework.security.web.authentication.
     * AuthenticationSuccessHandler#onAuthenticationSuccess(javax.servlet.http.
     * HttpServletRequest, javax.servlet.http.HttpServletResponse,
     * org.springframework.security.core.Authentication)
     */
         * (non-Javadoc)
         *
         * @see org.springframework.security.web.authentication.
         * AuthenticationSuccessHandler#onAuthenticationSuccess(javax.servlet.http.
         * HttpServletRequest, javax.servlet.http.HttpServletResponse,
         * org.springframework.security.core.Authentication)
         */
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
        String header = request.getHeader("Authorization");
        if (header != null && header.startsWith("Basic ")) {
        if (org.springframework.util.StringUtils.isEmpty(header) || (!header.startsWith("Basic "))) {
            throw new UnapprovedClientAuthenticationException("请求头没有client信息");
        }
        //解析头部的basic信息
@ -77,7 +86,7 @@ public class BaseAuthenticationSuccessHandler extends SavedRequestAwareAuthentic
        OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
        OAuth2AccessToken token = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);
        OAuth2AccessToken token = defaultTokenServices.createAccessToken(oAuth2Authentication);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(objectMapper.writeValueAsString(token));

+ 15 - 0
base/common-security/src/main/java/com.yihu.base.security/properties/SecurityProperties.java

@ -0,0 +1,15 @@
package com.yihu.base.security.properties;
/**
 * Created by chenweida on 2017/12/4.\
 * 安全框架配置信息
 */
public class SecurityProperties {
    //表单登陆相关信息
    public static String formLogin = "/authentication/form";
    public static String formLoginPage = "/denglu.html";
    //短信登陆相关信息
    public static String mobileLogin = "/authentication/mobile";
    public static String mobileLoginKey = "mobile";
}

+ 9 - 0
base/common-security/src/main/java/com.yihu.base.security/rbas/ClientServiceProvider.java

@ -0,0 +1,9 @@
package com.yihu.base.security.rbas;
import org.springframework.security.oauth2.provider.ClientDetailsService;
/**
 * Created by chenweida on 2017/12/5.
 */
public interface ClientServiceProvider extends ClientDetailsService {
}

+ 109 - 0
base/common-security/src/main/java/com.yihu.base.security/sms/SmsCodeAuthenticationFilter.java

@ -0,0 +1,109 @@
/**
 *
 */
package com.yihu.base.security.sms;
import com.yihu.base.security.properties.SecurityProperties;
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 chenweida
 */
public class SmsCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
    // ~ Static fields/initializers
    // =====================================================================================
    private String mobileParameter = SecurityProperties.mobileLoginKey;
    private boolean postOnly = true;
    // ~ Constructors
    // ===================================================================================================
    public SmsCodeAuthenticationFilter() {
        super(new AntPathRequestMatcher(SecurityProperties.mobileLogin, "POST"));
    }
    // ~ Methods
    // ========================================================================================================
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException {
        if (postOnly && !request.getMethod().equals("POST")) {
            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);
    }
    /**
     * 获取手机号
     */
    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 <tt>unsuccessfulAuthentication()</tt> method
     * will be called as if handling a failed authentication.
     * <p>
     * Defaults to <tt>true</tt> but may be overridden by subclasses.
     */
    public void setPostOnly(boolean postOnly) {
        this.postOnly = postOnly;
    }
    public final String getMobileParameter() {
        return mobileParameter;
    }
}

+ 65 - 0
base/common-security/src/main/java/com.yihu.base.security/sms/SmsCodeAuthenticationProvider.java

@ -0,0 +1,65 @@
/**
 * 
 */
package com.yihu.base.security.sms;
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 chenweida
 *
 */
public class SmsCodeAuthenticationProvider implements AuthenticationProvider {
	private UserDetailsService userDetailsService;
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.security.authentication.AuthenticationProvider#
	 * authenticate(org.springframework.security.core.Authentication)
	 */
	@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;
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.security.authentication.AuthenticationProvider#
	 * supports(java.lang.Class)
	 */
	@Override
	public boolean supports(Class<?> authentication) {
		return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication);
	}
	public UserDetailsService getUserDetailsService() {
		return userDetailsService;
	}
	public void setUserDetailsService(UserDetailsService userDetailsService) {
		this.userDetailsService = userDetailsService;
	}
}

+ 81 - 0
base/common-security/src/main/java/com.yihu.base.security/sms/SmsCodeAuthenticationToken.java

@ -0,0 +1,81 @@
/**
 * 
 */
package com.yihu.base.security.sms;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;
import java.util.Collection;
/**
 * @author chenweida
 *
 */
public class SmsCodeAuthenticationToken extends AbstractAuthenticationToken {
	private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
	// ~ Instance fields
	// ================================================================================================
	private final Object principal;
	// ~ Constructors
	// ===================================================================================================
	/**
	 * This constructor can be safely used by any code that wishes to create a
	 * <code>UsernamePasswordAuthenticationToken</code>, as the {@link #isAuthenticated()}
	 * will return <code>false</code>.
	 *
	 */
	public SmsCodeAuthenticationToken(String mobile) {
		super(null);
		this.principal = mobile;
		setAuthenticated(false);
	}
	/**
	 * This constructor should only be used by <code>AuthenticationManager</code> or
	 * <code>AuthenticationProvider</code> implementations that are satisfied with
	 * producing a trusted (i.e. {@link #isAuthenticated()} = <code>true</code>)
	 * authentication token.
	 *
	 * @param principal
	 * @param credentials
	 * @param authorities
	 */
	public SmsCodeAuthenticationToken(Object principal,
									  Collection<? extends GrantedAuthority> authorities) {
		super(authorities);
		this.principal = principal;
		super.setAuthenticated(true); // must use super, as we override
	}
	// ~ Methods
	// ========================================================================================================
	public Object getCredentials() {
		return null;
	}
	public Object getPrincipal() {
		return this.principal;
	}
	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();
	}
}

+ 17 - 0
svr-lib-parent-pom/pom.xml

@ -51,6 +51,8 @@
        <version.jackson>2.8.1</version.jackson>
        <version.myCommon>1.0.0</version.myCommon>
        <version.spring>4.3.8.RELEASE</version.spring>
        <version.spring.security>4.2.3.RELEASE</version.spring.security>
        <version.spring-data-jpa>1.11.3.RELEASE</version.spring-data-jpa>
        <version.spring-data-common>1.13.3.RELEASE</version.spring-data-common>
        <version.zipkin>1.24.0</version.zipkin>
@ -361,6 +363,21 @@
                <version>${version.spring}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-core</artifactId>
                <version>${version.spring.security}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-web</artifactId>
                <version>${version.spring.security}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-config</artifactId>
                <version>${version.spring.security}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>

+ 4 - 0
svr/svr-demo/pom.xml

@ -26,6 +26,10 @@
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>com.yihu.base</groupId>
            <artifactId>common-data-mysql</artifactId>

+ 88 - 1
svr/svr-demo/readme.MD

@ -1 +1,88 @@
http://localhost:8080/oauth/authorize?client_id=cwd&redirect_uri=localhost:8080&scope=all
**授权码模式:(一直开放API用)**
获取code
http://localhost:8060/oauth/authorize?response_type=code&client_id=cwd&redirect_uri=http://example.com&scope=all
获取token post请求
http://localhost:8060/oauth/token
header:  Basic {appid}:{appsecuri} 加密  例如 Basic Y3dkOmN3ZA==
  
{
     "grant_type":"authorization_code",  
     "client_id":"cwd",
     "code":"第一步请求获取的code",
     "redirect_uri":"http://example.com",
     "scope":"all"
}
返回值
{
    "access_token":"bd677e24-2de5-4862-a5e1-8f90a074db42",
    "token_type":"bearer",
    "refresh_token":"1427b997-ef94-4061-8940-c71da6549acd",
    "expires_in":43199,
    "scope":"all"
}
**密码模式(一般自己公司系统用)**
获取token post请求
http://localhost:8060/oauth/token
header:  Basic {appid}:{appsecuri} 加密  例如 Basic Y3dkOmN3ZA==
  
{
     "grant_type":"password",  
     "username":"jojo",
     "password":"123456",
     "scope":"all"
}
返回值
{
    "access_token":"630e2ccc-a5ce-4486-a855-ba755eb3d0d2",
    "token_type":"bearer",
    "refresh_token":"bbb36b54-61b2-4d86-aed3-91c5135174c3",
    "expires_in":43199,
    "scope":"all"
}
**刷新token **
获取token post请求
http://localhost:8060/oauth/token
header:  Basic {appid}:{appsecuri} 加密  例如 Basic Y3dkOmN3ZA==
  
{
     "grant_type":"refresh_token",
     "refresh_token":"all"
}
返回值
{
    "access_token":"630e2ccc-a5ce-4486-a855-ba755eb3d0d2",
    "token_type":"bearer",
    "refresh_token":"bbb36b54-61b2-4d86-aed3-91c5135174c3",
    "expires_in":43199,
    "scope":"all"
}
**自定义账号密码登陆**
POST
http://localhost:8060/authentication/form
header
Authorization  Basic Y3dkOmN3ZA==
body
{
    "username":"test",
    "password":"123456"
}
**自定义手机号短信验证码登陆**
**访问方式**
http://localhost:8060/user
header 
{
"Authorization":"bearer 5fe6b2c3-f69c-4ddc-a36a-367cdf9479a3"      即 bearer accesstoken
}

+ 2 - 0
svr/svr-demo/src/main/java/com/yihu/DemoApplication.java

@ -3,6 +3,7 @@ package com.yihu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
 * Created by chenweida on 2017/11/3.
@ -10,6 +11,7 @@ import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages={"com"})
@EnableAspectJAutoProxy(proxyTargetClass=true,exposeProxy = true)
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);

+ 2 - 1
svr/svr-demo/src/main/java/com/yihu/jw/model/MyUser.java

@ -8,7 +8,8 @@ import java.util.Collection;
/**
 * Created by chenweida on 2017/11/29.
 */
public class MyUser implements UserDetails {
public class MyUser implements UserDetails
{
    /**
     * 权限
     * @return

+ 80 - 2
svr/svr-demo/src/main/java/com/yihu/jw/model/SaasDO.java

@ -140,12 +140,18 @@ public class SaasDO implements Serializable, ClientDetails {
    @Override
    public Set<String> getAuthorizedGrantTypes() {
        return null;
        Set<String> strings = new HashSet<>();
        strings.add("password");
        strings.add("custom_password");
        strings.add("authorization_code");
        strings.add("refresh_token");
        return strings;
    }
    @Override
    public Set<String> getRegisteredRedirectUri() {
        Set<String> strings=new HashSet<>();
        Set<String> strings = new HashSet<>();
        strings.add(url);
        return strings;
    }
@ -174,4 +180,76 @@ public class SaasDO implements Serializable, ClientDetails {
    public Map<String, Object> getAdditionalInformation() {
        return null;
    }
    public String getCreateUser() {
        return createUser;
    }
    public void setCreateUser(String createUser) {
        this.createUser = createUser;
    }
    public String getCreateUserName() {
        return createUserName;
    }
    public void setCreateUserName(String createUserName) {
        this.createUserName = createUserName;
    }
    public Date getUpdateTime() {
        return updateTime;
    }
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
    public String getUpdateUser() {
        return updateUser;
    }
    public void setUpdateUser(String updateUser) {
        this.updateUser = updateUser;
    }
    public String getUpdateUserName() {
        return updateUserName;
    }
    public void setUpdateUserName(String updateUserName) {
        this.updateUserName = updateUserName;
    }
    public String getAppId() {
        return appId;
    }
    public void setAppId(String appId) {
        this.appId = appId;
    }
    public String getAppSecret() {
        return appSecret;
    }
    public void setAppSecret(String appSecret) {
        this.appSecret = appSecret;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
}

+ 29 - 9
svr/svr-demo/src/main/java/com/yihu/jw/service/ClientService.java

@ -1,27 +1,47 @@
package com.yihu.jw.service;
import com.yihu.base.security.rbas.ClientServiceProvider;
import com.yihu.jw.dao.SaasDao;
import com.yihu.jw.model.SaasDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.util.HashSet;
import java.util.Set;
/**
 * Created by chenweida on 2017/12/1.
 */
@Service
public class ClientService implements ClientDetailsService {
    @Autowired
    private SaasDao saasDao;
@Component("baseClientDetailsService")
public class ClientService implements ClientServiceProvider {
    public ClientService() {
        System.out.println("初始化");
    }
    @Override
    public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
        SaasDO saasDO = saasDao.findByAppId(clientId);
        if (saasDO == null) {
            throw new ClientRegistrationException("用户没有注册");
        }
        return saasDO;
//        SaasDO saasDO = saasDao.findByAppId(clientId);
//        if (saasDO == null) {
//            throw new ClientRegistrationException("用户没有注册");
//        }
        SaasDO baseClientDetails = new SaasDO();
        baseClientDetails.setAppId("cwd");
        baseClientDetails.setAppSecret("cwd");
        baseClientDetails.getAuthorizedGrantTypes();
        return baseClientDetails;
    }
}

+ 16 - 6
svr/svr-demo/src/main/java/com/yihu/jw/service/UserService.java

@ -1,16 +1,25 @@
package com.yihu.jw.service;
import com.sun.javafx.scene.control.skin.VirtualFlow;
import com.yihu.jw.model.MyUser;
import com.yihu.jw.model.SaasDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
 * Created by chenweida on 2017/11/29.
@ -32,17 +41,18 @@ public class UserService implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        if ("admin".equals(userName)) {
            System.out.printf("password:"+passwordEncoder.encode("123456"));
            System.out.printf("password:" + passwordEncoder.encode("123456"));
            return new User("admin",
                    "123456",
                    true,
                    passwordEncoder.encode("123456"),
                    true,
                    true,
                    true,
                    new ArrayList<>()  //权限
                    true
                    , AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_USER") //权限
            );
        } else {
            throw new UsernameNotFoundException("用户不存在");
        }
    }
}

+ 2 - 1
svr/svr-demo/src/main/resources/application.yml

@ -32,7 +32,8 @@ spring:
    port: 6379 # Redis server port.
    database: 1
  aop:
    proxy-target-class: true
quartz:

+ 1 - 26
svr/svr-demo/src/main/resources/resources/denglu.html

@ -7,7 +7,7 @@
<body>
	<h2>标准登录页面</h2>
	<h3>表单登录</h3>
	<form action="/authentication/form" method="post">
<form action="/authentication/form" method="post">
		<table>
			<tr>
				<td>用户名:</td> 
@ -32,30 +32,5 @@
			</tr>
		</table>
	</form>
	
	<h3>短信登录</h3>
	<form action="/authentication/mobile" method="post">
		<table>
			<tr>
				<td>手机号:</td>
				<td><input type="text" name="mobile" value="13012345678"></td>
			</tr>
			<tr>
				<td>短信验证码:</td>
				<td>
					<input type="text" name="smsCode">
					<a href="/code/sms?mobile=13012345678">发送验证码</a>
				</td>
			</tr>
			<tr>
				<td colspan="2"><button type="submit">登录</button></td>
			</tr>
		</table>
	</form>
	<br>
	<h3>社交登录</h3>
	<a href="/qqLogin/callback.do">QQ登录</a>
	&nbsp;&nbsp;&nbsp;&nbsp;
	<a href="/qqLogin/weixin">微信登录</a>
</body>
</html>