架构师之路-如何构建rest接口的安全性访问(dubbox+oatuh2+rest)

简介:

建立oauth2认证需要的数据库及数据表结构

CREATE SCHEMA IF NOT EXISTS `oauth2` DEFAULT CHARACTER SET utf8 ;

USE `oauth2` ;

 

-- -----------------------------------------------------

-- Table `oauth2`.`clientdetails`

-- -----------------------------------------------------

CREATE TABLE IF NOT EXISTS `oauth2`.`clientdetails` (

  `appId` VARCHAR(128) NOT NULL,

  `resourceIds` VARCHAR(256) NULL DEFAULT NULL,

  `appSecret` VARCHAR(256) NULL DEFAULT NULL,

  `scope` VARCHAR(256) NULL DEFAULT NULL,

  `grantTypes` VARCHAR(256) NULL DEFAULT NULL,

  `redirectUrl` VARCHAR(256) NULL DEFAULT NULL,

  `authorities` VARCHAR(256) NULL DEFAULT NULL,

  `access_token_validity` INT(11) NULL DEFAULT NULL,

  `refresh_token_validity` INT(11) NULL DEFAULT NULL,

  `additionalInformation` VARCHAR(4096) NULL DEFAULT NULL,

  `autoApproveScopes` VARCHAR(256) NULL DEFAULT NULL,

  PRIMARY KEY (`appId`))

ENGINE = InnoDB

DEFAULT CHARACTER SET = utf8;

 

 

-- -----------------------------------------------------

-- Table `oatuh2`.`oauth_access_token`

-- -----------------------------------------------------

CREATE TABLE IF NOT EXISTS `oauth2`.`oauth_access_token` (

  `token_id` VARCHAR(256) NULL DEFAULT NULL,

  `token` BLOB NULL DEFAULT NULL,

  `authentication_id` VARCHAR(128) NOT NULL,

  `user_name` VARCHAR(256) NULL DEFAULT NULL,

  `client_id` VARCHAR(256) NULL DEFAULT NULL,

  `authentication` BLOB NULL DEFAULT NULL,

  `refresh_token` VARCHAR(256) NULL DEFAULT NULL,

  PRIMARY KEY (`authentication_id`))

ENGINE = InnoDB

DEFAULT CHARACTER SET = utf8;

 

 

-- -----------------------------------------------------

-- Table `oatuh2`.`oauth_approvals`

-- -----------------------------------------------------

CREATE TABLE IF NOT EXISTS `oauth2`.`oauth_approvals` (

  `userId` VARCHAR(256) NULL DEFAULT NULL,

  `clientId` VARCHAR(256) NULL DEFAULT NULL,

  `scope` VARCHAR(256) NULL DEFAULT NULL,

  `status` VARCHAR(10) NULL DEFAULT NULL,

  `expiresAt` DATETIME NULL DEFAULT NULL,

  `lastModifiedAt` DATETIME NULL DEFAULT NULL)

ENGINE = InnoDB

DEFAULT CHARACTER SET = utf8;

 

 

-- -----------------------------------------------------

-- Table `oatuh2`.`oauth_client_details`

-- -----------------------------------------------------

CREATE TABLE IF NOT EXISTS `oauth2`.`oauth_client_details` (

  `client_id` VARCHAR(128) NOT NULL,

  `resource_ids` VARCHAR(256) NULL DEFAULT NULL,

  `client_secret` VARCHAR(256) NULL DEFAULT NULL,

  `scope` VARCHAR(256) NULL DEFAULT NULL,

  `authorized_grant_types` VARCHAR(256) NULL DEFAULT NULL,

  `web_server_redirect_uri` VARCHAR(256) NULL DEFAULT NULL,

  `authorities` VARCHAR(256) NULL DEFAULT NULL,

  `access_token_validity` INT(11) NULL DEFAULT NULL,

  `refresh_token_validity` INT(11) NULL DEFAULT NULL,

  `additional_information` VARCHAR(4096) NULL DEFAULT NULL,

  `autoapprove` VARCHAR(256) NULL DEFAULT NULL,

  PRIMARY KEY (`client_id`))

ENGINE = InnoDB

DEFAULT CHARACTER SET = utf8;

 

 

-- -----------------------------------------------------

-- Table `oatuh2`.`oauth_client_token`

-- -----------------------------------------------------

CREATE TABLE IF NOT EXISTS `oauth2`.`oauth_client_token` (

  `token_id` VARCHAR(256) NULL DEFAULT NULL,

  `token` BLOB NULL DEFAULT NULL,

  `authentication_id` VARCHAR(128) NOT NULL,

  `user_name` VARCHAR(256) NULL DEFAULT NULL,

  `client_id` VARCHAR(256) NULL DEFAULT NULL,

  PRIMARY KEY (`authentication_id`))

ENGINE = InnoDB

DEFAULT CHARACTER SET = utf8;

 

 

-- -----------------------------------------------------

-- Table `oatuh2`.`oauth_code`

-- -----------------------------------------------------

CREATE TABLE IF NOT EXISTS `oauth2`.`oauth_code` (

  `code` VARCHAR(256) NULL DEFAULT NULL,

  `authentication` BLOB NULL DEFAULT NULL)

ENGINE = InnoDB

DEFAULT CHARACTER SET = utf8;

 

 

-- -----------------------------------------------------

-- Table `oatuh2`.`oauth_refresh_token`

-- -----------------------------------------------------

CREATE TABLE IF NOT EXISTS `oauth2`.`oauth_refresh_token` (

  `token_id` VARCHAR(256) NULL DEFAULT NULL,

  `token` BLOB NULL DEFAULT NULL,

  `authentication` BLOB NULL DEFAULT NULL)

ENGINE = InnoDB

DEFAULT CHARACTER SET = utf8;

 

>>前提:  使用Maven来管理项目; spring-security-oauth的版本号为 2.0.10.RELEASE


1. 添加Maven dependencies; 以下只列出了主要的

  1.   

  2. <dependency>  

  3.     <groupId>org.springframework.securitygroupId>  

  4.     <artifactId>spring-security-coreartifactId>  

  5.     <version>${spring.security.version}version>  

  6. dependency>  

  7. <dependency>  

  8.     <groupId>org.springframework.securitygroupId>  

  9.     <artifactId>spring-security-webartifactId>  

  10.     <version>${spring.security.version}version>  

  11. dependency>  

  12. <dependency>  

  13.     <groupId>org.springframework.securitygroupId>  

  14.     <artifactId>spring-security-taglibsartifactId>  

  15.     <version>${spring.security.version}version>  

  16. dependency>  

  17. <dependency>  

  18.     <groupId>org.springframework.securitygroupId>  

  19.     <artifactId>spring-security-aclartifactId>  

  20.     <version>${spring.security.version}version>  

  21. dependency>  

  22. <dependency>  

  23.     <groupId>org.springframework.securitygroupId>  

  24.     <artifactId>spring-security-cryptoartifactId>  

  25.     <version>${spring.security.version}version>  

  26. dependency>  

  27. <dependency>  

  28.     <groupId>org.springframework.securitygroupId>  

  29.     <artifactId>spring-security-configartifactId>  

  30.     <version>${spring.security.version}version>  

  31. dependency>  

  32.   

  33. <dependency>  

  34.     <groupId>org.springframework.security.oauthgroupId>  

  35.     <artifactId>spring-security-oauth2artifactId>  

  36.     <version>1.0.5.RELEASEversion>  

  37. dependency>  


2. web.xml配置; 这一步与只使用Spring Security的配置一样.


  1. pre><pre code_snippet_id="73897" snippet_file_name="blog_20131119_2_2257675" name="code" class="html">    <filter>  

  2.         <filter-name>springSecurityFilterChainfilter-name>  

  3.         <filter-class>org.springframework.web.filter.DelegatingFilterProxyfilter-class>  

  4.     filter>  

  5.   

  6.     <filter-mapping>  

  7.         <filter-name>springSecurityFilterChainfilter-name>  

  8.         <url-pattern>/*url-pattern>  

  9.     filter-mapping>  

  10.   

  11.       

  12.     <context-param>  

  13.         <param-name>contextConfigLocationparam-name>  

  14.         <param-value>classpath:spring/*.xmlparam-value>  

  15.     context-param>  

  16.   

  17.       

  18.     <listener>  

  19.         <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>  

  20.     listener>  

  21.   

  22.       

  23.     <servlet>  

  24.         <servlet-name>hyservlet-name>  

  25.         <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>  

  26.         <load-on-startup>2load-on-startup>  

  27.     servlet>  

  28.     <servlet-mapping>  

  29.         <servlet-name>hyservlet-name>  

  30.         <url-pattern>/url-pattern>  

  31.     servlet-mapping>  


对于Spring MVC, 需要配置文件hy-servlet.xml, 该文件不是这儿关注的(忽略); 


在classpath创建spring目录, 在该目录里创建 security.xml 文件, 这是所有步骤配置的重点.


3.security.xml的配置; 重点开始.


3.1 起用注解; TokenEndpoint与AuthorizationEndpoint需要


  1. <mvc:annotation-driven/>  

  2. <mvc:default-servlet-handler/>  


3.2  TokenServices 配置


   1). TokenStore, 使用JdbcTokenStore, 将token信息存放数据库, 需要提供一个dataSource对象; 也可使用InMemoryTokenStore存于内存中

  1.   

  2. <beans:bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.JdbcTokenStore">  

  3.     <beans:constructor-arg index="0" ref="dataSource"/>  

  4. beans:bean>  


: 可以在spring-security-oauth2中找到对应的SQL脚本, 地址为https://github.com/spring-projects/spring-security-oauth/tree/master/spring-security-oauth2/src/test/resources, 目录中的schema.sql 即是. (以下不再说明SQL脚本的问题)


  2).TokenServices; 需要注入TokenStore


  1. <beans:bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">  

  2.     <beans:property name="tokenStore" ref="tokenStore"/>  

  3.     <beans:property name="supportRefreshToken" value="true"/>  

  4. beans:bean>  


      如果允许刷新token 请将supportRefreshToken 的值设置为true, 默认为不允许


3.3 ClientDetailsService 配置, 使用JdbcClientDetailsService, 也需要提供dataSource, 替换demo中直接配置在配置文件中


  1. <beans:bean id="clientDetailsService" class="org.springframework.security.oauth2.provider.JdbcClientDetailsService">  

  2.     <beans:constructor-arg index="0" ref="dataSource"/>  

  3. beans:bean>  


3.4 ClientDetailsUserDetailsService配置, 该类实现了Spring security中 UserDetailsService 接口


  1. <beans:bean id="oauth2ClientDetailsUserService"  

  2.             class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">  

  3.     <beans:constructor-arg ref="clientDetailsService"/>  

  4. beans:bean>  


3.5 OAuth2AuthenticationEntryPoint配置


  1. <beans:bean id="oauth2AuthenticationEntryPoint"  

  2.             class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"/>  


3.6 oauth2 AuthenticationManager配置; 在整个配置中,有两个AuthenticationManager需要配置


  1. <authentication-manager id="oauth2AuthenticationManager">  

  2.     <authentication-provider user-service-ref="oauth2ClientDetailsUserService"/>  

  3. authentication-manager>  


第二个AuthenticationManager用于向获取UserDetails信息, 


  1. <authentication-manager alias="authenticationManager">  

  2.     <authentication-provider user-service-ref="userService">  

  3.         <password-encoder hash="md5"/>  

  4.     authentication-provider>  

  5. authentication-manager>  


userService是一个实现UserDetailsService的Bean


3.7 OAuth2AccessDeniedHandler配置, 实现AccessDeniedHandler接口


  1. <beans:bean id="oauth2AccessDeniedHandler"  

  2.             class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler"/>  


3.8 UserApprovalHandler配置, 这儿使用DefaultUserApprovalHandler, 这里是实现client是否可信任的关键点,你可以扩展该接口来自定义approval行为


  1. <beans:bean id="oauthUserApprovalHandler" class="org.springframework.security.oauth2.provider.approval.DefaultUserApprovalHandler">  

  2. beans:bean>  


3.9 authorization-server配置, 核心


  1. <oauth2:authorization-server client-details-service-ref="clientDetailsService" token-services-ref="tokenServices"  

  2.                              user-approval-handler-ref="oauthUserApprovalHandler">  

  3.     <oauth2:authorization-code/>  

  4.     <oauth2:implicit/>  

  5.     <oauth2:refresh-token/>  

  6.     <oauth2:client-credentials/>  

  7.     <oauth2:password/>  

  8. oauth2:authorization-server>  


该元素里面的每个标签可设置每一种authorized-grant-type的行为. 如disable refresh-token的配置为


  1. <oauth2:refresh-token disabled="true"/>  


3.10 Oauth2 AccessDecisionManager配置, 这儿在默认的Spring Security AccessDecisionManager的基础上添加了ScopeVoter


  1. <beans:bean id="oauth2AccessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased">  

  2.     <beans:constructor-arg>  

  3.         <beans:list>  

  4.             <beans:bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter"/>  

  5.             <beans:bean class="org.springframework.security.access.vote.RoleVoter"/>  

  6.             <beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>  

  7.         beans:list>  

  8.     beans:constructor-arg>  

  9. beans:bean>  


3.11 resource-server配置, 这儿定义两咱不同的resource

  1.   

  2. <oauth2:resource-server id="unityResourceServer" resource-id="unity-resource" token-services-ref="tokenServices"/>  

  3.   

  4.   

  5. <oauth2:resource-server id="mobileResourceServer" resource-id="mobile-resource" token-services-ref="tokenServices"/>  


注意: 每个resource-id的值必须在对应的ClientDetails中resourceIds值中存在


3.12 ClientCredentialsTokenEndpointFilter配置, 该Filter将作用于Spring Security的chain 链条中


  1. <beans:bean id="clientCredentialsTokenEndpointFilter"  

  2.             class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">  

  3.     <beans:property name="authenticationManager" ref="oauth2AuthenticationManager"/>  

  4. beans:bean>  


3.13 /oauth/token 的http 配置, 用于监听该URL的请求, 核心


  1. <http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="oauth2AuthenticationManager"  

  2.       entry-point-ref="oauth2AuthenticationEntryPoint">  

  3.     <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY"/>  

  4.     <anonymous enabled="false"/>  

  5.     <http-basic entry-point-ref="oauth2AuthenticationEntryPoint"/>  

  6.   

  7.     <custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER"/>  

  8.     <access-denied-handler ref="oauth2AccessDeniedHandler"/>  

  9. http>  



3.14 针对不同resource的http配置, 由于上面配置了两个resource, 这儿也配置两个

  1.   

  2. <http pattern="/unity/**" create-session="never" entry-point-ref="oauth2AuthenticationEntryPoint"  

  3.       access-decision-manager-ref="oauth2AccessDecisionManager">  

  4.     <anonymous enabled="false"/>  

  5.   

  6.     <intercept-url pattern="/unity/**" access="ROLE_UNITY,SCOPE_READ"/>  

  7.   

  8.     <custom-filter ref="unityResourceServer" before="PRE_AUTH_FILTER"/>  

  9.     <access-denied-handler ref="oauth2AccessDeniedHandler"/>  

  10. http>  

  11.   

  12.   

  13. <http pattern="/m/**" create-session="never" entry-point-ref="oauth2AuthenticationEntryPoint"  

  14.       access-decision-manager-ref="oauth2AccessDecisionManager">  

  15.     <anonymous enabled="false"/>  

  16.   

  17.     <intercept-url pattern="/m/**" access="ROLE_MOBILE,SCOPE_READ"/>  

  18.   

  19.     <custom-filter ref="mobileResourceServer" before="PRE_AUTH_FILTER"/>  

  20.     <access-denied-handler ref="oauth2AccessDeniedHandler"/>  

  21. http>  


注意每一个http对应不同的resourceServer. access-decison-manager-ref对应Oauth的AccessDecisionManager



3.15 默认的http配置,给/oauth/** 设置权限



  1. <http access-denied-page="/login.jsp?authorization_error=2" disable-url-rewriting="true"  

  2.       authentication-manager-ref="authenticationManager">  

  3.     <intercept-url pattern="/oauth/**" access="ROLE_USER,ROLE_UNITY,ROLE_MOBILE"/>  

  4.     <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>  

  5.   

  6.     <form-login authentication-failure-url="/login.jsp?authentication_error=1" default-target-url="/index.jsp"  

  7.                 login-page="/login.jsp" login-processing-url="/login.do"/>  

  8.     <logout logout-success-url="/index.jsp" logout-url="/logout.do"/>  

  9.     <anonymous/>  

  10. http>  



到此, securiy.xml 配置完毕.


当然,还有些额外的工作你需要做, 如配置dataSource, 创建数据库, 添加用户用户信息, 管理ClientDetails等等.

Oauth相关的数据都是存放在数据库, 我们就可以根据表结果创建domain来实现管理.


更多参考内容: http://www.roncoo.com/article/index
相关文章
|
2月前
|
监控 网络协议 Nacos
Nacos:构建微服务架构的基石
Nacos:构建微服务架构的基石
118 2
|
2月前
|
前端开发 JavaScript 测试技术
Kotlin教程笔记 - 适合构建中大型项目的架构模式全面对比
Kotlin教程笔记 - 适合构建中大型项目的架构模式全面对比
38 3
|
26天前
|
监控 安全 API
使用PaliGemma2构建多模态目标检测系统:从架构设计到性能优化的技术实践指南
本文详细介绍了PaliGemma2模型的微调流程及其在目标检测任务中的应用。PaliGemma2通过整合SigLIP-So400m视觉编码器与Gemma 2系列语言模型,实现了多模态数据的高效处理。文章涵盖了开发环境构建、数据集预处理、模型初始化与配置、数据加载系统实现、模型微调、推理与评估系统以及性能分析与优化策略等内容。特别强调了计算资源优化、训练过程监控和自动化优化流程的重要性,为机器学习工程师和研究人员提供了系统化的技术方案。
146 77
使用PaliGemma2构建多模态目标检测系统:从架构设计到性能优化的技术实践指南
|
20天前
|
Serverless 决策智能 UED
构建全天候自动化智能导购助手:从部署者的视角审视Multi-Agent架构解决方案
在构建基于多代理系统(Multi-Agent System, MAS)的智能导购助手过程中,作为部署者,我体验到了从初步接触到深入理解再到实际应用的一系列步骤。整个部署过程得到了充分的引导和支持,文档详尽全面,使得部署顺利完成,未遇到明显的报错或异常情况。尽管初次尝试时对某些复杂配置环节需反复确认,但整体流程顺畅。
|
29天前
|
缓存 Kubernetes 容灾
如何基于服务网格构建高可用架构
分享如何利用服务网格构建更强更全面的高可用架构
|
2月前
|
弹性计算 持续交付 API
构建高效后端服务:微服务架构的深度解析与实践
在当今快速发展的软件行业中,构建高效、可扩展且易于维护的后端服务是每个技术团队的追求。本文将深入探讨微服务架构的核心概念、设计原则及其在实际项目中的应用,通过具体案例分析,展示如何利用微服务架构解决传统单体应用面临的挑战,提升系统的灵活性和响应速度。我们将从微服务的拆分策略、通信机制、服务发现、配置管理、以及持续集成/持续部署(CI/CD)等方面进行全面剖析,旨在为读者提供一套实用的微服务实施指南。
|
1月前
|
算法 NoSQL Java
微服务架构下的接口限流策略与实践#### 一、
本文旨在探讨微服务架构下,面对高并发请求时如何有效实施接口限流策略,以保障系统稳定性和服务质量。不同于传统的摘要概述,本文将从实际应用场景出发,深入剖析几种主流的限流算法(如令牌桶、漏桶及固定窗口计数器等),通过对比分析它们的优缺点,并结合具体案例,展示如何在Spring Cloud Gateway中集成自定义限流方案,实现动态限流规则调整,为读者提供一套可落地的实践指南。 #### 二、
64 3
|
1月前
|
负载均衡 Java 开发者
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
142 5
|
1月前
|
监控 安全 持续交付
构建高效微服务架构:策略与实践####
在数字化转型的浪潮中,微服务架构凭借其高度解耦、灵活扩展和易于维护的特点,成为现代企业应用开发的首选。本文深入探讨了构建高效微服务架构的关键策略与实战经验,从服务拆分的艺术到通信机制的选择,再到容器化部署与持续集成/持续部署(CI/CD)的实践,旨在为开发者提供一套全面的微服务设计与实现指南。通过具体案例分析,揭示如何避免常见陷阱,优化系统性能,确保系统的高可用性与可扩展性,助力企业在复杂多变的市场环境中保持竞争力。 ####
46 2
|
1月前
|
弹性计算 Kubernetes API
构建高效后端服务:微服务架构的深度剖析与实践####
本文深入探讨了微服务架构的核心理念、设计原则及实现策略,旨在为开发者提供一套系统化的方法论,助力其构建灵活、可扩展且易于维护的后端服务体系。通过案例分析与实战经验分享,揭示了微服务在提升开发效率、优化资源利用及增强系统稳定性方面的关键作用。文章首先概述了微服务架构的基本概念,随后详细阐述了其在后端开发中的应用优势与面临的挑战,最后结合具体实例,展示了如何从零开始规划并实施一个基于微服务的后端项目。 ####

热门文章

最新文章