【認證服務----SpringSecurityOauth2】一、基於內存實現Oauth2

基於SpringBoot(2.1.9.RELEASE)、SpringCloud(Greenwich.SR3)

一、關於OAuth2

OAuth2是一種協議規範,spring-security-oauth2是對他的一種實現。其次,還有shiro實現,自己根據規範編寫代碼的實現方式。主流的qq,微信等第三方授權登錄方式都是基於oauth2實現的。

oauth2的認證方式有授權碼,簡單,賬戶密碼,客戶端等方式,具體請自行百度不做過多的闡述。

本文基於授權碼方式實現

oauth生態設計的範圍很大,可以說是一種解決方案,它有“第三方客戶端(web服務,APP服務)”、“用戶”、“認證服務器”、“資源服務器”等部分。認證流程如下圖: 

  • (A)用戶打開客戶端以後,客戶端要求用戶給予授權。
  • (B)用戶同意給予客戶端授權。
  • (C)客戶端使用上一步獲得的授權,向認證服務器申請令牌。
  • (D)認證服務器對客戶端進行認證以後,確認無誤,同意發放令牌。
  • (E)客戶端使用令牌,向資源服務器申請獲取資源。
  • (F)資源服務器確認令牌無誤,同意向客戶端開放資源。

二、auth-server

1.創建auth-server工程,添加依賴。

springcloud-security已經封裝好了oauth2,所以只添加依賴spring-cloud-starter-oauth2,其他的依賴由於項目使用了Nacos和其他的組件,非必須

    <!-- 依賴 -->
    <dependencies>
        <!-- Spring Boot -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- SpringCloud -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

        <!-- Nacos -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!-- Security -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>

        <!-- Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </dependency>
    </dependencies>

2.創建WebSecurityConfig

認證之前需要先校驗用戶的賬戶密碼是否正確,所以我們先配置WebSecurityConfig攔截:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    BCryptPasswordEncoder passwordEncoder;

    /**
     * @Title: 配置內存用戶驗證
     * @Param: [auth]
     * @Return: void
     * @Author: SunBin
     * @Date: 2020/5/15 18:01
     * @Throws:
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth.inMemoryAuthentication()
                .withUser("admin").password(passwordEncoder.encode("123456")).roles("ADMIN")
                .and()
                .withUser("user").password(passwordEncoder.encode("123456")).roles("USER");
    }
}

注意密碼用了BCryptPasswordEncoder進行加密,在springboot2.x中不加密會報錯

3.創建AuthConfig認證攔截處理

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
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;

@Configuration
// 開啓認證服務
@EnableAuthorizationServer
public class AuthConfig extends AuthorizationServerConfigurerAdapter {

    /**
     * @Title: 配置密碼加密,SpringBoot2.X必須
     * @Param: []
     * @Return: org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
     * @Author: SunBin
     * @Date: 2020/5/15 18:08
     * @Throws:
     */
    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    /**
     * @Title: 基於內存的配置
     * @Param: [clients]
     * @Return: void
     * @Author: SunBin
     * @Date: 2020/5/15 18:13
     * @Throws:
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception{
        clients.inMemory()
                // 客戶端ID
                .withClient("client")
                // 客戶端secret
                .secret(passwordEncoder().encode("secret"))
                // 授權類型:授權碼
                .authorizedGrantTypes("authorization_code")
                // 範圍
                .scopes("app")
                // 重定向地址
                .redirectUris("http://127.0.0.1:8848/nacos/");
    }
}
  • 添加 @EnableAuthorizationServer註解開啓認證服務,注入加密用的BCryptPasswordEncoder實例。
  • 配置需要認證的客戶端,client_id是需要認證的服務
  • 客戶端的secret祕鑰需要加密
  • authorizedGrantTypes授權方式指的是授權碼,簡單,客戶端,賬戶密碼等,這裏使用的是授權碼(authorization_code)
  • 配置scopes範圍
  • redirectUris重定向地址,就是授權後跳轉的地址。

4.配置文件:

bootstrap.yml

# 項目設置
spring:
    profiles:
        active: local  # 默認激活文件
    application:
        name: auth-server

 bootstrap-local.yml

# 設置服務
server:
    port: 10410

# 項目設置
spring:
    cloud:
        nacos:
            discovery:
                server-addr: 127.0.0.1:8848
            config:
                server-addr: 127.0.0.1:8848
                file-extension: yaml
        sentinel:
            transport:
                dashboard: localhost:8080

# 使用默認日誌slf4
logging:
    level:
        com.sunber: DEBUG  # 可以按包顯示不同的級別
    file: F://###LOGS/Sunber/Auth/AuthServer/out.log  # 不指定目錄則輸出到當前項目下

 

 

5.啓動類

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;

@SpringCloudApplication
@EnableFeignClients(basePackages = {"com.sunber.**"})
@ComponentScan(basePackages= {"com.sunber"})
public class AuthServer {

    public static void main(String[] args) {
        SpringApplication.run(AuthServer.class, args);
    }
}

6.啓動應用:

 

成功,我們用這個地址進行授權訪問:http://localhost:10410/oauth/authorize?client_id=client&response_type=code
成功後,跳轉到登錄頁面:

 

輸入賬戶:admin 密碼: 123456 點登錄

選擇approve點擊Authorize認證

 

這個code就是授權碼
postman用post方式獲取access_token,請求URL:http://client:secret@localhost:10410/oauth/token

  • 這個client就是配置的client_id
  • secret就是配置的secret
  • 返回access_token

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章