美文网首页
Spring cloud oauth2 研究--第一个DEMO

Spring cloud oauth2 研究--第一个DEMO

作者: 输入昵称就行 | 来源:发表于2019-05-11 23:40 被阅读0次

    OAuth2简介

    OAuth2是一个基于令牌的安全验证和授权框架,主要分为四个部分

    1)资源所有者

    定义哪些应用程序可以调用其服务,哪些用户可以访问该服务,以及他们可以使用该服务完成哪些事情。(应用与用户都可以是资源所有者)

    2)受保护的资源

    这是开发人员想要保护的资源,只有通过授权的用户才能够访问,比如商品服务、库存服务, 资源所有者从资源服务器获取的资源

    3)应用程序

    代表用户调用服务的应用程序,也就是client端。

    4)OAuth2验证服务器 EnableAuthorizationServer

    验证服务器是应用程序介于应用程序于访问的服务的中介,Oauth2验证服务允许用户对自己进行验证,而不必将用户凭证传递到调用的每个服务。可以理解为用户在访问一个商品服务之前,通过Oauth2进行验证,然后得到token,通过token从Oauth2资源服务器获取到登陆信息将有限的信息传递下去,不必将用户名密码之类的信息传递下去

    图片来源https://deepzz.com/post/what-is-oauth2-protocol.html

    oauth2roles.jpg

    OAuth2 授权模式

    • 密码模式 password
    • 客户端凭据 client credential
    • 授权码 authorization code
    • 隐式 implicit
    密码模式 password

    密码模式一般用于都是可信的的情况,也就是说资源所有者,资源服务器,授权服务都是一家的

    1. 创建一个oauth2验证服务
      pom依赖
    <!--spring boot 版本-->
    <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.4.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
    </parent>
    .....
     <!--作为资源服务获取用户信息需要的依赖-->
     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
     <!--作为验证服务包含了security 和 oauth2-->
     <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-oauth2</artifactId>
     </dependency>
     
    

    AuthServerApplication .java

    @SpringBootApplication
    @RestController
    @EnableAuthorizationServer // 告诉springcloud该服务是oauth2鉴权服务
    @EnableResourceServer  // 告诉springcloud该服务是oauth2也是资源服务,为了保护该类内的/user接口
    public class AuthServerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(AuthServerApplication.class, args);
        }
    
        @RequestMapping(value = {"/user"}, produces = "application/json")
        public Map<String, Object> user(OAuth2Authentication user) {
    
            Map<String, Object> userInfo = new HashMap<>();
            userInfo.put("user", user.getUserAuthentication().getPrincipal());
            userInfo.put("authorities", AuthorityUtils.authorityListToSet(user.getUserAuthentication().getAuthorities()));
            return userInfo;
        }
    }
    
    

    OAuth2Config

    @Configuration
    public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
    
        @Autowired
        private AuthenticationManager authenticationManager;
    
        @Autowired
        private UserDetailsService userDetailsService;
    
    
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            // 定义哪些客户端可以注册到了服务
            clients.inMemory()
                    .withClient("clientId")
                    .secret("{noop}clientSecret")
            // 支持的授权模式 密码模式和客户端凭证           
                    .authorizedGrantTypes("refresh_token", "password", "client_credentials")  
            // 定义访问作用域,也就是当用户使用某一个scope授权之后,可以根据不同的scope封装不同的user信息,比如webclient会封装角色,mobileclient封装角色和资源api,由开发人员定义即可
                    .scopes("webclient", "mobileclient");  
        }
    
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        // 使用默认的验证管理器和用户信息服务
            endpoints.authenticationManager(authenticationManager)
                    .userDetailsService(userDetailsService);
        }
    }
    
    

    WebSecurityConfig

    @Configuration
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception{
            return super.authenticationManagerBean();
        }
    
        @Override
        @Bean
        public UserDetailsService userDetailsServiceBean() throws Exception {
            return super.userDetailsServiceBean();
        }
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication()
                    .withUser("user")
                    .password("{noop}password1")
                    .roles("USER")
                    .and()
                    .withUser("admin")
                    .password("{noop}password2")
                    .roles("USER", "ADMIN");
        }
    }
    
    1. 测试授权接口

    使用postman测试
    url: http://localhost:port/oauth/token

    1.使用authentication的方式

    参数1.png
    2.使用 Header的方式

    Authentication: Basic base64(clientId:clientSecret)

    header.png
    以上二选一

    ** form表单参数,密码授权模式 **


    参数2.png

    响应结果

    {
        "access_token": "0b9bb396-e7fb-43f1-a580-50ea28ff90dc",
        "token_type": "bearer",
        "refresh_token": "efdbc090-ced6-4e07-a0f9-fdbd5241ba0e",
        "expires_in": 42723,
        "scope": "webclient"
    }
    

    最基本的oauth2服务搭建完毕

    客户端凭据 client credential

    一般是用于没有用户的客户端进行授权的方式,通过clientId clientSecret进行授权

    授权码 authorization code

    授权码模式一般用于,提供第三方授权的情况,比如微信提供的第三方登陆等,再比如leecode提供github登陆这种情况,
    也就是说微信提供了一个统一第三方登陆平台,所有需要的接入方,注册到了微信就能够通过授权码授权

    隐式 implicit

    没有刷新token
    待续具体的使用场景

    相关文章

      网友评论

          本文标题:Spring cloud oauth2 研究--第一个DEMO

          本文链接:https://www.haomeiwen.com/subject/npcqaqtx.html