2.OAuth2.0实战案例

简介: 本文介绍基于Spring Boot与Spring Cloud的OAuth2安全认证实现,涵盖父工程搭建、资源服务与授权服务配置,并演示授权码、简化、密码及客户端四种模式的全流程测试,实现安全的分布式系统权限控制。

1.创建父工程

<groupId>com.itheima</groupId>
<artifactId>springboot_security_oauth</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.1.3.RELEASE</version>
  <relativePath/>
</parent>
<properties>
  <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
</properties>
<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>
<repositories>
  <repository>
    <id>spring-snapshots</id>
    <name>Spring Snapshots</name>
    <url>https://repo.spring.io/snapshot</url>
    <snapshots>
      <enabled>true</enabled>
    </snapshots>
  </repository>
  <repository>
    <id>spring-milestones</id>
    <name>Spring Milestones</name>
    <url>https://repo.spring.io/milestone</url>
    <snapshots>
      <enabled>false</enabled>
    </snapshots>
  </repository>
</repositories>

2.创建资源模块

2.1 创建工程并导入依赖

<parent>
  <artifactId>springboot_security_oauth</artifactId>
  <groupId>com.itheima</groupId>
  <version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>oauth_source</artifactId>
<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-oauth2</artifactId>
  </dependency>
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
  </dependency>
  <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.0</version>
  </dependency>
</dependencies>

2.2 创建配置文件

server:
  port: 9002
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql:///security_authority
    username: root
    password: root
  main:
    allow-bean-definition-overriding: true
mybatis:
  type-aliases-package: com.itheima.domain
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    com.itheima: debug

2.3 创建启动类

@SpringBootApplication
@MapperScan("com.itheima.mapper")
public class OAuthSourceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OAuthSourceApplication.class, args);
    }
}

2.4 创建处理器

@RestController
@RequestMapping("/product")
public class ProductController {
    @GetMapping
    public String findAll(){
        return "查询产品列表成功!";
    }
}

3.创建授权模块

3.1 创建工程并导入依赖

<parent>
  <artifactId>springboot_security_oauth</artifactId>
  <groupId>com.itheima</groupId>
  <version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>oauth_server</artifactId>
<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-oauth2</artifactId>
  </dependency>
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
  </dependency>
  <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.0</version>
  </dependency>
</dependencies>

3.2 创建配置文件

server:
  port: 9001
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql:///security_authority
    username: root
    password: root
  main:
    allow-bean-definition-overriding: true # 这个表示允许我们覆盖OAuth2放在容器中的bean对象,一定要配置
mybatis:
  type-aliases-package: com.itheima.domain
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    com.itheima: debug

3.3 创建启动类

@SpringBootApplication
@MapperScan("com.itheima.mapper")
public class OauthServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(OauthServerApplication.class, args);
    }
}

3.4 创建配置类

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Autowired
    private UserDetailsService myCustomUserService;
    @Bean
    public BCryptPasswordEncoder myPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
        //所有资源必须授权后访问
        .anyRequest().authenticated()
        .and()
        .formLogin()
        .loginProcessingUrl("/login")
        .permitAll()//指定认证页面可以匿名访问
        //关闭跨站请求防护
        .and().csrf().disable();
    }
    
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        //UserDetailsService类
        auth.userDetailsService(myCustomUserService)
        //加密策略
        .passwordEncoder(myPasswordEncoder());
    }
    
    //AuthenticationManager对象在OAuth2认证服务中要使用,提取放入IOC容器中
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

3.5 创建OAuth2授权配置类

@Configuration
@EnableAuthorizationServer
public class OauthServerConfig extends AuthorizationServerConfigurerAdapter {
    
    @Autowired
    private DataSource dataSource;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private UserDetailsService userDetailsService;
    
    //从数据库中查询出客户端信息
    @Bean
    public JdbcClientDetailsService clientDetailsService() {
        return new JdbcClientDetailsService(dataSource);
    }
    
    //token保存策略
    @Bean
    public TokenStore tokenStore() {
        return new JdbcTokenStore(dataSource);
    }
    
    //授权信息保存策略
    @Bean
    public ApprovalStore approvalStore() {
        return new JdbcApprovalStore(dataSource);
    }
    
    //授权码模式专用对象
    @Bean
    public AuthorizationCodeServices authorizationCodeServices() {
        return new JdbcAuthorizationCodeServices(dataSource);
    }
    
    //指定客户端登录信息来源
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.withClientDetails(clientDetailsService());
    }
    
    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer.allowFormAuthenticationForClients();
        oauthServer.checkTokenAccess("isAuthenticated()");
    }
    
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
        .approvalStore(approvalStore())
        .authenticationManager(authenticationManager)
        .authorizationCodeServices(authorizationCodeServices())
        .tokenStore(tokenStore());
    }
}

4.测试

4.1 授权码模式测试

在地址栏访问地址

http://localhost:9001/oauth/authorize?response_type=code&client_id=heima_one

跳转到SpringSecurity默认认证页面,提示用户登录个人账户【这里是sys_user表中的数据】

登录成功后询问用户是否给予操作资源的权限,具体给什么权限。Approve是授权,Deny是拒绝。

这里我们选择read和write都给予Approve。

点击Authorize后跳转到回调地址并获取授权码

使用授权码到服务器申请通行令牌token

重启资源服务器,然后携带通行令牌再次去访问资源服务器,大功告成!

4.2 简化模式测试

在地址栏访问地址

http://localhost:9001/oauth/authorize?response_type=token&client_id=heima_one

由于上面用户已经登录过了,所以无需再次登录,其实和上面是有登录步骤的,这时,浏览器直接返回了token

直接访问资源服务器

4.3 密码模式测试

申请token

访问资源服务器

4.4 客户端模式测试

申请token

访问资源服务

相关文章
|
IDE Java 测试技术
【IDEA】常用设置,让你更快速的编程
在使用JetBrains的进行软件开发时,了解和正确配置一些常用设置是非常重要的。IDEA的强大功能和定制性使得开发过程更加高效和舒适。在本文中,我们将介绍一些常用的IDEA设置,帮助您更好地利用IDEA进行开发。这些设置包括编辑器选项、代码样式、插件管理和键盘快捷键等。IDEA是JetBrains公司开发的一款集成开发环境(Integrated Development Environment,简称IDE),全名为。它是一个功能强大、智能化的Java开发工具。
|
8月前
|
SQL 人工智能 安全
我们用 AI Observe Stack 观测了 OpenClaw,发现 AI Agent 背后的这些隐患
本文基于 AI Observe Stack 构建的 OpenClaw 可观测系统是使用 AI 在一天内完成的。用户也可以用阿里云 SelectDB 云服务或者开源 Apache Doris 在几分钟内快速搭建起来亲身体验
1744 5
我们用 AI Observe Stack 观测了 OpenClaw,发现 AI Agent 背后的这些隐患
|
11月前
|
存储 运维 NoSQL
架构稳、低运维、按需付- Dify x 阿里云 Tablestore 解锁百亿级索引
今天,Dify 正式适配阿里云 Tablestore 向量索引能力,并依托 阿里云计算巢 提供一键部署体验。企业无需重构现有架构,即可享受极简运维、按需付费的灵活成本,以及原生支持百亿级向量检索的扩展能力,从容应对AI应用的结构化数据增长。
604 3
架构稳、低运维、按需付- Dify x 阿里云 Tablestore 解锁百亿级索引
|
7月前
|
人工智能 IDE 开发工具
重构研发基础设施:AI编程全流程落地的价值与路径
作为常年泡在代码里的开发者,想必大家都有过这样的体验:用AI插件补几行代码很快,但一到实际项目,环境配置、多任务并行、代码审查这些环节还是得靠人工一点点磨;不同的AI编程能力各有优势,切换适配却十分繁琐;团队协作时,Git操作和AI能力始终无法无缝融合。直到开源AI编程技术实现全流程落地,才发现其核心不是“写代码更快”,而是让AI深度融入研发全流程,把开发者从重复劳动中解放出来,真正实现研发模式的升级。
|
IDE Java 编译器
Java基础阶段的常见错误和解决方案
2025年Java实操学习路线(增强版)涵盖环境搭建、Java 21核心特性及基础常见错误解析。系统讲解环境配置、语法、面向对象与异常处理等典型问题,配代码示例与解决方案,助你从入门进阶到高级应用,夯实编程根基。
928 0
|
8月前
|
人工智能 数据可视化 Linux
保姆级图文教程!阿里云无影云电脑部署OpenClaw(Clawdbot)集成Skill指南
2026年,AI自动化代理工具已经深度融入日常办公与效率提升场景,OpenClaw(曾用名Clawdbot)凭借开源轻量、自然语言驱动、可扩展Skill生态等优势,成为个人与小型团队首选的AI自动化平台。它能够自主完成文件管理、信息检索、定时任务、网页操作、内容处理、邮件收发等一系列自动化工作,真正实现“一句话交给AI,剩下的让它自主执行”。
1567 4
|
10月前
|
人工智能 运维 NoSQL
|
人工智能 自然语言处理 搜索推荐
对话批改邦 | 从0到30万用户,如何抓住AI教育增长机遇
阿里云【AI访谈录】本期邀请AI创业者、批改邦创始人王庆棒,分享其团队如何通过AI技术打造教育场景下的教学助手。批改邦以作文批改切入教育行业,上线一年用户突破30万,付费转化率超30%。王庆棒围绕AI如何标准化主观评价、大模型在教育中的落地趋势、未来“杀手级AI应用”的形态等话题,分享一线实战经验。
1331 0
|
网络协议 安全 API
skynet.dispatch 使用详解
skynet.dispatch 使用详解
775 2
|
JavaScript 前端开发 容器
this、self、window、top 在 JavaScript 中的区别深入研究
在 JavaScript 开发中,`this`、`self`、`window` 和 `top` 是四个常用的概念。`this` 指向当前执行上下文的对象,其值取决于函数调用方式;`self` 在全局作用域中等同于 `window`,常用于 Web Workers;`window` 代表浏览器窗口,是全局变量的容器;`top` 指向最顶层窗口,用于判断是否在框架中。理解这些概念有助于编写健壮的代码。
661 1
this、self、window、top 在 JavaScript 中的区别深入研究