spring-security-oauth2 密码模式

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 # 连接超时时间(毫秒)
复制代码

 

配置授权服务器:

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

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
/**
 * 自定义类继承自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做登录认证
    }
}

  

配置资源服务器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@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:

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
@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

 

posted @   草木物语  阅读(853)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示