github地址:https://github.com/intfish123/oauth.git
需要2个服务,一个认证授权服务,一个资源服务
认证授权服务为客户端颁发令牌,资源服务用于客户端获取用户信息。
1. 总体架构:
2.认证授权服务
pom文件:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.intfish</groupId> <artifactId>auth-server</artifactId> <version>0.0.1-SNAPSHOT</version> <name>auth-server</name> <description>Demo project for Spring Boot</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.SR3</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-oauth2 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2.1 项目目录:
2.2 代码
AuthorizationConfig.java
package com.intfish.authorization.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.factory.PasswordEncoderFactories; 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.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.InMemoryTokenStore; @Configuration public class AuthorizationConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Autowired private UserDetailsService userDetailsService; @Bean public TokenStore memoryTokenStore(){ //token存在内存中 return new InMemoryTokenStore(); } @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { //tokenKeyAccess("permitAll()")表示谁都可以获取令牌 checkTokenAccess("isAuthenticated()")表示只有认证之后才可以检查令牌 security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()").allowFormAuthenticationForClients(); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory().withClient("client1") //客户端id .authorizedGrantTypes("authorization_code", "refresh_token") //允许authorization_code和refresh_token授权 .scopes("test") //权限范围 可以是 read,write 自己填 .secret(PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("123456")) //客户端secret .redirectUris("http://www.baidu.com"); //回调地址,用于接收code和access_token }
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
// .tokenServices(tokenService())
.tokenStore(tokenStore())
.userDetailsService(userDetailsService);
}
@Bean
public DefaultTokenServices tokenService() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
//配置token存储
tokenServices.setTokenStore(tokenStore());
//开启支持refresh_token,此处如果之前没有配置,启动服务后再配置重启服务,可能会导致不返回token的问题,解决方式:清除redis对应token存储
tokenServices.setSupportRefreshToken(true);
//复用refresh_token
tokenServices.setReuseRefreshToken(true);
//token有效期,设置12小时
tokenServices.setAccessTokenValiditySeconds(12 * 60 * 60);
//refresh_token有效期,设置一周
tokenServices.setRefreshTokenValiditySeconds(7 * 24 * 60 * 60);
return tokenServices;
}
}
SecurityConfig.java
package com.intfish.authorization.config; import org.springframework.context.annotation.Bean; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.provisioning.InMemoryUserDetailsManager; @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Bean @Override public UserDetailsService userDetailsService() { //基于内存查询用户 InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager(); userDetailsManager.createUser( User.withUsername("admin") .password( PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("admin") ).authorities("USER").build() ); return userDetailsManager; } @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService()); } }
启动类 AuthServerApplication.java
package com.intfish.authorization; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; @SpringBootApplication @EnableAuthorizationServer //启用认证授权服务 public class AuthServerApplication { public static void main(String[] args) { SpringApplication.run(AuthServerApplication.class, args); } }
配置文件 application.properties
//默认配置即可 什么都不用配置
到此认证授权服务配置完成,直接启动即可。
3. 资源服务(用于根据access_token查询用户信息)
pom文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.intfish</groupId> <artifactId>resource-server</artifactId> <version>0.0.1-SNAPSHOT</version> <name>resource-server</name> <description>Demo project for Spring Boot</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.SR3</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-security</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3.1 资源服务项目目录
3.2 代码
UserController.java
package com.intfish.resourceserver.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/user") public class UserController { private Logger log = LoggerFactory.getLogger(this.getClass()); @PostMapping("getUserInfo") public Object getUserInfo(Authentication authentication){ log.info("获取用户信息;"+ authentication); return authentication; } }
启动类 ResourceServerApplication.java
package com.intfish.resourceserver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; @SpringBootApplication @EnableResourceServer //开启资源服务 public class ResourceServerApplication { public static void main(String[] args) { SpringApplication.run(ResourceServerApplication.class, args); } }
配置文件 application.properties
server.port=9090 auth-server-url=http://localhost:8080 security.oauth2.client.client-id=client1 security.oauth2.client.client-secret=123456 security.oauth2.client.scope=test security.oauth2.client.access-token-uri=${auth-server-url}/oauth/token security.oauth2.client.user-authorization-uri=${auth-server-url}/oauth/authorize security.oauth2.resource.token-info-uri=${auth-server-url}/oauth/check_token
到此资源服务配置完成,启动服务即可。
4. 认证授权+获取令牌(access_token)
4.1 用浏览器访问 认证授权服务
http://localhost:8080/oauth/authorize?response_type=code&client_id=client1&redirect_uri=http://www.baidu.com
然后自动跳入登录地址,输入账号密码登录: admin/admin
登录成功提示用户是否允许授权,点Approve允许
登录成功,自动调转到回调地址,并在url中带有code参数
那着这个code用postman发请求获取令牌
成功拿到令牌access_token。
接着用这个令牌访问资源服务
请求成功。也可以这样请求
http://localhost:9090/user/getUserInfo?access_token=2f3c1803-dbb8-4f95-acf6-88a298309ecd
到此全部结束。!!!!!