Browse Source

init from phab

xielq 4 years ago
parent
commit
20f8294e81
37 changed files with 1645 additions and 0 deletions
  1. 0 0
      README.md
  2. 48 0
      build.gradle
  3. 40 0
      gradle/docker.gradle
  4. 78 0
      gradle/publish.gradle
  5. 61 0
      gradle/service-base.gradle
  6. 2 0
      settings.gradle
  7. 21 0
      src/main/java/com/uas/cloud/oauth2/OAuth2Application.java
  8. 48 0
      src/main/java/com/uas/cloud/oauth2/config/AuthenticationConfiguration.java
  9. 34 0
      src/main/java/com/uas/cloud/oauth2/config/CacheConfiguration.java
  10. 53 0
      src/main/java/com/uas/cloud/oauth2/config/OAuth2ServerConfiguration.java
  11. 13 0
      src/main/java/com/uas/cloud/oauth2/config/SessionConfiguration.java
  12. 20 0
      src/main/java/com/uas/cloud/oauth2/config/WebMvcConfiguration.java
  13. 62 0
      src/main/java/com/uas/cloud/oauth2/config/WebSecurityConfiguration.java
  14. 35 0
      src/main/java/com/uas/cloud/oauth2/core/SaltedUser.java
  15. 83 0
      src/main/java/com/uas/cloud/oauth2/entity/OAuth2Account.java
  16. 36 0
      src/main/java/com/uas/cloud/oauth2/entity/OAuth2AccountId.java
  17. 155 0
      src/main/java/com/uas/cloud/oauth2/entity/OAuth2Client.java
  18. 72 0
      src/main/java/com/uas/cloud/oauth2/entity/OAuth2ClientScope.java
  19. 36 0
      src/main/java/com/uas/cloud/oauth2/entity/OAuth2ClientScopeId.java
  20. 86 0
      src/main/java/com/uas/cloud/oauth2/entity/OAuth2Scope.java
  21. 95 0
      src/main/java/com/uas/cloud/oauth2/entity/UserAccount.java
  22. 116 0
      src/main/java/com/uas/cloud/oauth2/entity/UserCredential.java
  23. 123 0
      src/main/java/com/uas/cloud/oauth2/entity/UserProfile.java
  24. 42 0
      src/main/java/com/uas/cloud/oauth2/provider/JpaClientDetailsService.java
  25. 50 0
      src/main/java/com/uas/cloud/oauth2/provider/JpaUserDetailsService.java
  26. 13 0
      src/main/java/com/uas/cloud/oauth2/repository/OAuth2AccountRepository.java
  27. 12 0
      src/main/java/com/uas/cloud/oauth2/repository/OAuth2ClientRepository.java
  28. 13 0
      src/main/java/com/uas/cloud/oauth2/repository/OAuth2ClientScopeRepository.java
  29. 21 0
      src/main/java/com/uas/cloud/oauth2/repository/OAuth2ScopeRepository.java
  30. 14 0
      src/main/java/com/uas/cloud/oauth2/repository/UserAccountRepository.java
  31. 14 0
      src/main/java/com/uas/cloud/oauth2/repository/UserCredentialRepository.java
  32. 12 0
      src/main/java/com/uas/cloud/oauth2/repository/UserProfileRepository.java
  33. 19 0
      src/main/java/com/uas/cloud/oauth2/user/UserController.java
  34. 26 0
      src/main/resources/application.yml
  35. 40 0
      src/main/resources/templates/authorize.html
  36. 20 0
      src/main/resources/templates/index.html
  37. 32 0
      src/main/resources/templates/login.html

+ 0 - 0
README.md


+ 48 - 0
build.gradle

@@ -0,0 +1,48 @@
+apply from: "$rootDir/gradle/service-base.gradle"
+apply from: "$rootDir/gradle/publish.gradle"
+apply from: "$rootDir/gradle/docker.gradle"
+
+group 'com.uas.cloud.base'
+version '0.1.0'
+
+ext {
+    baseName = 'base-oauth2-service'
+    artifactId = 'base-oauth2-service'
+}
+
+jar {
+    baseName = "${baseName}"
+    version = "${version}"
+}
+
+dependencies {
+    compile 'org.springframework.boot:spring-boot-starter-data-jpa'
+    compile 'org.springframework.boot:spring-boot-starter-security'
+    compile 'org.springframework.cloud:spring-cloud-starter-oauth2'
+    compile 'org.springframework.boot:spring-boot-starter-web'
+    compile 'org.springframework.boot:spring-boot-starter-data-rest'
+    compile 'org.springframework.cloud:spring-cloud-starter-hystrix'
+//    compile 'org.springframework.boot:spring-boot-starter-freemarker'
+    compile 'org.springframework.boot:spring-boot-starter-thymeleaf'
+    compile 'org.springframework.boot:spring-boot-starter-redis'
+    compile 'org.springframework.session:spring-session-data-redis'
+    compile 'org.hibernate:hibernate-java8'
+
+//    compile 'com.h2database:h2'
+//    runtime 'mysql:mysql-connector-java'
+    compile "com.oracle:ojdbc6:11.2.0"
+    compile "com.alibaba:fastjson:1.2.14"
+
+    compile 'joda-time:joda-time'
+    compile 'com.google.code.gson:gson'
+
+    // 静态文件作为依赖虽然能够简洁源码,但是不方便静态页面调试,所以不采用这种方式。而且编写前端页面时也没有代码提示
+    // 静态文件
+//    compile 'org.webjars:angularjs:1.4.3'
+//    compile 'org.webjars:jquery:2.1.1'
+//    compile 'org.webjars:bootstrap:3.2.0'
+//    compile 'org.webjars:webjars-locator'
+
+    // 后续需要使用插件把改以来改为 optional, 而不是 compile
+    compile 'org.springframework.boot:spring-boot-configuration-processor'
+}

+ 40 - 0
gradle/docker.gradle

@@ -0,0 +1,40 @@
+buildscript {
+    ext {
+        springBootVersion = '1.4.4.RELEASE'
+    }
+    repositories {
+        maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
+        mavenCentral()
+        jcenter()
+    }
+    dependencies {
+        classpath('se.transmode.gradle:gradle-docker:1.2')
+    }
+}
+
+//apply plugin: 'docker'
+apply plugin: se.transmode.gradle.plugins.docker.DockerPlugin
+
+// 这里产生的镜像的标签会和 project。group一样,暂未找到解决办法
+// tag = "${project.group}/${applicationName}:${tagVersion}"
+task buildDocker(type:Docker, dependsOn: build) {
+    push = true
+//    applicationName = jar.baseName
+
+    tag = "10.10.100.200:5000/${jar.baseName}"
+    dockerfile = file('src/main/docker/Dockerfile')
+    doFirst {
+        copy {
+            from jar
+            into stageDir
+        }
+    }
+}
+
+docker {
+    hostUrl 'https://192.168.99.100:2376' // set the URL used to contact the Docker server. Defaults to http://localhost:2375
+    dockerBinary 'C:\\Program Files\\Docker Toolbox\\docker.exe'
+    useApi false // Use the Docker Remote API instead of a locally installed docker binary.
+    maintainer  'yingp@usoftchina.com'// The name and email address of the image maintainer.
+    registry '10.10.100.200:5000' // The hostname and port of the Docker image registry unless the Docker Hub Registry is used.
+}

+ 78 - 0
gradle/publish.gradle

@@ -0,0 +1,78 @@
+task sourcesJar(type: Jar) {
+    baseName "${baseName}"
+    classifier 'sources'
+    from sourceSets.main.allSource
+}
+artifacts {
+    archives sourcesJar
+}
+
+apply plugin: 'distribution'
+
+distributions {
+    main {
+        baseName = archivesBaseName
+
+        contents {
+            from { libsDir }
+        }
+    }
+
+    docs {
+        baseName = "$archivesBaseName-docs"
+
+        contents {
+            from(libsDir) {
+                include sourcesJar.archiveName
+            }
+        }
+    }
+}
+
+ext {
+    artifactoryBaseUrl = 'http://113.105.74.141:8081/artifactory'
+    artifactorySnapshotRepoUrl = "$artifactoryBaseUrl/libs-snapshot-local"
+    artifactoryReleaseRepoUrl = "$artifactoryBaseUrl/libs-release-local"
+}
+
+apply plugin: 'maven-publish'
+
+publishing {
+    publications {
+        plugin(MavenPublication) {
+            from components.java
+            artifactId "${artifactId}"
+
+            pom.withXml {
+                def root = asNode()
+                root.appendNode('name', 'base-OAuth2-service')
+                root.appendNode('description', '用户授权服务')
+                root.appendNode('inceptionYear', '2017')
+
+                def developer = root.appendNode('developers').appendNode('developer')
+                developer.appendNode('id', 'yingp')
+                developer.appendNode('name', '应鹏')
+                developer.appendNode('email', 'yingp@usoftchina.com')
+            }
+
+            artifact sourcesJar
+        }
+    }
+
+    repositories {
+        maven {
+            name 'myLocal'
+            url "file://$projectDir/repo"
+        }
+
+        maven {
+            name 'remoteArtifactory'
+            url project.version.endsWith('-SNAPSHOT') ? artifactorySnapshotRepoUrl : artifactoryReleaseRepoUrl
+
+            credentials {
+                username = 'yingp'
+                password = '111111'
+            }
+        }
+    }
+}

+ 61 - 0
gradle/service-base.gradle

@@ -0,0 +1,61 @@
+buildscript {
+    ext {
+        springBootVersion = '1.4.4.RELEASE'
+    }
+    repositories {
+        maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
+        mavenCentral()
+        jcenter()
+    }
+    dependencies {
+        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
+    }
+}
+
+apply plugin: 'idea'
+apply plugin: 'eclipse'
+apply plugin: 'java'
+//apply plugin: 'spring-boot'
+apply plugin: org.springframework.boot.gradle.plugin.SpringBootPlugin // applying a plugin by plugin id is not supported in script plugins. You must use the plugin's fully qualified class name.
+sourceCompatibility = 1.8 // 必须在apply java插件之后
+targetCompatibility = 1.8
+
+bootRun {
+    addResources = true
+}
+idea {
+    module {
+        downloadSources = true
+        downloadJavadoc = false
+        inheritOutputDirs = false
+        outputDir = file("$buildDir/classes/main/")
+    }
+}
+
+repositories {
+    mavenLocal()
+    maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
+    maven {
+        url 'http://10.10.101.21:8081/artifactory/libs-release'
+    }
+    maven {
+        url 'http://10.10.101.21:8081/artifactory/libs-snapshot'
+    }
+    maven {
+        url 'http://10.10.101.21:8081/artifactory/plugins-snapshot'
+    }
+    mavenCentral()
+}
+
+dependencyManagement {
+    imports {
+        mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Camden.SR5'
+    }
+}
+dependencies {
+    testCompile 'org.springframework.boot:spring-boot-starter-test'
+    compile 'org.springframework.cloud:spring-cloud-starter-config'
+    compile 'org.springframework.boot:spring-boot-devtools'
+    compile 'org.springframework.cloud:spring-cloud-starter-eureka'
+
+}

+ 2 - 0
settings.gradle

@@ -0,0 +1,2 @@
+rootProject.name = 'base-oauth2-service'
+

+ 21 - 0
src/main/java/com/uas/cloud/oauth2/OAuth2Application.java

@@ -0,0 +1,21 @@
+package com.uas.cloud.oauth2;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+@SpringBootApplication
+@EnableJpaAuditing
+@EnableDiscoveryClient
+public class OAuth2Application {
+
+    public static void main(String[] args) {
+        SpringApplication.run(OAuth2Application.class, args);
+    }
+
+}

+ 48 - 0
src/main/java/com/uas/cloud/oauth2/config/AuthenticationConfiguration.java

@@ -0,0 +1,48 @@
+package com.uas.cloud.oauth2.config;
+
+import com.uas.cloud.oauth2.provider.JpaUserDetailsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+import org.springframework.security.authentication.dao.ReflectionSaltSource;
+import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+@Configuration
+public class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {
+
+    @Autowired
+    private JpaUserDetailsService userDetailsService;
+
+    @Bean
+    public Md5PasswordEncoder passwordEncoder() {
+        return new Md5PasswordEncoder();
+    }
+
+    @Bean
+    public ReflectionSaltSource saltSource() {
+        ReflectionSaltSource saltSource = new ReflectionSaltSource();
+        saltSource.setUserPropertyToUse("salt");
+        return saltSource;
+    }
+
+    @Bean
+    public DaoAuthenticationProvider authenticationProvider(){
+        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
+        authenticationProvider.setUserDetailsService(userDetailsService);
+        authenticationProvider.setPasswordEncoder(passwordEncoder());
+        authenticationProvider.setSaltSource(saltSource());
+        return authenticationProvider;
+    }
+
+    @Override
+    public void init(AuthenticationManagerBuilder auth) throws Exception {
+        auth.authenticationProvider(authenticationProvider());
+    }
+
+}

+ 34 - 0
src/main/java/com/uas/cloud/oauth2/config/CacheConfiguration.java

@@ -0,0 +1,34 @@
+package com.uas.cloud.oauth2.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+@Configuration
+@EnableCaching
+public class CacheConfiguration {
+
+    @Bean
+    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
+        RedisTemplate redisTemplate = new RedisTemplate();
+        redisTemplate.setConnectionFactory(factory);
+        return redisTemplate;
+    }
+
+    @Bean
+    public CacheManager cacheManager(RedisTemplate redisTemplate) {
+        RedisCacheManager cacheManager = new RedisCacheManager((redisTemplate));
+        cacheManager.setDefaultExpiration(10000); // 10000s后过期
+        return cacheManager;
+    }
+
+}

+ 53 - 0
src/main/java/com/uas/cloud/oauth2/config/OAuth2ServerConfiguration.java

@@ -0,0 +1,53 @@
+package com.uas.cloud.oauth2.config;
+
+import com.uas.cloud.oauth2.provider.JpaClientDetailsService;
+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.token.TokenStore;
+import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+@Configuration
+@EnableAuthorizationServer
+public class OAuth2ServerConfiguration extends AuthorizationServerConfigurerAdapter {
+
+    @Autowired
+    private AuthenticationManager authenticationManager;
+    @Autowired
+    private RedisConnectionFactory redisConnectionFactory;
+    @Autowired
+    private JpaClientDetailsService clientDetailsService;
+
+    @Bean
+    public TokenStore tokenStore() {
+        return new RedisTokenStore(redisConnectionFactory);
+    }
+
+    @Override
+    public void configure(AuthorizationServerEndpointsConfigurer configurer) throws Exception {
+        configurer.authenticationManager(authenticationManager).tokenStore(tokenStore());
+    }
+
+    @Override
+    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
+        security.allowFormAuthenticationForClients()
+                .tokenKeyAccess("permitAll()")
+                .checkTokenAccess("isAuthenticated()");
+    }
+
+    @Override
+    public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
+        configurer.withClientDetails(clientDetailsService);
+    }
+
+}

+ 13 - 0
src/main/java/com/uas/cloud/oauth2/config/SessionConfiguration.java

@@ -0,0 +1,13 @@
+package com.uas.cloud.oauth2.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
+
+/**
+ * Created by Pro1 on 2017/3/23.
+ */
+@Configuration
+@EnableRedisHttpSession
+public class SessionConfiguration {
+
+}

+ 20 - 0
src/main/java/com/uas/cloud/oauth2/config/WebMvcConfiguration.java

@@ -0,0 +1,20 @@
+package com.uas.cloud.oauth2.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+@Configuration
+public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
+
+    @Override
+    public void addViewControllers(ViewControllerRegistry registry) {
+        registry.addViewController("/").setViewName("index");
+        registry.addViewController("/login").setViewName("login");
+        registry.addViewController("/oauth/confirm_access").setViewName("authorize");
+    }
+
+}

+ 62 - 0
src/main/java/com/uas/cloud/oauth2/config/WebSecurityConfiguration.java

@@ -0,0 +1,62 @@
+package com.uas.cloud.oauth2.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
+import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+@Configuration
+@EnableResourceServer
+@EnableWebSecurity
+@Order(-20)
+public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
+
+    @Bean
+    @Override
+    public AuthenticationManager authenticationManagerBean() throws Exception {
+        return super.authenticationManagerBean();
+    }
+
+    @Bean
+    public AuthenticationSuccessHandler authenticationSuccessHandler() {
+        return new AuthenticationSuccessHandler() {
+            @Override
+            public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
+
+            }
+        };
+    }
+
+    @Override
+    public void configure(HttpSecurity http) throws Exception {
+        http.formLogin()
+                .loginPage("/login")
+                .successHandler(authenticationSuccessHandler())
+                .permitAll()
+                .and()
+                .requestMatchers()
+                .antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
+                .and()
+                .authorizeRequests()
+                .anyRequest()
+                .authenticated()
+                .antMatchers("/resources/**").permitAll();
+    }
+
+}

+ 35 - 0
src/main/java/com/uas/cloud/oauth2/core/SaltedUser.java

@@ -0,0 +1,35 @@
+package com.uas.cloud.oauth2.core;
+
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.User;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Created by Pro1 on 2017/3/23.
+ */
+public class SaltedUser extends User implements Serializable{
+
+    private String salt;
+
+    public SaltedUser(String username, String password,
+                      boolean enabled,
+                      boolean accountNonExpired, boolean credentialsNonExpired,
+                      boolean accountNonLocked, List<GrantedAuthority>
+                              authorities, String salt) {
+        super(username, password, enabled,
+                accountNonExpired, credentialsNonExpired,
+                accountNonLocked, authorities);
+        this.salt = salt;
+    }
+
+    public String getSalt() {
+        return salt;
+    }
+
+    public void setSalt(String salt) {
+        this.salt = salt;
+    }
+
+}

+ 83 - 0
src/main/java/com/uas/cloud/oauth2/entity/OAuth2Account.java

@@ -0,0 +1,83 @@
+package com.uas.cloud.oauth2.entity;
+
+import javax.persistence.*;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+@Entity
+@IdClass(OAuth2AccountId.class)
+@Table(name = "oauth2_accounts")
+public class OAuth2Account {
+
+    @Id
+    @Column(name = "oauth2_client_id", length = 32)
+    private String oauth2ClientId;
+
+    @Id
+    @Column(name = "user_account_id")
+    private Long userAccountId;
+
+    @Column(name = "open_id", nullable = false, length = 32)
+    private String openId;
+
+    @Column(name = "authorities", length = 256)
+    private String authorities;
+
+    @ManyToOne(fetch = FetchType.LAZY, optional = false)
+    @JoinColumn(name = "oauth2_client_id", insertable = false, updatable = false, nullable = false)
+    private OAuth2Client client;
+
+    @ManyToOne(fetch = FetchType.LAZY, optional = false)
+    @JoinColumn(name = "user_account_id", insertable = false, updatable = false, nullable = false)
+    private UserAccount userAccount;
+
+    public String getOauth2ClientId() {
+        return oauth2ClientId;
+    }
+
+    public void setOauth2ClientId(String oauth2ClientId) {
+        this.oauth2ClientId = oauth2ClientId;
+    }
+
+    public Long getUserAccountId() {
+        return userAccountId;
+    }
+
+    public void setUserAccountId(Long userAccountId) {
+        this.userAccountId = userAccountId;
+    }
+
+    public String getOpenId() {
+        return openId;
+    }
+
+    public void setOpenId(String openId) {
+        this.openId = openId;
+    }
+
+    public String getAuthorities() {
+        return authorities;
+    }
+
+    public void setAuthorities(String authorities) {
+        this.authorities = authorities;
+    }
+
+    public OAuth2Client getClient() {
+        return client;
+    }
+
+    public void setClient(OAuth2Client client) {
+        this.client = client;
+    }
+
+    public UserAccount getUserAccount() {
+        return userAccount;
+    }
+
+    public void setUserAccount(UserAccount userAccount) {
+        this.userAccount = userAccount;
+    }
+
+}

+ 36 - 0
src/main/java/com/uas/cloud/oauth2/entity/OAuth2AccountId.java

@@ -0,0 +1,36 @@
+package com.uas.cloud.oauth2.entity;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+public class OAuth2AccountId implements Serializable {
+
+    private Long oauth2ClientId;
+    private Long userAccountId;
+
+    public OAuth2AccountId() {
+    }
+
+    public OAuth2AccountId(Long oauth2ClientId, Long userAccountId) {
+        this.oauth2ClientId = oauth2ClientId;
+        this.userAccountId = userAccountId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        OAuth2AccountId that = (OAuth2AccountId) o;
+        return Objects.equals(oauth2ClientId, that.oauth2ClientId) &&
+                Objects.equals(userAccountId, that.userAccountId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(oauth2ClientId, userAccountId);
+    }
+
+}

+ 155 - 0
src/main/java/com/uas/cloud/oauth2/entity/OAuth2Client.java

@@ -0,0 +1,155 @@
+package com.uas.cloud.oauth2.entity;
+
+import javax.persistence.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.UUID;
+
+/**
+ * 客户端(即第三方应用)
+ * Created by Pro1 on 2017/3/22.
+ */
+@Entity
+@Table(name = "oauth2_clients")
+public class OAuth2Client {
+
+    @Id
+    @Column(name = "id", length = 32)
+    private String id;
+
+    @Column(name = "secret", nullable = false, length = 32)
+    private String secret;
+
+    @Column(name = "name", nullable = false, length = 32)
+    private String name;
+
+    @Column(name = "resource_ids", length = 256)
+    private String resourceIds;
+
+    @Column(name = "authorities", length = 256)
+    private String authorities;
+
+    @Column(name = "grant_types", length = 256)
+    private String grantTypes;
+
+    @Column(name = "redirect_uris", length = 256)
+    private String redirectUris;
+
+    @Column(name = "access_token_validity")
+    private Integer accessTokenValidity;
+
+    @Column(name = "refresh_token_validity")
+    private Integer refreshTokenValidity;
+
+    @OneToMany(fetch = FetchType.LAZY, mappedBy = "client")
+    private Collection<OAuth2Account> accounts = new ArrayList<OAuth2Account>();
+
+    @OneToMany(fetch = FetchType.LAZY, mappedBy = "client")
+    private Collection<OAuth2ClientScope> clientScopes;
+
+    /**
+     * 如"mall-home-app"
+     * @return
+     */
+    public String getId() {
+        return id;
+    }
+
+    private void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * 私钥
+     * @return
+     */
+    public String getSecret() {
+        return secret;
+    }
+
+    private void setSecret(String secret) {
+        this.secret = secret;
+    }
+
+    /**
+     * 应用名,如"商城首页"
+     * @return
+     */
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getResourceIds() {
+        return resourceIds;
+    }
+
+    public void setResourceIds(String resourceIds) {
+        this.resourceIds = resourceIds;
+    }
+
+    public String getAuthorities() {
+        return authorities;
+    }
+
+    public void setAuthorities(String authorities) {
+        this.authorities = authorities;
+    }
+
+    /**
+     * 授权方式:authorization_code,refresh_token,client_credentials,password
+     * @return
+     */
+    public String getGrantTypes() {
+        return grantTypes;
+    }
+
+    public void setGrantTypes(String grantTypes) {
+        this.grantTypes = grantTypes;
+    }
+
+    /**
+     * 跳转地址:应用首页或用户个人主页
+     * @return
+     */
+    public String getRedirectUris() {
+        return redirectUris;
+    }
+
+    public void setRedirectUris(String redirectUris) {
+        this.redirectUris = redirectUris;
+    }
+
+    public Integer getAccessTokenValidity() {
+        return accessTokenValidity;
+    }
+
+    public void setAccessTokenValidity(Integer accessTokenValidity) {
+        this.accessTokenValidity = accessTokenValidity;
+    }
+
+    public Integer getRefreshTokenValidity() {
+        return refreshTokenValidity;
+    }
+
+    public void setRefreshTokenValidity(Integer refreshTokenValidity) {
+        this.refreshTokenValidity = refreshTokenValidity;
+    }
+
+    public Collection<OAuth2Account> getAccounts() {
+        return accounts;
+    }
+
+    public void setAccounts(Collection<OAuth2Account> accounts) {
+        this.accounts = accounts;
+    }
+
+    @PrePersist
+    public void prePersist() {
+        this.setId(UUID.randomUUID().toString());
+        this.setSecret(UUID.randomUUID().toString());
+    }
+}

+ 72 - 0
src/main/java/com/uas/cloud/oauth2/entity/OAuth2ClientScope.java

@@ -0,0 +1,72 @@
+package com.uas.cloud.oauth2.entity;
+
+import javax.persistence.*;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+@Entity
+@IdClass(OAuth2ClientScopeId.class)
+@Table(name = "oauth2_client_scopes")
+public class OAuth2ClientScope {
+
+    @Id
+    @Column(name = "client_id", length = 32)
+    private String clientId;
+
+    @Id
+    @Column(name = "scope_id")
+    private Long scopeId;
+
+    @Column(name = "auto_approve")
+    private Boolean autoApprove;
+
+    @ManyToOne(fetch = FetchType.LAZY, optional = false)
+    @JoinColumn(name = "client_id", insertable = false, updatable = false, nullable = false)
+    private OAuth2Client client;
+
+    @ManyToOne(fetch = FetchType.LAZY, optional = false)
+    @JoinColumn(name = "scope_id", insertable = false, updatable = false, nullable = false)
+    private OAuth2Scope scope;
+
+    public String getClientId() {
+        return clientId;
+    }
+
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    public Long getScopeId() {
+        return scopeId;
+    }
+
+    public void setScopeId(Long scopeId) {
+        this.scopeId = scopeId;
+    }
+
+    public Boolean getAutoApprove() {
+        return autoApprove;
+    }
+
+    public void setAutoApprove(Boolean autoApprove) {
+        this.autoApprove = autoApprove;
+    }
+
+    public OAuth2Client getClient() {
+        return client;
+    }
+
+    public void setClient(OAuth2Client client) {
+        this.client = client;
+    }
+
+    public OAuth2Scope getScope() {
+        return scope;
+    }
+
+    public void setScope(OAuth2Scope scope) {
+        this.scope = scope;
+    }
+
+}

+ 36 - 0
src/main/java/com/uas/cloud/oauth2/entity/OAuth2ClientScopeId.java

@@ -0,0 +1,36 @@
+package com.uas.cloud.oauth2.entity;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+public class OAuth2ClientScopeId implements Serializable {
+
+    private String clientId;
+    private String scopeId;
+
+    public OAuth2ClientScopeId() {
+    }
+
+    public OAuth2ClientScopeId(String clientId, String scopeId) {
+        this.clientId = clientId;
+        this.scopeId = scopeId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        OAuth2ClientScopeId that = (OAuth2ClientScopeId) o;
+        return Objects.equals(clientId, that.clientId) &&
+                Objects.equals(scopeId, that.scopeId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(clientId, scopeId);
+    }
+
+}

+ 86 - 0
src/main/java/com/uas/cloud/oauth2/entity/OAuth2Scope.java

@@ -0,0 +1,86 @@
+package com.uas.cloud.oauth2.entity;
+
+import javax.persistence.*;
+import java.util.Collection;
+
+/**
+ * 权限范围
+ * Created by Pro1 on 2017/3/22.
+ */
+@Entity
+@Table(name = "oauth2_scopes", uniqueConstraints = {
+        @UniqueConstraint(columnNames = {"scope_key", "client_id"}),
+        @UniqueConstraint(columnNames = {"scope_name", "client_id"})
+})
+public class OAuth2Scope {
+
+    @Id
+    @Column(name = "id")
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Column(name = "scope_key", nullable = false, length = 64)
+    private String key;
+
+    @Column(name = "scope_name", length = 64)
+    private String name;
+
+    @Column(name = "client_id", nullable = false, length = 32)
+    private String clientId;
+
+    @ManyToOne(fetch = FetchType.LAZY, optional = false)
+    @JoinColumn(name = "client_id", insertable = false, updatable = false, nullable = false)
+    private OAuth2Client client;
+
+    @OneToMany(fetch = FetchType.LAZY, mappedBy = "scope")
+    private Collection<OAuth2ClientScope> clientScopes;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getClientId() {
+        return clientId;
+    }
+
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    public OAuth2Client getClient() {
+        return client;
+    }
+
+    public void setClient(OAuth2Client client) {
+        this.client = client;
+    }
+
+    public Collection<OAuth2ClientScope> getClientScopes() {
+        return clientScopes;
+    }
+
+    public void setClientScopes(Collection<OAuth2ClientScope> clientScopes) {
+        this.clientScopes = clientScopes;
+    }
+
+}

+ 95 - 0
src/main/java/com/uas/cloud/oauth2/entity/UserAccount.java

@@ -0,0 +1,95 @@
+package com.uas.cloud.oauth2.entity;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * 用户账户
+ * Created by Pro1 on 2017/3/22.
+ */
+@Entity
+@Table(name = "user_accounts")
+public class UserAccount {
+
+    @Id
+    @Column(name = "id")
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Column(name = "expires_at")
+    private LocalDateTime expiresAt;
+
+    @Column(name = "locked", nullable = false)
+    private boolean locked;
+
+    @Column(name = "disabled", nullable = false)
+    private boolean disabled;
+
+    @OneToOne(fetch = FetchType.LAZY)
+    @PrimaryKeyJoinColumn
+    private UserProfile profile;
+
+    @OneToMany(fetch = FetchType.LAZY, mappedBy = "account")
+    private Collection<UserCredential> credentials = new ArrayList<UserCredential>();
+
+    @OneToMany(fetch = FetchType.LAZY, mappedBy = "userAccount")
+    private Collection<OAuth2Account> oAuth2Accounts = new ArrayList<OAuth2Account>();
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public LocalDateTime getExpiresAt() {
+        return expiresAt;
+    }
+
+    public void setExpiresAt(LocalDateTime expiresAt) {
+        this.expiresAt = expiresAt;
+    }
+
+    public boolean isLocked() {
+        return locked;
+    }
+
+    public void setLocked(boolean locked) {
+        this.locked = locked;
+    }
+
+    public boolean isDisabled() {
+        return disabled;
+    }
+
+    public void setDisabled(boolean disabled) {
+        this.disabled = disabled;
+    }
+
+    public UserProfile getProfile() {
+        return profile;
+    }
+
+    public void setProfile(UserProfile profile) {
+        this.profile = profile;
+    }
+
+    public Collection<UserCredential> getCredentials() {
+        return credentials;
+    }
+
+    public void setCredentials(Collection<UserCredential> credentials) {
+        this.credentials = credentials;
+    }
+
+    public Collection<OAuth2Account> getoAuth2Accounts() {
+        return oAuth2Accounts;
+    }
+
+    public void setoAuth2Accounts(Collection<OAuth2Account> oAuth2Accounts) {
+        this.oAuth2Accounts = oAuth2Accounts;
+    }
+}

+ 116 - 0
src/main/java/com/uas/cloud/oauth2/entity/UserCredential.java

@@ -0,0 +1,116 @@
+package com.uas.cloud.oauth2.entity;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+/**
+ * 用户凭据
+ * Created by Pro1 on 2017/3/22.
+ */
+@Entity
+@Table(name = "user_credentials")
+public class UserCredential {
+
+    @Id
+    @Column(name = "id")
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Column(name = "provider_key", nullable = false, length = 128)
+    private String providerKey;
+
+    @Column(name = "user_key", unique = true, nullable = false, length = 256)
+    private String userKey;
+
+    @Column(name = "secret_code", length = 256)
+    private String secretCode;
+
+    @Column(name = "salt", length = 128)
+    private String salt;
+
+    @Column(name = "expires_at")
+    private LocalDateTime expiresAt;
+
+    @Column(name = "account_id", nullable = false)
+    private Long accountId;
+
+    @ManyToOne(fetch = FetchType.LAZY, optional = false)
+    @JoinColumn(name = "account_id", insertable = false, updatable = false, nullable = false)
+    private UserAccount account;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getProviderKey() {
+        return providerKey;
+    }
+
+    public void setProviderKey(String providerKey) {
+        this.providerKey = providerKey;
+    }
+
+    /**
+     * @return 用户名:账户ID、手机号、邮箱
+     */
+    public String getUserKey() {
+        return userKey;
+    }
+
+    public void setUserKey(String userKey) {
+        this.userKey = userKey;
+    }
+
+    /**
+     * @return 密码密文
+     */
+    public String getSecretCode() {
+        return secretCode;
+    }
+
+    public void setSecretCode(String secretCode) {
+        this.secretCode = secretCode;
+    }
+
+    /**
+     * @return 过期时间
+     */
+    public LocalDateTime getExpiresAt() {
+        return expiresAt;
+    }
+
+    public void setExpiresAt(LocalDateTime expiresAt) {
+        this.expiresAt = expiresAt;
+    }
+
+    public Long getAccountId() {
+        return accountId;
+    }
+
+    public void setAccountId(Long accountId) {
+        this.accountId = accountId;
+    }
+
+    public UserAccount getAccount() {
+        return account;
+    }
+
+    public void setAccount(UserAccount account) {
+        this.account = account;
+    }
+
+    /**
+     * @return 密码加密盐值
+     */
+    public String getSalt() {
+        return salt;
+    }
+
+    public void setSalt(String salt) {
+        this.salt = salt;
+    }
+}

+ 123 - 0
src/main/java/com/uas/cloud/oauth2/entity/UserProfile.java

@@ -0,0 +1,123 @@
+package com.uas.cloud.oauth2.entity;
+
+import javax.persistence.*;
+import java.time.LocalDate;
+
+/**
+ * 用户信息
+ * Created by Pro1 on 2017/3/22.
+ */
+@Entity
+@Table(name = "user_profiles")
+public class UserProfile {
+    @Id
+    @Column(name = "id")
+    private Long id;
+
+    @Column(name = "name", nullable = false, length = 64)
+    private String name;
+
+    @Column(name = "gender", length = 32)
+    private String gender;
+
+    @Column(name = "birthday")
+    private LocalDate birthday;
+
+    @Column(name = "telephone", length = 64)
+    private String telephone;
+
+    @Column(name = "mobile", length = 64)
+    private String mobile;
+
+    @Column(name = "email", length = 128)
+    private String email;
+
+    @OneToOne(fetch = FetchType.LAZY, optional = false)
+    @PrimaryKeyJoinColumn
+    private UserAccount account;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * 性别
+     * @return
+     */
+    public String getGender() {
+        return gender;
+    }
+
+    public void setGender(String gender) {
+        this.gender = gender;
+    }
+
+    /**
+     * 出生日期
+     * @return
+     */
+    public LocalDate getBirthday() {
+        return birthday;
+    }
+
+    public void setBirthday(LocalDate birthday) {
+        this.birthday = birthday;
+    }
+
+    /**
+     * 电话
+     * @return
+     */
+    public String getTelephone() {
+        return telephone;
+    }
+
+    public void setTelephone(String telephone) {
+        this.telephone = telephone;
+    }
+
+    /**
+     * 手机号
+     * @return
+     */
+    public String getMobile() {
+        return mobile;
+    }
+
+    public void setMobile(String mobile) {
+        this.mobile = mobile;
+    }
+
+    /**
+     * 邮箱
+     * @return
+     */
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public UserAccount getAccount() {
+        return account;
+    }
+
+    public void setAccount(UserAccount account) {
+        this.account = account;
+    }
+
+}

+ 42 - 0
src/main/java/com/uas/cloud/oauth2/provider/JpaClientDetailsService.java

@@ -0,0 +1,42 @@
+package com.uas.cloud.oauth2.provider;
+
+import com.uas.cloud.oauth2.entity.OAuth2Client;
+import com.uas.cloud.oauth2.repository.OAuth2ClientRepository;
+import com.uas.cloud.oauth2.repository.OAuth2ScopeRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+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.BaseClientDetails;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+@Component
+public class JpaClientDetailsService implements ClientDetailsService {
+
+    private final OAuth2ClientRepository oAuth2ClientRepository;
+    private final OAuth2ScopeRepository oAuth2ScopeRepository;
+
+    @Autowired
+    public JpaClientDetailsService(OAuth2ClientRepository oAuth2ClientRepository, OAuth2ScopeRepository oAuth2ScopeRepository) {
+        this.oAuth2ClientRepository = oAuth2ClientRepository;
+        this.oAuth2ScopeRepository = oAuth2ScopeRepository;
+    }
+
+    public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
+        OAuth2Client oAuth2Client = oAuth2ClientRepository.findOne(clientId);
+        BaseClientDetails clientDetails = new BaseClientDetails(
+                oAuth2Client.getId(),
+                oAuth2Client.getResourceIds(),
+                null,
+                oAuth2Client.getGrantTypes(),
+                oAuth2Client.getAuthorities(),
+                oAuth2Client.getRedirectUris()
+        );
+        clientDetails.setClientSecret(oAuth2Client.getSecret());
+        clientDetails.setScope(oAuth2ScopeRepository.findScopeKeysByClientId(clientId));
+        return clientDetails;
+    }
+}

+ 50 - 0
src/main/java/com/uas/cloud/oauth2/provider/JpaUserDetailsService.java

@@ -0,0 +1,50 @@
+package com.uas.cloud.oauth2.provider;
+
+import com.uas.cloud.oauth2.core.SaltedUser;
+import com.uas.cloud.oauth2.entity.UserAccount;
+import com.uas.cloud.oauth2.entity.UserCredential;
+import com.uas.cloud.oauth2.repository.UserAccountRepository;
+import com.uas.cloud.oauth2.repository.UserCredentialRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.util.Collections;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+@Component
+public class JpaUserDetailsService implements UserDetailsService {
+
+    private final UserCredentialRepository userCredentialRepository;
+    private final UserAccountRepository userAccountRepository;
+
+    @Autowired
+    public JpaUserDetailsService(UserCredentialRepository userCredentialRepository, UserAccountRepository userAccountRepository) {
+        this.userCredentialRepository = userCredentialRepository;
+        this.userAccountRepository = userAccountRepository;
+    }
+
+    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+        UserCredential credential = userCredentialRepository.findOneByUserKey(username);
+        UserAccount account = userAccountRepository.findOne(credential.getAccountId());
+        LocalDateTime utcNow = ZonedDateTime.now(ZoneOffset.UTC).toLocalDateTime();
+        return new SaltedUser(
+                credential.getUserKey(),
+                credential.getSecretCode(),
+                !account.isDisabled(),
+                !account.getExpiresAt().isBefore(utcNow),
+                !credential.getExpiresAt().isBefore(utcNow),
+                !account.isLocked(),
+                Collections.<GrantedAuthority>emptyList(),
+                credential.getSalt()
+        );
+    }
+}

+ 13 - 0
src/main/java/com/uas/cloud/oauth2/repository/OAuth2AccountRepository.java

@@ -0,0 +1,13 @@
+package com.uas.cloud.oauth2.repository;
+
+import com.uas.cloud.oauth2.entity.OAuth2Account;
+import com.uas.cloud.oauth2.entity.OAuth2AccountId;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+@Repository
+public interface OAuth2AccountRepository extends JpaRepository<OAuth2Account, OAuth2AccountId> {
+}

+ 12 - 0
src/main/java/com/uas/cloud/oauth2/repository/OAuth2ClientRepository.java

@@ -0,0 +1,12 @@
+package com.uas.cloud.oauth2.repository;
+
+import com.uas.cloud.oauth2.entity.OAuth2Client;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+@Repository
+public interface OAuth2ClientRepository extends JpaRepository<OAuth2Client, String> {
+}

+ 13 - 0
src/main/java/com/uas/cloud/oauth2/repository/OAuth2ClientScopeRepository.java

@@ -0,0 +1,13 @@
+package com.uas.cloud.oauth2.repository;
+
+import com.uas.cloud.oauth2.entity.OAuth2ClientScope;
+import com.uas.cloud.oauth2.entity.OAuth2ClientScopeId;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+@Repository
+public interface OAuth2ClientScopeRepository extends JpaRepository<OAuth2ClientScope, OAuth2ClientScopeId> {
+}

+ 21 - 0
src/main/java/com/uas/cloud/oauth2/repository/OAuth2ScopeRepository.java

@@ -0,0 +1,21 @@
+package com.uas.cloud.oauth2.repository;
+
+import com.uas.cloud.oauth2.entity.OAuth2Scope;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.Set;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+@Repository
+public interface OAuth2ScopeRepository extends JpaRepository<OAuth2Scope, Long> {
+
+    @Query("select distinct(s.key) from OAuth2Scope s" +
+            " left join s.clientScopes cs" +
+            " where s.clientId = :clientId or cs.clientId = :clientId")
+    Set<String> findScopeKeysByClientId(@Param("clientId") String clientId);
+}

+ 14 - 0
src/main/java/com/uas/cloud/oauth2/repository/UserAccountRepository.java

@@ -0,0 +1,14 @@
+package com.uas.cloud.oauth2.repository;
+
+import com.uas.cloud.oauth2.entity.UserAccount;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+@Repository
+public interface UserAccountRepository extends JpaRepository<UserAccount, Long> {
+}
+
+

+ 14 - 0
src/main/java/com/uas/cloud/oauth2/repository/UserCredentialRepository.java

@@ -0,0 +1,14 @@
+package com.uas.cloud.oauth2.repository;
+
+import com.uas.cloud.oauth2.entity.UserCredential;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+@Repository
+public interface UserCredentialRepository extends JpaRepository<UserCredential, Long> {
+
+    UserCredential findOneByUserKey(String userKey);
+}

+ 12 - 0
src/main/java/com/uas/cloud/oauth2/repository/UserProfileRepository.java

@@ -0,0 +1,12 @@
+package com.uas.cloud.oauth2.repository;
+
+import com.uas.cloud.oauth2.entity.UserProfile;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by Pro1 on 2017/3/22.
+ */
+@Repository
+public interface UserProfileRepository extends JpaRepository<UserProfile, Long> {
+}

+ 19 - 0
src/main/java/com/uas/cloud/oauth2/user/UserController.java

@@ -0,0 +1,19 @@
+package com.uas.cloud.oauth2.user;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.security.Principal;
+
+/**
+ * Created by Pro1 on 2017/3/23.
+ */
+@RestController
+public class UserController {
+
+    @RequestMapping("/user")
+    public Principal user(Principal user) {
+        return user;
+    }
+
+}

+ 26 - 0
src/main/resources/application.yml

@@ -0,0 +1,26 @@
+spring:
+  application:
+    name: base-oauth2-service
+  datasource:
+    url: jdbc:oracle:thin:@192.168.253.6:1521:orcl
+    username: uuplatformdemo
+    password: selectuuplatform
+    driver-class-name: oracle.jdbc.driver.OracleDriver
+  jpa:
+      show-sql: true
+      hibernate:
+        ddl-auto: none
+      properties:
+        hibernate:
+          dialect: org.hibernate.dialect.Oracle10gDialect
+  redis:
+      host: 192.168.253.6
+      port: 6379
+server:
+  port: 20140
+  contextPath: /auth
+eureka:
+  client:
+    serviceUrl:
+      defaultZone: http://10.10.100.23:28000/eureka/
+

+ 40 - 0
src/main/resources/templates/authorize.html

@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org" lang="zh-CN">
+<!--/*@thymesVar id="authorizationRequest" type="org.springframework.security.oauth2.provider.AuthorizationRequest"*/-->
+<head>
+    <meta charset="UTF-8"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1"/>
+    <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
+    <title>Authorize</title>
+</head>
+
+<body>
+<div class="container">
+    <div class="page-header">
+        <h1>Authorize</h1>
+    </div>
+    <p th:inline="text">
+        Do you authorize "[[${authorizationRequest.clientId}]]" at "[[${authorizationRequest.redirectUri}]]" to access
+        your protected resources?
+    </p>
+    <form role="form" action="../oauth/authorize" method="post">
+        <div class="form-group" th:each="scope:${authorizationRequest.scope}">
+            <label for="scope.approve" th:for="${'scope.' + scope + '.approve'}" th:text="${'scope.' + scope + ':'}">scope:</label>
+            <label class="radio-inline">
+                <input type="radio" name="scope" th:name="${'scope.' + scope}" th:id="${'scope.' + scope + '.approve'}"
+                       id="scope.approve" value="true" checked="checked"/> Approve
+            </label>
+            <label class="radio-inline">
+                <input type="radio" name="scope" th:name="${'scope.' + scope}" th:id="${'scope.' + scope + '.deny'}"
+                       id="scope.deny" value="false"/> Deny
+            </label>
+        </div>
+        <input name="user_oauth_approval" value="true" type="hidden"/>
+        <input type="hidden" id="csrf_token" name="_csrf" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
+        <button type="submit" class="btn btn-primary">Submit</button>
+    </form>
+</div>
+</body>
+
+</html>

+ 20 - 0
src/main/resources/templates/index.html

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+
+<head>
+    <meta charset="UTF-8"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1"/>
+    <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
+    <title>Home</title>
+</head>
+
+<body>
+<div class="container">
+    <div class="page-header">
+        <h1>Home</h1>
+    </div>
+</div>
+</body>
+
+</html>

+ 32 - 0
src/main/resources/templates/login.html

@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org" lang="zh-CN">
+
+<head>
+    <meta charset="UTF-8"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1"/>
+    <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
+    <title>Login</title>
+</head>
+
+<body>
+<div class="container">
+    <div class="page-header">
+        <h1>Login</h1>
+    </div>
+    <form role="form" action="./login" method="post">
+        <div class="form-group">
+            <label for="username">Username:</label>
+            <input type="text" class="form-control" id="username" name="username"/>
+        </div>
+        <div class="form-group">
+            <label for="password">Password:</label>
+            <input type="password" class="form-control" id="password" name="password"/>
+        </div>
+        <input type="hidden" id="csrf_token" name="_csrf" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
+        <button type="submit" class="btn btn-primary">Submit</button>
+    </form>
+</div>
+</body>
+
+</html>