欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringSecurity+OAuth2.0?搭建認證中心和資源服務中心流程分析

 更新時間:2024年01月22日 15:03:46   作者:山河亦問安  
OAuth?2.0?主要用于在互聯(lián)網(wǎng)上安全地委托授權,廣泛應用于身份驗證和授權場景,這篇文章介紹SpringSecurity+OAuth2.0?搭建認證中心和資源服務中心,感興趣的朋友一起看看吧

1. OAuth2.0 簡介

OAuth 2.0(開放授權 2.0)是一個開放標準,用于授權第三方應用程序訪問用戶在資源所有者(用戶)的帳戶上存儲的受保護資源,而無需共享用戶憑據(jù)。OAuth 2.0 主要用于在互聯(lián)網(wǎng)上安全地委托授權,廣泛應用于身份驗證和授權場景。

以下是 OAuth 2.0 的核心概念和流程:

角色:

  • 資源所有者(Resource Owner): 擁有受保護資源的用戶。
  • 客戶端(Client): 第三方應用程序,希望訪問資源所有者的受保護資源。
  • 授權服務器(Authorization Server): 負責驗證資源所有者并頒發(fā)訪問令牌的服務器。
  • 資源服務器(Resource Server): 存儲受保護資源的服務器,它可以與授權服務器相同,也可以是不同的服務器。

授權類型:OAuth2.0協(xié)議一共支持 4 種不同的授權模式:

                授權碼模式:常見的第三方平臺登錄功能基本都是使用這種模式。

                簡化模式:簡化模式是不需要客戶端服務器參與,直接在瀏覽器中向授權服務器申請令牌(token),一般如果網(wǎng)站是純靜態(tài)頁面則可以采用這種方式。

                密碼模式:密碼模式是用戶把用戶名密碼直接告訴客戶端,客戶端使用說這些信息向授權服務器申請令牌(token)。這需要用戶對客戶端高度信任,例如客戶端應用和服務提供商就是同一家公司,自己做前后端分離登錄就可以采用這種模式。

                客戶端模式:客戶端模式是指客戶端使用自己的名義而不是用戶的名義向服務提供者申請授權,嚴格來說,客戶端模式并不能算作 OAuth 協(xié)議要解決的問題的一種解決方案,但是,對于開發(fā)者而言,在一些前后端分離應用或者為移動端提供的認證授權服務器上使用這種模式還是非常方便的。

2. 代碼搭建

2.1 認證中心(8080端口)

導入依賴

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
    </dependencies>

只需要添加兩個配置類即可

MyAuthorizationConfig類

@Configuration
@EnableAuthorizationServer
public class MyAuthorizationConfig extends AuthorizationServerConfigurerAdapter {
    /**
     * 客戶端存儲策略,這里使用內(nèi)存方式,后續(xù)可以存儲在數(shù)據(jù)庫
     */
    @Autowired
    private ClientDetailsService clientDetailsService;
    /**
     * Security的認證管理器,密碼模式需要用到
     */
    @Autowired
    private AuthenticationManager authenticationManager;
    /**
     * 配置令牌訪問的安全約束
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security
                //開啟/oauth/token_key驗證端口權限訪問
                .tokenKeyAccess("permitAll()")
                //開啟/oauth/check_token驗證端口認證權限訪問
                .checkTokenAccess("permitAll()")
                //表示支持 client_id 和 client_secret 做登錄認證
                .allowFormAuthenticationForClients();
    }
    //配置客戶端
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //內(nèi)存模式
        clients.inMemory()
                //客戶端id
                .withClient("test")
                //客戶端秘鑰
                .secret(new BCryptPasswordEncoder().encode("123456"))
                //資源id,唯一,比如訂單服務作為一個資源,可以設置多個
                .resourceIds("order")
                //授權模式,總共四種,1. authorization_code(授權碼模式)、password(密碼模式)、client_credentials(客戶端模式)、implicit(簡化模式)
                //refresh_token并不是授權模式,
                .authorizedGrantTypes("authorization_code","password","client_credentials","implicit","refresh_token")
                //允許的授權范圍,客戶端的權限,這里的all只是一種標識,可以自定義,為了后續(xù)的資源服務進行權限控制
                .scopes("all")
                //false 則跳轉到授權頁面
                .autoApprove(false)
                //授權碼模式的回調(diào)地址
                .redirectUris("http://www.baidu.com"); //可以and繼續(xù)添加客戶端
    }
    /**
     * 令牌存儲策略
     */
    @Bean
    public TokenStore tokenStore(){
        return new InMemoryTokenStore();
    }
    @Bean
    public AuthorizationServerTokenServices tokenServices() {
        DefaultTokenServices services = new DefaultTokenServices();
        //客戶端端配置策略
        services.setClientDetailsService(clientDetailsService);
        //支持令牌的刷新
        services.setSupportRefreshToken(true);
        //令牌服務
        services.setTokenStore(tokenStore());
        //access_token的過期時間
        services.setAccessTokenValiditySeconds(60 * 60 * 2);
        //refresh_token的過期時間
        services.setRefreshTokenValiditySeconds(60 * 60 * 24 * 3);
        return services;
    }
    /**
     * 授權碼模式的service,使用授權碼模式authorization_code必須注入
     */
    @Bean
    public AuthorizationCodeServices authorizationCodeServices() {
        //授權碼存在內(nèi)存中
        return new InMemoryAuthorizationCodeServices();
    }
    /**
     * 配置令牌訪問的端點
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                //授權碼模式所需要的authorizationCodeServices
                .authorizationCodeServices(authorizationCodeServices())
                //密碼模式所需要的authenticationManager
                .authenticationManager(authenticationManager)
                //令牌管理服務,無論哪種模式都需要
                .tokenServices(tokenServices())
                //只允許POST提交訪問令牌,uri:/oauth/token
                .allowedTokenEndpointRequestMethods(HttpMethod.POST);
    }
}

SecurityConfig類

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 加密算法
     */
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //todo 允許表單登錄
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginProcessingUrl("/login")
                .permitAll()
                .and()
                .csrf()
                .disable();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //從內(nèi)存中加載用戶,實際生產(chǎn)中需要從數(shù)據(jù)庫中加載
        auth.inMemoryAuthentication()
                .withUser("admin")
                .password(new BCryptPasswordEncoder().encode("123456"))
                .roles("admin");//后面可以跟and連接
    }
    /**
     * AuthenticationManager對象在OAuth2認證服務中要使用,提前放入IOC容器中
     * Oauth的密碼模式需要
     */
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

2.2 資源服務中心(8081端口)

導入依賴和認證中心相同,添加一個配置類ResourceServerConfig

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    /**
     * 配置令牌校驗服務,客戶端攜帶令牌訪問資源,作為資源端必須檢驗令牌的真?zhèn)?
     * TODO 使用JWT作為TOKEN則不必遠程調(diào)用check_token校驗
     */
    @Bean
    public RemoteTokenServices tokenServices() {
        //遠程調(diào)用授權服務的check_token進行令牌的校驗
        RemoteTokenServices services = new RemoteTokenServices();
        // /oauth/check_token 這個url是認證中心校驗的token的端點
        services.setCheckTokenEndpointUrl("http://localhost:8080/oauth/check_token");
        //客戶端的唯一id
        services.setClientId("test");
        //客戶端的秘鑰
        services.setClientSecret("123456");
        return services;
    }
    /**
     * 配置資源id和令牌校驗服務
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources)  {
        //配置唯一資源id
        resources.resourceId("order")
                //配置令牌校驗服務
                .tokenServices(tokenServices());
    }
    /**
     * 配置security的安全機制
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        //#oauth2.hasScope()校驗客戶端的權限,這個all是在客戶端中的scope
        http.authorizeRequests()
                .antMatchers("/**").access("#oauth2.hasScope('all')")
                .anyRequest().authenticated();
    }
}

測試接口

@RestController
public class TestController {
    @GetMapping("/test")
    public String hello() {
        return "hello world";
    }
}

3. 測試結果

訪問http://localhost:8080/oauth/authorize?client_id=test&response_type=code&scope=all&redirect_uri=http://www.baidu.com

登錄,賬號admin,密碼123456,然后獲取授權碼

獲取令牌

訪問資源中心

 未攜帶令牌測試結果

攜帶令牌測試結果

到此這篇關于SpringSecurity+OAuth2.0 搭建認證中心和資源服務中心的文章就介紹到這了,更多相關SpringSecurity OAuth2.0 認證中心內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java版仿QQ驗證碼風格圖片驗證碼

    Java版仿QQ驗證碼風格圖片驗證碼

    這篇文章主要為大家分享了java圖片驗證碼實例代碼,感興趣的小伙伴們可以參考一下
    2016-04-04
  • java教學筆記之對象的創(chuàng)建與銷毀

    java教學筆記之對象的創(chuàng)建與銷毀

    面向對象的編程語言使程序能夠直觀的反應客觀世界的本來面目,并且使軟件開發(fā)人員能夠運用人類認識事物所采用的一般思維方法進行軟件開發(fā),是當今計算機領域中軟件開發(fā)和應用的主流技術。
    2016-01-01
  • Java中==與equals的區(qū)別小結

    Java中==與equals的區(qū)別小結

    這篇文章主要介紹了Java中==與equals的區(qū)別小結,本文總結結論:== 與 equals()比較的內(nèi)容是不同的,equals()方式是String類中的方法,它用于比較兩個對象引用所指的內(nèi)容是否相等,而 == 比較的是兩個對象引用的地址是否相等,需要的朋友可以參考下
    2015-06-06
  • java中String的一些方法深入解析

    java中String的一些方法深入解析

    以下是對java中String的一些方法進行了詳細的分析介紹,需要的朋友可以參考下
    2013-07-07
  • Java協(xié)程編程之Loom

    Java協(xié)程編程之Loom

    這篇文章主要介紹了Java協(xié)程編程Loom的方法,需要的朋友請看下文
    2021-08-08
  • java中 Set與Map排序輸出到Writer詳解及實例

    java中 Set與Map排序輸出到Writer詳解及實例

    這篇文章主要介紹了 java中 Set與Map排序輸出到Writer詳解及實例的相關資料,需要的朋友可以參考下
    2017-03-03
  • JAVA HashMap詳細介紹和示例

    JAVA HashMap詳細介紹和示例

    我們先對HashMap有個整體認識,然后再學習它的源碼,最后再通過實例來學會使用HashMap。
    2013-11-11
  • 淺談單例模式和線程安全問題

    淺談單例模式和線程安全問題

    這篇文章主要介紹了淺談單例模式和線程安全問題,再某些特殊的情況下,存在一個類僅能用來產(chǎn)生一個唯一對象的必要性,因此需要單例模式,需要的朋友可以參考下
    2023-04-04
  • SpringBoot 過濾器與攔截器實例演示

    SpringBoot 過濾器與攔截器實例演示

    本文通過示例代碼給大家講解SpringBoot 過濾器與攔截器的相關知識,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-11-11
  • Java 獲取本機IP地址的方法的兩種方法

    Java 獲取本機IP地址的方法的兩種方法

    本文主要介紹了Java 獲取本機IP地址的方法的兩種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-01-01

最新評論