• springsecurityoauth2 密码模式


    OAuth 2

    添加依赖:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security.oauth</groupId>
        <artifactId>spring-security-oauth2</artifactId>
        <version>2.3.3.RELEASE</version>
    </dependency>
    <!--redis依赖配置-->
    <!--<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
        <exclusions>
            <exclusion>
                <groupId>io.lettuce</groupId>
                <artifactId>lettuce-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
    </dependency>

    由于Spring Boot中的OAuth协议是在Spring Security的基础上完成的,因此首先要添加Spring Security依赖,

    要用到OAuth 2,因此添加OAuth 2相关依赖,

    令牌可以存储在Redis缓存服务器上,同时Redis具有过期等功能,很适合令牌的存储,因此也加入Redis依赖。

    配置Redis服务器的连接信息:

    spring:
      redis:
        host: localhost # Redis服务器地址
        database: 0 # Redis数据库索引(默认为0)
        port: 6379 # Redis服务器连接端口
        password: # Redis服务器连接密码(默认为空)
        jedis:
          pool:
            max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
            max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
            max-idle: 8 # 连接池中的最大空闲连接
            min-idle: 0 # 连接池中的最小空闲连接
        timeout: 3000ms # 连接超时时间(毫秒)

    配置授权服务器:

    授权服务器和资源服务器可以是同一台服务器,也可以是不同服务器,本案例中假设是同一台服务器,通过不同的配置分别开启授权服务器和资源服务器,首先是授权服务器:

    /**
     * 自定义类继承自AuthorizationServerConfigurerAdapter,完成对授权服务器的配置
     */
    @Configuration
    @EnableAuthorizationServer // 通过@EnableAuthorizationServer注解开启授权服务器
    public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    
        @Autowired
        AuthenticationManager authenticationManager; // 该对象将用来支持password模式
        @Autowired
        RedisConnectionFactory redisConnectionFactory; // 该对象将用来完成Redis缓存,将令牌信息存储到Redis缓存中。
        @Autowired
        UserDetailsService userDetailsService; // 该对象将为刷新token提供支持
    
        @Bean
        PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.inMemory()
                    .withClient("password")
                    /*
                     * 表示OAuth 2中的授权模式为“password”和“refresh_token”两种
                     * 在标准的OAuth 2协议中,授权模式并不包括“refresh_token”,但是在Spring Security的实现中将其归为一种,
                     * 因此如果要实现access_token的刷新,就需要添加这样一种授权模式
                     */
                    .authorizedGrantTypes("password", "refresh_token")
                    .accessTokenValiditySeconds(1800) // 配置了access_token的过期时间
                    .resourceIds("rid") // resourceIds配置了资源id
                    .scopes("all")
                    .secret("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq");//secret方法配置了加密后的密码,明文是123
        }
    
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
            /*
             * 配置了令牌的存储,AuthenticationManager和UserDetailsService主要用于支持password模式以及令牌的刷新。
             */
            endpoints.tokenStore(new RedisTokenStore(redisConnectionFactory))
                    .authenticationManager(authenticationManager)
                    .userDetailsService(userDetailsService);
        }
    
        @Override
        public void configure(AuthorizationServerSecurityConfigurer security) {
            security.allowFormAuthenticationForClients();// 表示支持client_id和client_secret做登录认证
        }
    }
    

      

    配置资源服务器:

    @Configuration
    @EnableResourceServer // @EnableResourceServer注解开启资源服务器配置
    public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    
        @Override
        public void configure(ResourceServerSecurityConfigurer resources) {
            // 配置资源id,这里的资源id和授权服务器中的资源id一致,然后设置这些资源仅基于令牌认证。
            resources.resourceId("rid").stateless(true);
        }
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .antMatchers("/admin/**").hasRole("admin")
                    .antMatchers("/user/**").hasRole("user")
                    .anyRequest().authenticated();
        }
    }
    

      

    配置Security:

    @Configuration
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        // 这里两个Bean将注入授权服务器配置类中使用
        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
    
        @Bean
        @Override
        protected UserDetailsService userDetailsService() {
            return super.userDetailsService();
        }
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication()
                    .withUser("admin")
                    .password("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq")
                    .roles("admin")
                    .and()
                    .withUser("sang")
                    .password("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq")
                    .roles("user");
        }
    
        /**
         * 在Spring Security配置和资源服务器配置中,一共涉及两个HttpSecurity,
         * 其中Spring Security中的配置优先级高于资源服务器中的配置,即请求地址先经过Spring Security的HttpSecurity,再经过资源服务器的HttpSecurity。
         */
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/oauth/**").authorizeRequests()
                    .antMatchers("/oauth/**").permitAll()//这里的HttpSecurity配置主要是配置“/oauth/**”模式的URL,这一类的请求直接放行
                    .and().csrf().disable();
        }
    }
    

      

    测试验证:

    启动Redis服务器,再启动Spring Boot项目,首先发送一个POST请求获取token,请求地址如下

    POST http://127.0.0.1:8081/oauth/token?username=sang&password=123&grant_type=password&client_id=password&scope=all&client_secret=123

    当access_token过期后,使用refresh_token重新获取新的access_token(前提是refresh_token未过期),请求地址如下

    POST http://127.0.0.1:8081/oauth/token?grant_type=refresh_token&refresh_token=6b80de74-e264-4ca5-b 9cc-20e8a6fa486d&client_id=password&client_secret=123

    接下来访问资源,携带上access_token参数即可

    GET http://127.0.0.1:8081/user/hello?access_token=4c0ab1bd-5e01-4420-aa79-a4acf79fe7d2

    文章来源: Spring Boot+Vue全栈开发实战 - 10.4 OAuth 2

  • 相关阅读:
    Redis缓存穿透,缓存击穿,缓存雪崩
    Redis持久化机制
    Docker小白到实战之常用命令演示,通俗易懂
    分布式事务最终一致性-CAP框架轻松搞定
    gRPC四种模式、认证和授权实战演示,必赞~~~
    Docker小白到实战之开篇概述
    郑州 | 7月20日,想想都后怕
    避不开的分布式事务
    c++实现十大经典排序算法
    浏览器缓存机制总结
  • 原文地址:https://www.cnblogs.com/ooo0/p/16404191.html
Copyright © 2020-2023  润新知