SpringBoot+SpringSecurity+SpringCloudOauth2授权码模式使用(一)

什么是Oauth2

OAuth 2 是一种授权框架,允许第三方应用通过用户授权的形式访问服务中的用户信息,最常见的场景是授权登录;再复杂一点的比如第三方应用通过 Github 给开发者提供的接口访问权限内的用户信息或仓库信息。OAuth2 广泛应用于 web 、桌面应用、移动 APP 的第三方服务提供了授权验证机制,以此实现不同应用间的数据访问权限。 下面分别从不同角色、授权类型、使用场景及流程的纬度详细介绍 OAuth2

OAuth Roles

OAuth 定义了四种角色:

  • 资源拥有者 (Resource Owner)
  • 客户端 (Client)
  • 资源服务器 (Resource Server)
  • 授权服务器 (Authorization Server)

授权流程

接下来文中提到的客户端均为第三方应用,服务端均为被接入的服务。譬如很多网站有微信登录功能,那么这个网站就是客户端,微信就是服务端。

在这里插入图片描述

流程图解释:

  1. 用户点击客户端提供的授权请求
  2. 客户端请求服务的授权页面呈现给用户,用户点击确认授权后服务端返回授权许可凭证给客户端
  3. 客户端通过步骤二接收到的授权许可凭证及在服务端注册的应用信息请求服务端
  4. 如果步骤三验证通过服务端则返回 access token给客户端
  5. 客户端通过第四步获取的 access token 请求服务端获取资源
  6. 如果服务端校验 access token 成功,则返回指定资源给客户端

授权模式

  • 授权码模式(authorization code)
  • 简化模式(implicit)
  • 密码模式(resource owner password credentials)
  • 客户端模式(client credentials)

构建一个资源服务器和认证服务器

相关依赖如下,springboot版本使用的是2.2.5稳定版,springcloud版本是Greenwich.SR2版本,先介绍授权码模式

<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

构建资源服务器配置类
@Configuration
@EnableResourceServer// 启动资源服务器
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()// 对相关请求进行授权
                .anyRequest()// 任意请求
                .authenticated()// 都要经过验证
                .and()
                .requestMatchers()// 设置要保护的资源
                .antMatchers("/user/**");// 保护的资源
    }
}

这里是保护的资源

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/getCurrentUser")
    public Object getCurrentUser(Authentication authentication){
		return authentication.getPrincipal();
    }
}
构建认证服务器配置类

首先得配置好当前程序的SecurityConfig

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Lazy
    @Autowired
    private UserService userService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()
                .antMatchers("/oauth/**","/login/**","/logout/**")
                .permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .formLogin()
                .permitAll()
                .and()
                .csrf()
                .disable();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
    }

    @Bean("passwordEncoder")
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }
}

相关的UserDetailsService的实现类,这里为了方便一点没有去连接数据库,不太会使用SpringSecurity的可以去查看SpringBoot+SpringSecurity整合(一)相关的合集

@Service("userService")
public class UserService implements UserDetailsService {
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        String encode = passwordEncoder.encode("123456");

        return new User(username,encode, AuthorityUtils.createAuthorityList("admin"));
    }
}

配置相关的认证服务器的配置类,一般授权服务器和资源服务器不放在一起这里为了方便放在一起去使用

@Configuration
@EnableAuthorizationServer// 启动授权服务器
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
	@Lazy
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                // 授权服务的名字
                .withClient("clients")
                // 授权码
                .secret(passwordEncoder.encode("112233"))
                // 重定向位置
                .redirectUris("http://www.baidu.com")
                // 授权范围
                .scopes("all")
                /**
                 * authorization_code 授权码模式
                 */
                .authorizedGrantTypes("authorization_code");
    }
}

启动项目

启动项目之后在浏览器中输入http://localhost:8080/oauth/authorize?response_type=code&client_id=clients&redirect_uri=http://www.baidu.com&scope=all连接地址,然后授权服务器会返回当前页面先输入登录账号和密码登录到系统中

在这里插入图片描述

然后当前服务器代表我们去访问授权服务器,返回让我们授权的页面选择Approve进行授权,

在这里插入图片描述

从百度的url地址上获取到验证码code

在这里插入图片描述

通过授权之后服务器再次通过授权码去访问认证服务器去获取access_token,这一个步骤我们通过postMan来完成因为是post请求,localhost:8081/oauth/token

在这里插入图片描述

相关参数如下:

参数名参数值
grant_typeauthorization_code(授权码模式)
client_idclients(客户端id)
redirect_urihttp://www.baidu.com
code从百度的url地址上获取的code
scopeall

在这里插入图片描述

通过send发送请求获取到了access_token的值这样就可以拿着这个token去获取到对应的值了

在这里插入图片描述

这样就可以获取到相关的值了,红色区域填相关的access_token值

在这里插入图片描述

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麦片王子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值