1、認證中心
1.1 依賴
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mine</groupId>
<artifactId>oauth2.0-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<!-- 管理依賴 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- SpringBoot整合Web組件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- springboot整合freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-->spring-boot 整合security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- spring-cloud-starter-oauth2 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
</dependencies>
<!-- 注意: 這裏必須要添加, 否者各種依賴有問題 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
1.2 springsecurity引入
SecurityConfig
package com.mine.config;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
@Component
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).withUser("user")
.password(new BCryptPasswordEncoder().encode("123456")).authorities("ROLE");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().formLogin();
}
}
1.3 認證中心配置
MyAuthenticationManager
package com.mine.config;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.stereotype.Component;
@Component
public class MyAuthenticationManager implements AuthenticationManager {
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
UserDetailsService userDetailsService = new InMemoryUserDetailsManager();
((InMemoryUserDetailsManager) userDetailsService).createUser(User.withUsername("zhangsan")
.password(new BCryptPasswordEncoder().encode("123456")).authorities("ROLE_USER").build());
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
daoAuthenticationProvider.setHideUserNotFoundExceptions(false);
daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
return daoAuthenticationProvider.authenticate(authentication);
}
}
AuthorizationServerConfig
package com.mine.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
// accessToken有效期
private static int ACCESS_TOKEN_VALIDITY_SECONDS = 7200;
// refreshToken有效期
private static int REFRESH_TOKEN_VALIDITY_SECONDS = 7200;
@Autowired
private MyAuthenticationManager authenticationManager;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("elapse").secret(new BCryptPasswordEncoder().encode("123456"))
.redirectUris("https://www.baidu.com")
.authorizedGrantTypes("authorization_code", "client_credentials", "refresh_token", "password",
"implicit")
.scopes("all").accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS)
.refreshTokenValiditySeconds(REFRESH_TOKEN_VALIDITY_SECONDS);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager).allowedTokenEndpointRequestMethods(HttpMethod.GET,
HttpMethod.POST);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("permitAll()").checkTokenAccess("permitAll()").allowFormAuthenticationForClients();
}
@Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
return passwordEncoder;
}
}
1.4 啓動類
AppOauthServer
package com.mine;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AppOauthServer {
public static void main(String[] args) {
SpringApplication.run(AppOauthServer.class, args);
}
}
2、資源服務器
2.1 依賴
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mine</groupId>
<artifactId>oauth2.0-order</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<!-- 管理依賴 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- SpringBoot整合Web組件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- springboot整合freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-->spring-boot 整合security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
</dependencies>
<!-- 注意: 這裏必須要添加, 否者各種依賴有問題 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
2.2 配置文件
application.yml
server:
port: 8081
security:
oauth2:
resource:
####從認證授權中心上驗證token
tokenInfoUri: http://localhost:8080/oauth/check_token
preferTokenInfo: true
client:
accessTokenUri: http://localhost:8080/oauth/token
userAuthorizationUri: http://localhost:8080/oauth/authorize
###appid
clientId: elapse
###appSecret
clientSecret: 123456
2.3 資源服務器配置
ResourceServerConfiguration
package com.mine.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
// 對 api/order 請求進行攔截
http.authorizeRequests().antMatchers("/api/order/**").authenticated();
}
}
2.4 控制器
OrderController
package com.mine.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/order")
public class OrderController {
@RequestMapping("/getOrder")
public String getOrder() {
return "i am order resource";
}
}
2.5 啓動類
AppResourceOrder
package com.mine;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
@SpringBootApplication
@EnableOAuth2Sso
public class AppResourceOrder {
public static void main(String[] args) {
SpringApplication.run(AppResourceOrder.class, args);
}
}
3、測試
3.1 啓動認證中心與資源中心
3.2 嘗試直接訪問資源中心地址
localhost:8081/api/order/getOrder
響應
{
"error": "unauthorized",
"error_description": "Full authentication is required to access this resource"
}
3.3 通過認證中心請求資源
3.3.1 獲取授權碼(瀏覽器訪問)(登錄用戶名user,密碼123456)
http://localhost:8080/oauth/authorize?response_type=code&client_id=elapse&redirect_uri=https://www.baidu.com
用戶選擇授權後,跳轉到回調地址,例如
https://www.baidu.com/?code=r1uh2E
3.3.2 根據授權碼獲取令牌(postman調用)(授權碼只能用一次)
http://localhost:8080/oauth/token?grant_type=authorization_code&code=r1uh2E&redirect_uri=https://www.baidu.com&client_id=elapse&client_secret=123456&scope=all
響應
{
"access_token": "63ec445e-3f14-4c2c-97fa-434100aa6a8f",
"token_type": "bearer",
"refresh_token": "4d67d9ff-c3a1-43a4-b7cb-cdcfad714a2b",
"expires_in": 7199,
"scope": "all"
}
3.3.3 根據獲取到的令牌(accessToken)訪問資源(postman調用)
localhost:8081/api/order/getOrder
下面2選1
1、設置認證信息,設置相應方式爲oauth2,輸入Access Token
2、設置請求頭信息,key爲Authorization,value爲Bearer+空格+令牌
響應
i am order resource
3.4 密碼認證方式獲取令牌
3.4.1 密碼方式獲取令牌(postman調用)
http://localhost:8080/oauth/token
post請求,參數如下:
grant_type:password
username:zhangsan
password:123456
client_id:elapse
client_secret:123456
scope:all
相應
{
"access_token": "17493e77-f30e-495b-b922-6df5090d891a",
"token_type": "bearer",
"refresh_token": "aaeef695-c22f-49df-b612-a0a22cde2714",
"expires_in": 7188,
"scope": "all"
}