├── .gitignore ├── README.md ├── jwt-resource-server ├── .gitignore ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── cn │ │ └── com │ │ └── sina │ │ └── alan │ │ └── oauth │ │ ├── OAuth2ResourceServer.java │ │ ├── WebController.java │ │ └── config │ │ ├── GlobalMethodSecurityConfiguration.java │ │ ├── JwtConfiguration.java │ │ └── ResourceServerConfiguration.java │ └── resources │ ├── application.properties │ ├── public.cert │ └── templates │ └── error.vm └── oauth-server ├── .gitignore ├── README.md ├── pom.xml └── src └── main ├── java └── cn │ └── com │ └── sina │ └── alan │ └── oauth │ ├── AuthServerApplication.java │ ├── config │ ├── OAuth2Configuration.java │ └── WebSecurityConfig.java │ └── controller │ ├── ErrorCtr.java │ └── WebController.java └── resources ├── application.properties ├── jwt.jks ├── keystore.jks └── templates └── error.vm /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | target 3 | *.idea 4 | *.DS_Store 5 | .idea/ 6 | target/ 7 | target/* 8 | .idea/* 9 | .idea/*.xml 10 | .idea/workspace.xml 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # spring-cloud-security-oauth2-jwt 2 | 使用spring-cloud-security-oauth2来实现oauth server和resource server,oauth Server和resource Server分开,oauth Server和resource Server使用了jwt的方式进行了实现。认证服务器生成jwt格式的token,并不对其进行持久化,然后资源服务器使用密钥进行校验token。 3 | 4 | 授权登录时,使用用户名reader密码reader登录 5 | -------------------------------------------------------------------------------- /jwt-resource-server/.gitignore: -------------------------------------------------------------------------------- 1 | # maven ignore 2 | target/ 3 | *.jar 4 | *.war 5 | *.zip 6 | *.tar 7 | *.tar.gz 8 | 9 | # eclipse ignore 10 | .settings/ 11 | .project 12 | .classpath 13 | 14 | # idea ignore 15 | .idea/ 16 | *.ipr 17 | *.iml 18 | *.iws 19 | *.springBeans 20 | 21 | # temp ignore 22 | *.log 23 | *.cache 24 | *.diff 25 | *.patch 26 | *.tmp 27 | *.java~ 28 | *.properties~ 29 | *.xml~ 30 | *.bak 31 | 32 | # system ignore 33 | .DS_Store 34 | Thumbs.db 35 | 36 | *.log 37 | 38 | -------------------------------------------------------------------------------- /jwt-resource-server/README.md: -------------------------------------------------------------------------------- 1 | # Spring Security OAuth2 Demo 2 | 项目使用的是MySql存储, 需要先创建以下表结构: 3 | ``` 4 | 5 | CREATE SCHEMA IF NOT EXISTS `alan-oauth` DEFAULT CHARACTER SET utf8 ; 6 | USE `alan-oauth` ; 7 | 8 | -- ----------------------------------------------------- 9 | -- Table `alan-oauth`.`clientdetails` 10 | -- ----------------------------------------------------- 11 | CREATE TABLE IF NOT EXISTS `alan-oauth`.`clientdetails` ( 12 | `appId` VARCHAR(128) NOT NULL, 13 | `resourceIds` VARCHAR(256) NULL DEFAULT NULL, 14 | `appSecret` VARCHAR(256) NULL DEFAULT NULL, 15 | `scope` VARCHAR(256) NULL DEFAULT NULL, 16 | `grantTypes` VARCHAR(256) NULL DEFAULT NULL, 17 | `redirectUrl` VARCHAR(256) NULL DEFAULT NULL, 18 | `authorities` VARCHAR(256) NULL DEFAULT NULL, 19 | `access_token_validity` INT(11) NULL DEFAULT NULL, 20 | `refresh_token_validity` INT(11) NULL DEFAULT NULL, 21 | `additionalInformation` VARCHAR(4096) NULL DEFAULT NULL, 22 | `autoApproveScopes` VARCHAR(256) NULL DEFAULT NULL, 23 | PRIMARY KEY (`appId`)) 24 | ENGINE = InnoDB 25 | DEFAULT CHARACTER SET = utf8; 26 | 27 | 28 | -- ----------------------------------------------------- 29 | -- Table `alan-oauth`.`oauth_access_token` 30 | -- ----------------------------------------------------- 31 | CREATE TABLE IF NOT EXISTS `alan-oauth`.`oauth_access_token` ( 32 | `token_id` VARCHAR(256) NULL DEFAULT NULL, 33 | `token` BLOB NULL DEFAULT NULL, 34 | `authentication_id` VARCHAR(128) NOT NULL, 35 | `user_name` VARCHAR(256) NULL DEFAULT NULL, 36 | `client_id` VARCHAR(256) NULL DEFAULT NULL, 37 | `authentication` BLOB NULL DEFAULT NULL, 38 | `refresh_token` VARCHAR(256) NULL DEFAULT NULL, 39 | PRIMARY KEY (`authentication_id`)) 40 | ENGINE = InnoDB 41 | DEFAULT CHARACTER SET = utf8; 42 | 43 | 44 | -- ----------------------------------------------------- 45 | -- Table `alan-oauth`.`oauth_approvals` 46 | -- ----------------------------------------------------- 47 | CREATE TABLE IF NOT EXISTS `alan-oauth`.`oauth_approvals` ( 48 | `userId` VARCHAR(256) NULL DEFAULT NULL, 49 | `clientId` VARCHAR(256) NULL DEFAULT NULL, 50 | `scope` VARCHAR(256) NULL DEFAULT NULL, 51 | `status` VARCHAR(10) NULL DEFAULT NULL, 52 | `expiresAt` DATETIME NULL DEFAULT NULL, 53 | `lastModifiedAt` DATETIME NULL DEFAULT NULL) 54 | ENGINE = InnoDB 55 | DEFAULT CHARACTER SET = utf8; 56 | 57 | 58 | -- ----------------------------------------------------- 59 | -- Table `alan-oauth`.`oauth_client_details` 60 | -- ----------------------------------------------------- 61 | CREATE TABLE IF NOT EXISTS `alan-oauth`.`oauth_client_details` ( 62 | `client_id` VARCHAR(128) NOT NULL, 63 | `resource_ids` VARCHAR(256) NULL DEFAULT NULL, 64 | `client_secret` VARCHAR(256) NULL DEFAULT NULL, 65 | `scope` VARCHAR(256) NULL DEFAULT NULL, 66 | `authorized_grant_types` VARCHAR(256) NULL DEFAULT NULL, 67 | `web_server_redirect_uri` VARCHAR(256) NULL DEFAULT NULL, 68 | `authorities` VARCHAR(256) NULL DEFAULT NULL, 69 | `access_token_validity` INT(11) NULL DEFAULT NULL, 70 | `refresh_token_validity` INT(11) NULL DEFAULT NULL, 71 | `additional_information` VARCHAR(4096) NULL DEFAULT NULL, 72 | `autoapprove` VARCHAR(256) NULL DEFAULT NULL, 73 | PRIMARY KEY (`client_id`)) 74 | ENGINE = InnoDB 75 | DEFAULT CHARACTER SET = utf8; 76 | 77 | 78 | -- ----------------------------------------------------- 79 | -- Table `alan-oauth`.`oauth_client_token` 80 | -- ----------------------------------------------------- 81 | CREATE TABLE IF NOT EXISTS `alan-oauth`.`oauth_client_token` ( 82 | `token_id` VARCHAR(256) NULL DEFAULT NULL, 83 | `token` BLOB NULL DEFAULT NULL, 84 | `authentication_id` VARCHAR(128) NOT NULL, 85 | `user_name` VARCHAR(256) NULL DEFAULT NULL, 86 | `client_id` VARCHAR(256) NULL DEFAULT NULL, 87 | PRIMARY KEY (`authentication_id`)) 88 | ENGINE = InnoDB 89 | DEFAULT CHARACTER SET = utf8; 90 | 91 | 92 | -- ----------------------------------------------------- 93 | -- Table `alan-oauth`.`oauth_code` 94 | -- ----------------------------------------------------- 95 | CREATE TABLE IF NOT EXISTS `alan-oauth`.`oauth_code` ( 96 | `code` VARCHAR(256) NULL DEFAULT NULL, 97 | `authentication` BLOB NULL DEFAULT NULL) 98 | ENGINE = InnoDB 99 | DEFAULT CHARACTER SET = utf8; 100 | 101 | 102 | -- ----------------------------------------------------- 103 | -- Table `alan-oauth`.`oauth_refresh_token` 104 | -- ----------------------------------------------------- 105 | CREATE TABLE IF NOT EXISTS `alan-oauth`.`oauth_refresh_token` ( 106 | `token_id` VARCHAR(256) NULL DEFAULT NULL, 107 | `token` BLOB NULL DEFAULT NULL, 108 | `authentication` BLOB NULL DEFAULT NULL) 109 | ENGINE = InnoDB 110 | DEFAULT CHARACTER SET = utf8; 111 | 112 | ``` 113 | 然后在`oauth_client_details`表中插入记录: 114 | ``` 115 | # client_id, resource_ids, client_secret, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove 116 | 'client', NULL, 'secret', 'app', 'authorization_code', 'http://www.baidu.com', NULL, NULL, NULL, NULL, NULL 117 | ``` 118 | 这时就可以访问授权页面了: 119 | ``` 120 | localhost:8080/oauth/authorize?client_id=client&response_type=code&redirect_uri=http://www.baidu.com 121 | ``` 122 | 访问时Spring让你登陆,随便输入一个用户名密码即可. 123 | 124 | 数据库连接信息在`application.properties`中配置。 -------------------------------------------------------------------------------- /jwt-resource-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | cn.com.sina 8 | resource-server3 9 | 1.0-SNAPSHOT 10 | 11 | 12 | org.springframework.boot 13 | spring-boot-starter-parent 14 | 1.3.7.RELEASE 15 | 16 | 17 | 18 | 19 | org.springframework.cloud 20 | spring-cloud-dependencies 21 | Brixton.SR5 22 | pom 23 | import 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.springframework.cloud 32 | spring-cloud-starter-security 33 | 34 | 35 | 36 | org.springframework.cloud 37 | spring-cloud-starter-oauth2 38 | 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-velocity 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | org.apache.maven.plugins 62 | maven-compiler-plugin 63 | 64 | 1.8 65 | 1.8 66 | 67 | 68 | 69 | 70 | 71 | org.springframework.boot 72 | spring-boot-maven-plugin 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /jwt-resource-server/src/main/java/cn/com/sina/alan/oauth/OAuth2ResourceServer.java: -------------------------------------------------------------------------------- 1 | package cn.com.sina.alan.oauth; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * Created by on 2017.03.08. 8 | */ 9 | @SpringBootApplication 10 | public class OAuth2ResourceServer { 11 | 12 | public static void main(String[] args) { 13 | SpringApplication.run(OAuth2ResourceServer.class, args); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /jwt-resource-server/src/main/java/cn/com/sina/alan/oauth/WebController.java: -------------------------------------------------------------------------------- 1 | package cn.com.sina.alan.oauth; 2 | 3 | import org.springframework.security.access.prepost.PreAuthorize; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestMethod; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | import java.util.UUID; 9 | 10 | /** 11 | * Created by on 2017.03.08. 12 | */ 13 | @RestController 14 | @RequestMapping("/foo") 15 | public class WebController { 16 | 17 | @RequestMapping(method = RequestMethod.GET) 18 | public String readFoo() { 19 | return "read foo " + UUID.randomUUID().toString(); 20 | } 21 | 22 | @PreAuthorize("hasAuthority('FOO_WRITE')") 23 | @RequestMapping(method = RequestMethod.POST) 24 | public String writeFoo() { 25 | return "write foo " + UUID.randomUUID().toString(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jwt-resource-server/src/main/java/cn/com/sina/alan/oauth/config/GlobalMethodSecurityConfiguration.java: -------------------------------------------------------------------------------- 1 | package cn.com.sina.alan.oauth.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 5 | 6 | /** 7 | * Created by on 2017.03.08. 8 | */ 9 | @Configuration 10 | @EnableGlobalMethodSecurity(prePostEnabled = true) 11 | public class GlobalMethodSecurityConfiguration { 12 | } 13 | -------------------------------------------------------------------------------- /jwt-resource-server/src/main/java/cn/com/sina/alan/oauth/config/JwtConfiguration.java: -------------------------------------------------------------------------------- 1 | package cn.com.sina.alan.oauth.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.beans.factory.annotation.Qualifier; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.security.oauth2.provider.token.TokenStore; 8 | import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; 9 | import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; 10 | 11 | /** 12 | * Created by on 2017.03.08. 13 | */ 14 | @Configuration 15 | public class JwtConfiguration { 16 | @Autowired 17 | JwtAccessTokenConverter jwtAccessTokenConverter; 18 | 19 | @Bean 20 | @Qualifier("tokenStore") 21 | public TokenStore tokenStore() { 22 | 23 | System.out.println("Created JwtTokenStore"); 24 | return new JwtTokenStore(jwtAccessTokenConverter); 25 | } 26 | 27 | // @Bean 28 | // protected JwtAccessTokenConverter jwtTokenEnhancer() { 29 | // JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); 30 | // Resource resource = new ClassPathResource("public.cert"); 31 | // String publicKey = null; 32 | // try { 33 | // publicKey = new String(FileCopyUtils.copyToByteArray(resource.getInputStream())); 34 | // } catch (IOException e) { 35 | // throw new RuntimeException(e); 36 | // } 37 | // converter.setVerifierKey(publicKey); 38 | // return converter; 39 | // } 40 | 41 | @Bean 42 | protected JwtAccessTokenConverter jwtTokenEnhancer() { 43 | JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); 44 | converter.setSigningKey("123"); 45 | return converter; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /jwt-resource-server/src/main/java/cn/com/sina/alan/oauth/config/ResourceServerConfiguration.java: -------------------------------------------------------------------------------- 1 | package cn.com.sina.alan.oauth.config; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.http.HttpMethod; 8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 9 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; 10 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; 11 | import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; 12 | import org.springframework.security.oauth2.provider.token.TokenStore; 13 | import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; 14 | 15 | /** 16 | * Created by on 2017.03.08. 17 | */ 18 | @Configuration 19 | @EnableResourceServer 20 | public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { 21 | Logger log = LoggerFactory.getLogger(ResourceServerConfiguration.class); 22 | 23 | @Override 24 | public void configure(HttpSecurity http) throws Exception { 25 | http.csrf().disable().authorizeRequests().antMatchers("/**").authenticated().antMatchers(HttpMethod.GET, "/foo") 26 | // 拦截用户,必须具有所列权限 27 | .hasAuthority("FOO_READ"); 28 | // .antMatchers(HttpMethod.POST, "/foo").hasAuthority("FOO_WRITE"); 29 | // you can implement it like this, but I show method invocation security on write 30 | } 31 | 32 | @Override 33 | public void configure(ResourceServerSecurityConfigurer resources) throws Exception { 34 | log.info("Configuring ResourceServerSecurityConfigurer "); 35 | resources.resourceId("foo").tokenStore(tokenStore); 36 | } 37 | 38 | @Autowired 39 | TokenStore tokenStore; 40 | 41 | @Autowired 42 | JwtAccessTokenConverter tokenConverter; 43 | } 44 | -------------------------------------------------------------------------------- /jwt-resource-server/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=9090 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /jwt-resource-server/src/main/resources/public.cert: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwR84LFHwnK5GXErnwkmD 3 | mPOJl4CSTtYXCqmCtlbF+5qVOosu0YsM2DsrC9O2gun6wVFKkWYiMoBSjsNMSI3Z 4 | w5JYgh+ldHvA+MIex2QXfOZx920M1fPUiuUPgmnTFS+Z3lmK3/T6jJnmciUPY1pe 5 | h4MXL6YzeI0q4W9xNBBeKT6FDGpduc0FC3OlXHfLbVOThKmAUpAWFDwf9/uUA//l 6 | 3PLchmV6VwTcUaaHp5W8Af/GU4lPGZbTAqOxzB9ukisPFuO1DikacPhrOQgdxtqk 7 | LciRTa884uQnkFwSguOEUYf3ni8GNRJauIuW0rVXhMOs78pKvCKmo53M0tqeC6ul 8 | +QIDAQAB 9 | -----END PUBLIC KEY----- -------------------------------------------------------------------------------- /jwt-resource-server/src/main/resources/templates/error.vm: -------------------------------------------------------------------------------- 1 |

invalid parameter!

-------------------------------------------------------------------------------- /oauth-server/.gitignore: -------------------------------------------------------------------------------- 1 | # maven ignore 2 | target/ 3 | *.jar 4 | *.war 5 | *.zip 6 | *.tar 7 | *.tar.gz 8 | 9 | # eclipse ignore 10 | .settings/ 11 | .project 12 | .classpath 13 | 14 | # idea ignore 15 | .idea/ 16 | *.ipr 17 | *.iml 18 | *.iws 19 | *.springBeans 20 | 21 | # temp ignore 22 | *.log 23 | *.cache 24 | *.diff 25 | *.patch 26 | *.tmp 27 | *.java~ 28 | *.properties~ 29 | *.xml~ 30 | *.bak 31 | 32 | # system ignore 33 | .DS_Store 34 | Thumbs.db 35 | 36 | *.log 37 | 38 | -------------------------------------------------------------------------------- /oauth-server/README.md: -------------------------------------------------------------------------------- 1 | # Spring Security OAuth2 Demo 2 | 项目使用的是MySql存储, 需要先创建以下表结构: 3 | ``` 4 | 5 | CREATE SCHEMA IF NOT EXISTS `alan-oauth` DEFAULT CHARACTER SET utf8 ; 6 | USE `alan-oauth` ; 7 | 8 | -- ----------------------------------------------------- 9 | -- Table `alan-oauth`.`clientdetails` 10 | -- ----------------------------------------------------- 11 | CREATE TABLE IF NOT EXISTS `alan-oauth`.`clientdetails` ( 12 | `appId` VARCHAR(128) NOT NULL, 13 | `resourceIds` VARCHAR(256) NULL DEFAULT NULL, 14 | `appSecret` VARCHAR(256) NULL DEFAULT NULL, 15 | `scope` VARCHAR(256) NULL DEFAULT NULL, 16 | `grantTypes` VARCHAR(256) NULL DEFAULT NULL, 17 | `redirectUrl` VARCHAR(256) NULL DEFAULT NULL, 18 | `authorities` VARCHAR(256) NULL DEFAULT NULL, 19 | `access_token_validity` INT(11) NULL DEFAULT NULL, 20 | `refresh_token_validity` INT(11) NULL DEFAULT NULL, 21 | `additionalInformation` VARCHAR(4096) NULL DEFAULT NULL, 22 | `autoApproveScopes` VARCHAR(256) NULL DEFAULT NULL, 23 | PRIMARY KEY (`appId`)) 24 | ENGINE = InnoDB 25 | DEFAULT CHARACTER SET = utf8; 26 | 27 | 28 | -- ----------------------------------------------------- 29 | -- Table `alan-oauth`.`oauth_access_token` 30 | -- ----------------------------------------------------- 31 | CREATE TABLE IF NOT EXISTS `alan-oauth`.`oauth_access_token` ( 32 | `token_id` VARCHAR(256) NULL DEFAULT NULL, 33 | `token` BLOB NULL DEFAULT NULL, 34 | `authentication_id` VARCHAR(128) NOT NULL, 35 | `user_name` VARCHAR(256) NULL DEFAULT NULL, 36 | `client_id` VARCHAR(256) NULL DEFAULT NULL, 37 | `authentication` BLOB NULL DEFAULT NULL, 38 | `refresh_token` VARCHAR(256) NULL DEFAULT NULL, 39 | PRIMARY KEY (`authentication_id`)) 40 | ENGINE = InnoDB 41 | DEFAULT CHARACTER SET = utf8; 42 | 43 | 44 | -- ----------------------------------------------------- 45 | -- Table `alan-oauth`.`oauth_approvals` 46 | -- ----------------------------------------------------- 47 | CREATE TABLE IF NOT EXISTS `alan-oauth`.`oauth_approvals` ( 48 | `userId` VARCHAR(256) NULL DEFAULT NULL, 49 | `clientId` VARCHAR(256) NULL DEFAULT NULL, 50 | `scope` VARCHAR(256) NULL DEFAULT NULL, 51 | `status` VARCHAR(10) NULL DEFAULT NULL, 52 | `expiresAt` DATETIME NULL DEFAULT NULL, 53 | `lastModifiedAt` DATETIME NULL DEFAULT NULL) 54 | ENGINE = InnoDB 55 | DEFAULT CHARACTER SET = utf8; 56 | 57 | 58 | -- ----------------------------------------------------- 59 | -- Table `alan-oauth`.`oauth_client_details` 60 | -- ----------------------------------------------------- 61 | CREATE TABLE IF NOT EXISTS `alan-oauth`.`oauth_client_details` ( 62 | `client_id` VARCHAR(128) NOT NULL, 63 | `resource_ids` VARCHAR(256) NULL DEFAULT NULL, 64 | `client_secret` VARCHAR(256) NULL DEFAULT NULL, 65 | `scope` VARCHAR(256) NULL DEFAULT NULL, 66 | `authorized_grant_types` VARCHAR(256) NULL DEFAULT NULL, 67 | `web_server_redirect_uri` VARCHAR(256) NULL DEFAULT NULL, 68 | `authorities` VARCHAR(256) NULL DEFAULT NULL, 69 | `access_token_validity` INT(11) NULL DEFAULT NULL, 70 | `refresh_token_validity` INT(11) NULL DEFAULT NULL, 71 | `additional_information` VARCHAR(4096) NULL DEFAULT NULL, 72 | `autoapprove` VARCHAR(256) NULL DEFAULT NULL, 73 | PRIMARY KEY (`client_id`)) 74 | ENGINE = InnoDB 75 | DEFAULT CHARACTER SET = utf8; 76 | 77 | 78 | -- ----------------------------------------------------- 79 | -- Table `alan-oauth`.`oauth_client_token` 80 | -- ----------------------------------------------------- 81 | CREATE TABLE IF NOT EXISTS `alan-oauth`.`oauth_client_token` ( 82 | `token_id` VARCHAR(256) NULL DEFAULT NULL, 83 | `token` BLOB NULL DEFAULT NULL, 84 | `authentication_id` VARCHAR(128) NOT NULL, 85 | `user_name` VARCHAR(256) NULL DEFAULT NULL, 86 | `client_id` VARCHAR(256) NULL DEFAULT NULL, 87 | PRIMARY KEY (`authentication_id`)) 88 | ENGINE = InnoDB 89 | DEFAULT CHARACTER SET = utf8; 90 | 91 | 92 | -- ----------------------------------------------------- 93 | -- Table `alan-oauth`.`oauth_code` 94 | -- ----------------------------------------------------- 95 | CREATE TABLE IF NOT EXISTS `alan-oauth`.`oauth_code` ( 96 | `code` VARCHAR(256) NULL DEFAULT NULL, 97 | `authentication` BLOB NULL DEFAULT NULL) 98 | ENGINE = InnoDB 99 | DEFAULT CHARACTER SET = utf8; 100 | 101 | 102 | -- ----------------------------------------------------- 103 | -- Table `alan-oauth`.`oauth_refresh_token` 104 | -- ----------------------------------------------------- 105 | CREATE TABLE IF NOT EXISTS `alan-oauth`.`oauth_refresh_token` ( 106 | `token_id` VARCHAR(256) NULL DEFAULT NULL, 107 | `token` BLOB NULL DEFAULT NULL, 108 | `authentication` BLOB NULL DEFAULT NULL) 109 | ENGINE = InnoDB 110 | DEFAULT CHARACTER SET = utf8; 111 | 112 | ``` 113 | 然后在`oauth_client_details`表中插入记录: 114 | ``` 115 | # client_id, resource_ids, client_secret, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove 116 | 'client', NULL, 'secret', 'app', 'authorization_code', 'http://www.baidu.com', NULL, NULL, NULL, NULL, NULL 117 | ``` 118 | 这时就可以访问授权页面了: 119 | ``` 120 | localhost:8080/oauth/authorize?client_id=client&response_type=code&redirect_uri=http://www.baidu.com 121 | ``` 122 | 访问时Spring让你登陆,随便输入一个用户名密码即可. 123 | 124 | 数据库连接信息在`application.properties`中配置。 -------------------------------------------------------------------------------- /oauth-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | cn.com.sina 8 | oauth-server2 9 | 1.0-SNAPSHOT 10 | 11 | 12 | org.springframework.boot 13 | spring-boot-starter-parent 14 | 1.3.7.RELEASE 15 | 16 | 17 | 18 | 19 | org.springframework.cloud 20 | spring-cloud-dependencies 21 | Brixton.SR5 22 | pom 23 | import 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.springframework.cloud 32 | spring-cloud-starter-security 33 | 34 | 35 | 36 | org.springframework.cloud 37 | spring-cloud-starter-oauth2 38 | 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-velocity 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | org.apache.maven.plugins 62 | maven-compiler-plugin 63 | 64 | 1.8 65 | 1.8 66 | 67 | 68 | 69 | 70 | 71 | org.springframework.boot 72 | spring-boot-maven-plugin 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /oauth-server/src/main/java/cn/com/sina/alan/oauth/AuthServerApplication.java: -------------------------------------------------------------------------------- 1 | package cn.com.sina.alan.oauth; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * Created by on 2017.03.08. 8 | */ 9 | @SpringBootApplication 10 | public class AuthServerApplication { 11 | 12 | public static void main(String[] args) { 13 | SpringApplication.run(AuthServerApplication.class, args); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /oauth-server/src/main/java/cn/com/sina/alan/oauth/config/OAuth2Configuration.java: -------------------------------------------------------------------------------- 1 | package cn.com.sina.alan.oauth.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.beans.factory.annotation.Qualifier; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.core.io.ClassPathResource; 8 | import org.springframework.security.authentication.AuthenticationManager; 9 | import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; 10 | import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; 11 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; 12 | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; 13 | import org.springframework.security.oauth2.provider.token.TokenStore; 14 | import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; 15 | import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; 16 | import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory; 17 | 18 | /** 19 | * Created by on 2017.03.08. 20 | */ 21 | @Configuration 22 | @EnableAuthorizationServer 23 | public class OAuth2Configuration extends AuthorizationServerConfigurerAdapter { 24 | @Override 25 | public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 26 | clients.inMemory().withClient("web_app") 27 | .scopes("FOO").autoApprove(true) 28 | .authorities("FOO_READ", "FOO_WRITE") 29 | .authorizedGrantTypes("implicit", "refresh_token", "password", "authorization_code"); 30 | } 31 | 32 | @Override 33 | public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 34 | endpoints.tokenStore(tokenStore()).tokenEnhancer(jwtTokenEnhancer()) 35 | .authenticationManager(authenticationManager); 36 | } 37 | 38 | @Autowired 39 | @Qualifier("authenticationManagerBean") 40 | private AuthenticationManager authenticationManager; 41 | 42 | @Bean 43 | public TokenStore tokenStore() { 44 | return new JwtTokenStore(jwtTokenEnhancer()); 45 | } 46 | 47 | // @Bean 48 | // protected JwtAccessTokenConverter jwtTokenEnhancer() { 49 | // KeyStoreKeyFactory keyStoreKeyFactory = 50 | // new KeyStoreKeyFactory(new ClassPathResource("jwt.jks"), "mySecretKey".toCharArray()); 51 | // JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); 52 | // converter.setKeyPair(keyStoreKeyFactory.getKeyPair("jwt")); 53 | // return converter; 54 | // } 55 | 56 | @Bean 57 | protected JwtAccessTokenConverter jwtTokenEnhancer() { 58 | JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); 59 | converter.setSigningKey("123"); 60 | return converter; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /oauth-server/src/main/java/cn/com/sina/alan/oauth/config/WebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package cn.com.sina.alan.oauth.config; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.security.authentication.AuthenticationManager; 8 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 10 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 11 | 12 | /** 13 | * Created by on 2017.03.08. 14 | */ 15 | @Configuration 16 | class WebSecurityConfig extends WebSecurityConfigurerAdapter { 17 | 18 | Logger log = LoggerFactory.getLogger(WebSecurityConfig.class); 19 | 20 | @Override 21 | @Bean 22 | public AuthenticationManager authenticationManagerBean() throws Exception { 23 | return super.authenticationManagerBean(); 24 | } 25 | 26 | @Override 27 | protected void configure(HttpSecurity http) throws Exception { 28 | // http.csrf().disable().exceptionHandling().authenticationEntryPoint( 29 | // (request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED)).and() 30 | // .authorizeRequests().antMatchers("/**").authenticated().and().httpBasic(); 31 | super.configure(http); 32 | } 33 | 34 | @Override 35 | protected void configure(AuthenticationManagerBuilder auth) throws Exception { 36 | auth.inMemoryAuthentication().withUser("reader").password("reader").authorities("FOO_READ").and() 37 | .withUser("writer").password("writer").authorities("FOO_READ", "FOO_WRITE"); 38 | 39 | // auth.jdbcAuthentication(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /oauth-server/src/main/java/cn/com/sina/alan/oauth/controller/ErrorCtr.java: -------------------------------------------------------------------------------- 1 | package cn.com.sina.alan.oauth.controller; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RequestParam; 8 | import org.springframework.web.bind.annotation.SessionAttributes; 9 | 10 | import java.util.Map; 11 | 12 | /** 13 | * Created by on 2017.03.08. 14 | */ 15 | @Controller 16 | @SessionAttributes("authorizationRequest") 17 | public class ErrorCtr { 18 | private static final Logger log = LoggerFactory.getLogger(ErrorCtr.class); 19 | 20 | @RequestMapping("/oauth/error") 21 | public String error(@RequestParam Map parameters) { 22 | String uri = parameters.get("redirect_uri"); 23 | log.info("重定向: {}", uri); 24 | 25 | return "redirect:" + uri + "?error=1"; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /oauth-server/src/main/java/cn/com/sina/alan/oauth/controller/WebController.java: -------------------------------------------------------------------------------- 1 | package cn.com.sina.alan.oauth.controller; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | /** 7 | * Created by jiangchao08 on 17/3/6. 8 | */ 9 | @RestController 10 | public class WebController { 11 | 12 | @RequestMapping("/hello") 13 | public String hello() { 14 | return "hello word!"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /oauth-server/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.contextPath=/uaa 2 | security.user.password=password 3 | security.ignored=/css/**,/js/**,/favicon.ico,/webjars/** 4 | logging.level.org.springframework.security=DEBUG -------------------------------------------------------------------------------- /oauth-server/src/main/resources/jwt.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiangchao123/spring-cloud-security-oauth2-jwt/6dc1f96a97b260795cecf2e4b560cade2c8c5a68/oauth-server/src/main/resources/jwt.jks -------------------------------------------------------------------------------- /oauth-server/src/main/resources/keystore.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiangchao123/spring-cloud-security-oauth2-jwt/6dc1f96a97b260795cecf2e4b560cade2c8c5a68/oauth-server/src/main/resources/keystore.jks -------------------------------------------------------------------------------- /oauth-server/src/main/resources/templates/error.vm: -------------------------------------------------------------------------------- 1 |

invalid parameter!

--------------------------------------------------------------------------------