Spring Boot Security Oauth 2のクライアントモードとパスワードモード実現

12661 ワード

Spring Boot Security Oauth 2のクライアントモードとパスワードモード実現
サンプルの主な内容
  • 1.マルチ認証モード(パスワードモード、クライアントモード)
  • 2.tokenはredisサポート
  • に保存されます.
  • 3.リソース保護
  • 4.パスワード・モード・ユーザーおよびアクセス権のデータベースへの保存
  • 5.使用説明
  • サンプルコード-github
    紹介する
    oauth 2 client credentialsクライアントモード取得access_tokenプロセス
    クライアント・モード(Client Credentials Grant)とは、ユーザーの名義ではなく、クライアントが独自の名義で「サービス・プロバイダ」に認証することを意味します.厳密には、クライアント・モードはOAuthフレームワークが解決すべき問題ではない.このモードでは、ユーザーは直接クライアントに登録し、クライアントは自分の名義で「サービスプロバイダ」にサービスを提供するように要求しますが、ライセンスの問題はありません.
  • (A)クライアントは認証サーバに認証を行い、アクセストークンを要求する.クライアントから発行されたHTTPリクエストには、granttype:認証タイプを表し、ここでの値は「clientcredentials」に固定され、必須オプションが含まれます.scope:権限範囲を表し、オプションです.
  • (B)認証サーバはエラーがないことを確認した後、クライアントにアクセストークンを提供する.

  • oauth 2 passwordパスワードモード取得access_tokenプロセス
    パスワードモード(Resource Owner Password Credentials Grant)では、ユーザーはクライアントに自分のユーザー名とパスワードを提供します.クライアントは、これらの情報を使用して、サービスプロバイダに権限を要求します.このモードでは、ユーザは自分のパスワードをクライアントに渡さなければならないが、クライアントはパスワードを保存してはならない.これは、通常、クライアントがオペレーティングシステムの一部であるか、有名な会社が出品しているかのように、ユーザがクライアントを信頼している場合に使用されます.認証サーバは、他の認証モードが実行できない場合にのみ、このモードを使用することを考慮します.
  • (A)ユーザはクライアントにユーザ名とパスワードを提供する.
  • (B)クライアントは、認証サーバにユーザ名とパスワードを送信し、後者にトークンを要求する.クライアントからのHTTPリクエスト.grant_type:ライセンスタイプを表します.ここでの値は「password」に固定され、必須です.username:ユーザー名、必須オプションを表します.password:ユーザーのパスワード、必須オプションを表します.scope:権限範囲を表し、オプションです.
  • (C)認証サーバはエラーがないことを確認した後、クライアントにアクセストークンを提供する.

  • Oauth 2が提供するデフォルトのエンドポイント(endpoints)
  • /oauth/authorize:承認エンドポイント
  • /oauth/token:トークンエンドポイント
  • /oauth/confirm_アクセス:ユーザー確認認証コミットエンドポイント
  • /oauth/error:認証サービスエラー情報エンドポイント
  • /oauth/check_token:リソース・サービス・アクセスのためのトークン解析エンド・ポイント
  • /oauth/token_key:JWTトークンを使用する場合
  • 使用例の説明
    1.エンドモード取得アクセス_token
    http://localhost:8080/oauth/token?grant_type=client_credentials&scope=select&client_id=client_1&client_secret=123456
    結果を返す
    {
        "access_token": "67a2c8f6-bd08-4409-a0d6-6ba61a4be950",
        "token_type": "bearer",
        "expires_in": 41203,
        "scope": "select"
    }

    2.パスワードモード取得アクセス_token
    http://localhost:8080/oauth/token?username=user&password=123456&grant_type=password&scope=select&client_id=client_2&client_secret=123456
    結果を返す
    {
        "access_token": "b3d2c131-1225-45b4-9ff5-51ec17511cee",
        "token_type": "bearer",
        "refresh_token": "8495d597-0560-4598-95ef-143c0855363c",
        "expires_in": 42417,
        "scope": "select"
    }

    3.アクセスの更新token
    http://localhost:8080/oauth/token?grant_type=refresh_token&refresh_token=8495d597-0560-4598-95ef-143c0855363c&client_id=client_2&client_secret=123456
    結果を返す
    {
        "access_token": "63de6c71-672f-418c-80eb-0c9abc95b67c",
        "token_type": "bearer",
        "refresh_token": "8495d597-0560-4598-95ef-143c0855363c",
        "expires_in": 43199,
        "scope": "select"
    }

    4.保護されたリソースへのアクセス
    http://localhost:8080/order/1?access_token=b3d2c131-1225-45b4-9ff5-51ec17511cee
    データを正しく返す
    Spring security oauth 2コードプロシージャ
    Security oauth 2統合の3つのコア構成クラス
  • 1.リソース・サービス構成ResourceServer Configure
  • 2.AuthorizationServerConfiguration
  • の認証サービス構成
  • 3.Security構成SecurityConfiguration
  • 1.pom.xml maven依存性の追加
        
            
                org.springframework.boot
                spring-boot-starter-security
            
    
            
                org.springframework.security.oauth
                spring-security-oauth2
                2.3.6.RELEASE
            
    
            
                org.springframework.boot
                spring-boot-starter-web
            
    
            
                org.springframework.boot
                spring-boot-starter-data-redis
            
    
            
                org.springframework.boot
                spring-boot-starter-thymeleaf
            
    
            
                org.springframework.boot
                spring-boot-starter-test
                test
            
    
            
                mysql
                mysql-connector-java
                8.0.17
            
    
            
                com.baomidou
                mybatis-plus-boot-starter
                3.1.2
            
    
            
                org.projectlombok
                lombok
                true
            
    
            
                cn.hutool
                hutool-all
                4.6.1
                test
            
        

    主にsecurity、oauth 2、redis、mysql、mybatis-plusなどのコンポーネントを使用しています
    2.認証権限設定AuthorizationServerConfigurerAdapter.java
    @Configuration
    @EnableAuthorizationServer
    public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    
        private static final String RESOURCE_IDS = "order";
    
        @Autowired
        AuthenticationManager authenticationManager;
    
        @Autowired
        RedisConnectionFactory redisConnectionFactory;
    
        @Autowired
        private UserDetailsService userDetailsService;
    
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    
            String finalSecret = "{bcrypt}" + new BCryptPasswordEncoder().encode("123456");
            //       ,    password      client  
            clients.inMemory()
    
                    //client  
                    .withClient("client_1")
                    .resourceIds(RESOURCE_IDS)
                    .authorizedGrantTypes("client_credentials", "refresh_token")
                    .scopes("select")
                    .authorities("oauth2")
                    .secret(finalSecret)
    
                    .and()
    
                    //    
                    .withClient("client_2")
                    .resourceIds(RESOURCE_IDS)
                    .authorizedGrantTypes("password", "refresh_token")
                    .scopes("select")
                    .authorities("oauth2")
                    .secret(finalSecret);
        }
    
        /**
         *         
         */
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
            endpoints
                    //    
                    .userDetailsService(userDetailsService)
                    //token  redis
                    .tokenStore(new RedisTokenStore(redisConnectionFactory))
                    //  oauth2  
                    .authenticationManager(authenticationManager)
                    //  GET POST
                    .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
        }
    
        @Override
        public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
            oauthServer.allowFormAuthenticationForClients();
        }
    }

    3.リソース構成ResourceServer Config.java
    @Configuration
    @EnableResourceServer
    public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    
        private static final String RESOURCE_IDS = "order";
    
        @Override
        public void configure(ResourceServerSecurityConfigurer resources) {
            resources.resourceId(RESOURCE_IDS).stateless(true);
        }
    
        @Override
        public void configure(HttpSecurity httpSecurity) throws Exception {
            httpSecurity
                    .authorizeRequests()
                    .antMatchers("/order/**").authenticated();      //  order    ,           
    
        }
    }

    4.パスワードモードのユーザーおよび権限がデータベースに保存されています.java
    
    @Service
    public class UserDetailsServiceImpl implements UserDetailsService {
    
        @Autowired
        private UserServiceImpl userService;
    
        /**
         *   UserDetailsService  loadUserByUsername  ,        
         */
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            User user = userService.queryUserByUsername(username);
            if (user == null) {
                throw new UsernameNotFoundException("     ");
            }
    
            //      
            Collection extends GrantedAuthority> authorities = userService.queryUserAuthorities(user.getId());
    
            return new AuthUser(
                    user.getId(),
                    user.getUsername(),
                    user.getPassword(),
                    true,
                    true,
                    true,
                    true,
                    authorities);
        }
    }
    

    5.WebSecurityConfig構成
    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Bean
        PasswordEncoder passwordEncoder() {
            return PasswordEncoderFactories.createDelegatingPasswordEncoder();
        }
    
        /**
         *   AuthenticationManager  ,  OAuth2    
         *
         * @return
         * @throws Exception
         */
        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            AuthenticationManager manager = super.authenticationManagerBean();
            return manager;
        }
    
        /**
         *   HttpSecurity  Security        
         *
         * @param httpSecurity
         * @throws Exception
         */
        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
            httpSecurity
                    .requestMatchers().anyRequest()
                    .and()
                    .authorizeRequests()
                    .antMatchers("/oauth/**").permitAll();
        }
    }

    6.application.yml構成
    server:
      port: 8080
    
    spring:
      thymeleaf:
        encoding: UTF-8
        cache: false
    
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/easy_web?useSSL=false&serverTimezone=UTC
        username: root
        password: 123456
    
      redis:
        host: 127.0.0.1
        port: 6379
        password:
    
    logging.level.org.springframework.security: DEBUG

    7.inital.sqlデータベース初期化スクリプト
    DROP TABLE IF EXISTS `user`;
    DROP TABLE IF EXISTS `role`;
    DROP TABLE IF EXISTS `user_role`;
    DROP TABLE IF EXISTS `role_permission`;
    DROP TABLE IF EXISTS `permission`;
    
    CREATE TABLE `user` (
    `id` bigint(11) NOT NULL AUTO_INCREMENT,
    `username` varchar(255) NOT NULL,
    `password` varchar(255) NOT NULL,
    PRIMARY KEY (`id`) 
    );
    CREATE TABLE `role` (
    `id` bigint(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) NOT NULL,
    PRIMARY KEY (`id`) 
    );
    CREATE TABLE `user_role` (
    `id` bigint(11) NOT NULL AUTO_INCREMENT,
    `user_id` bigint(11) NOT NULL,
    `role_id` bigint(11) NOT NULL,
    PRIMARY KEY (`id`)
    );
    CREATE TABLE `role_permission` (
    `id` bigint(11) NOT NULL AUTO_INCREMENT,
    `role_id` bigint(11) NOT NULL,
    `permission_id` bigint(11) NOT NULL,
    PRIMARY KEY (`id`)
    );
    CREATE TABLE `permission` (
    `id` bigint(11) NOT NULL AUTO_INCREMENT,
    `url` varchar(255) NOT NULL,
    `name` varchar(255) NOT NULL,
    `description` varchar(255) NULL,
    `pid` bigint(11) NOT NULL,
    PRIMARY KEY (`id`) 
    );
    
    INSERT INTO user (id, username, password) VALUES (1,'user','{bcrypt}$2a$10$Tme77eHtXzcB8ghQUepYguJr7P7ESg0Y7XHMnk60s.kf2A.BWBD9m');
    INSERT INTO user (id, username , password) VALUES (2,'admin','{bcrypt}$2a$10$Tme77eHtXzcB8ghQUepYguJr7P7ESg0Y7XHMnk60s.kf2A.BWBD9m');
    INSERT INTO role (id, name) VALUES (1,'USER');
    INSERT INTO role (id, name) VALUES (2,'ADMIN');
    INSERT INTO permission (id, url, name, pid) VALUES (1,'/user/common','common',0);
    INSERT INTO permission (id, url, name, pid) VALUES (2,'/user/admin','admin',0);
    INSERT INTO user_role (user_id, role_id) VALUES (1, 1);
    INSERT INTO user_role (user_id, role_id) VALUES (2, 1);
    INSERT INTO user_role (user_id, role_id) VALUES (2, 2);
    INSERT INTO role_permission (role_id, permission_id) VALUES (1, 1);
    INSERT INTO role_permission (role_id, permission_id) VALUES (2, 1);
    INSERT INTO role_permission (role_id, permission_id) VALUES (2, 2);

    以上の7つのステップを経て、Oauth 2のパスワードモードと顧客モード機能を迅速に実現しました.
    資料
  • サンプルコード-github
  • チェン一峰理解OAuth 2.0