• spring security oauth2


    package com.example.oauth.config;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.http.HttpMethod;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.http.SessionCreationPolicy;
    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;
    import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
    import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
    import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
    import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
    import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
    import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
    
    @Configuration
    public class OAuth2ServerConfig {
    
        private static final String DEMO_RESOURCE_ID = "order";
    
        // 资源服务器配置
        @Configuration
        @EnableResourceServer
        protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
    
            @Override
            public void configure(ResourceServerSecurityConfigurer resources) {
                resources.resourceId(DEMO_RESOURCE_ID).stateless(true);
            }
    
            @Override
            public void configure(HttpSecurity http) throws Exception {
                // @formatter:off
                http
                        // Since we want the protected resources to be accessible in the UI as well we need
                        // session creation to be allowed (it's disabled by default in 2.0.6)
                        .sessionManagement()
                        .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
    
                        .and()
                        .requestMatchers()
                        .anyRequest()
    
                        .and()
                        .anonymous()
    
                        .and()
                        .authorizeRequests()
    //                    .antMatchers("/product/**").access("#oauth2.hasScope('select') and hasRole('ROLE_USER')")
                        .antMatchers("/private/**")//配置访问控制,必须认证过后才可以访问
                        .authenticated();
                // @formatter:on
            }
        }
    
        // oauth 2 配置信息
        @Configuration
        @EnableAuthorizationServer
        protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
    
            @Autowired
            AuthenticationManager authenticationManager;
            @Autowired
            RedisConnectionFactory redisConnectionFactory;
            @Autowired
            private BCryptPasswordEncoder bCryptPasswordEncoder;
    
            @Override
            public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
                //配置两个客户端,模拟第三方应用
                clients.inMemory()
                        // 凭证方式 , 适用于没有前端的命令行应用
                        .withClient("client_1")
                        .resourceIds(DEMO_RESOURCE_ID)
                        .authorizedGrantTypes("client_credentials", "refresh_token")
                        .scopes("select")
                        .authorities("client")
                        .secret(bCryptPasswordEncoder.encode("123"))
    
                        // 密码的方式去认证
                        .and().withClient("client_2")
                        .resourceIds(DEMO_RESOURCE_ID)
                        .authorizedGrantTypes("password", "refresh_token")
                        .scopes("select")//作用域(Scopes): 客户请求访问令牌时,有资源拥有者额外指定的细分权限(permission)
                        .authorities("client")
                        .secret(bCryptPasswordEncoder.encode("123"));
            }
    
            @Override
            public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
                endpoints
                        // token 的保存方式
                        .tokenStore(new RedisTokenStore(redisConnectionFactory))
                        // 允许 GET、POST 请求获取 token,即访问端点:oauth/token
                        .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
                        //token里加点信息
    //                    .tokenEnhancer(tokenEnhancerChain)
                        .authenticationManager(authenticationManager);
            }
    
            @Override
            public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
                //允许表单认证
                oauthServer.allowFormAuthenticationForClients();
            }
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    package com.example.oauth.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    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;
    
    /**
     * @Description: spring security配置
     * @Author: yanhonghai
     * @Date: 2019/4/18 0:38
     */
    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        /**
         * 对应密码模式,内存中新建2个用户;实际用数据库查询
         *
         * @return
         */
        @Bean
        @Override
        protected UserDetailsService userDetailsService() {
            // 内存 , 实现了登录的接口
            InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
            manager.createUser(User.withUsername("zhangsan")
                    .password(this.passwordEncoder().encode("123"))
                    .authorities("client")
                    .build());
            manager.createUser(User.withUsername("user_2")
                    .password(this.passwordEncoder().encode("123"))
                    .authorities("USER")
                    .build());
            return manager;
        }
        // http 请求的权限配置 , 和 路径, 和 处理器
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            http
                .requestMatchers()
                .anyRequest()
                .and()
                .authorizeRequests()
                .antMatchers("/oauth/*")
                .permitAll();//生产token的url允许任何登录的用户访问
            // @formatter:on
        }
        // 鉴权管理器
        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
        // 加密器
        @Bean
        public BCryptPasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    package com.example.oauth.controller;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;
    
    
    
    /**
    * 1.测试需要启动redis,
    * 2.直接get访问localhost:8080/public/1  localhost:8080/private/1
    * 3.使用http工具post访问password模式
    * http://localhost:8080/oauth/token?username=zhangsan&password=123&grant_type=password&scope=select&client_id=client_2&client_secret=123
    * 使用http工具post访问client模式http://localhost:8080/oauth/token?grant_type=client_credentials&scope=select&client_id=client_1&client_secret=123
    * 4.再次get访问http://localhost:8080/private/1?access_token=bd77315b-5f83-433f-a4aa-b9f20b89ff34
    * http://localhost:8080/private/1?access_token=d6912dd2-347d-4e64-98a3-922380dab7a0
    * @author chentong
    * @date 2021/12/1
    */
    @RestController
    public class TestController {
        private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
        @GetMapping("/public/{id}")
        public String getProduct(@PathVariable String id) {
            logger.info("当前用户认证信息:{}", SecurityContextHolder.getContext().getAuthentication());
            return "public id: " + id;
        }
    
        @GetMapping("/private/{id}")
        public String getOrder(@PathVariable String id) {
            logger.info("当前用户认证信息:{}", SecurityContextHolder.getContext().getAuthentication());
            return "private id: " + id;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    
    @EnableResourceServer
    @SpringBootApplication
    public class OauthApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(OauthApplication.class, args);
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    spring.redis.host=localhost
    spring.redis.database=0
    spring.redis.port=6379
    spring.redis.password=123456
    #filter ����˳��,�������,���ز���
    security.oauth2.resource.filter-order=3
    logging.level.org.springframework.security: DEBUG
    
    server.port=8083
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    readme
    1.测试需要启动redis
    
    2.直接get访问
        localhost:8080/public/1    这个路径能通过  
        localhost:8080/private/1   这个路径不放行,需要认证
    
    3.使用http工具post访问password模式
        http://localhost:8080/oauth/token?username=zhangsan&password=123&grant_type=password&scope=select&client_id=client_2&client_secret=123456
    
    使用http工具post访问client模式
        http://localhost:8080/oauth/token?grant_type=client_credentials&scope=select&client_id=client_1&client_secret=123456
    
    4.再次带上获取的tokenget访问 , get 请求
        http://localhost:8080/private/1?access_token=bd77315b-5f83-433f-a4aa-b9f20b89ff34
    或者
        http://localhost:8080/private/1?access_token=d6912dd2-347d-4e64-98a3-922380dab7a0
    
    这里的token 是上面任意种方式获取的 token
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
  • 相关阅读:
    泛微OA表说明
    微服务架构之:基于Redis的分布式锁优化(Redisson)
    玩转Mysql系列 - 第23篇:mysql索引管理详解
    1836: 【USACO】Buying Feed(购买饲料)
    数据库设计(火车订票系统)
    Verilog HDL复习总结
    GO语言容器大全(附样例代码)
    Nginx配置高可用集群
    toString和valueOf
    Composition API(常用部分)
  • 原文地址:https://blog.csdn.net/qq_22555107/article/details/125418397