架构师之路-如何构建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; 以下只列出了主要的
  
    org.springframework.securitygroupId>  
    spring-security-coreartifactId>  
    ${spring.security.version}version>  
dependency>  
  
    org.springframework.securitygroupId>  
    spring-security-webartifactId>  
    ${spring.security.version}version>  
dependency>  
  
    org.springframework.securitygroupId>  
    spring-security-taglibsartifactId>  
    ${spring.security.version}version>  
dependency>  
  
    org.springframework.securitygroupId>  
    spring-security-aclartifactId>  
    ${spring.security.version}version>  
dependency>  
  
    org.springframework.securitygroupId>  
    spring-security-cryptoartifactId>  
    ${spring.security.version}version>  
dependency>  
  
    org.springframework.securitygroupId>  
    spring-security-configartifactId>  
    ${spring.security.version}version>  
dependency>  
  
    org.springframework.security.oauthgroupId>  
    spring-security-oauth2artifactId>  
    1.0.5.RELEASEversion>  
dependency>  
  1. web.xml配置; 这一步与只使用Spring Security的配置一样.
pre>
      
        springSecurityFilterChainfilter-name>  
        org.springframework.web.filter.DelegatingFilterProxyfilter-class>  
    filter>  
  
      
        springSecurityFilterChainfilter-name>  
        /*url-pattern>  
    filter-mapping>  
  
      
      
        contextConfigLocationparam-name>  
        classpath:spring/*.xmlparam-value>  
    context-param>  
  
      
      
        org.springframework.web.context.ContextLoaderListenerlistener-class>  
    listener>  
  
      
      
        hyservlet-name>  
        org.springframework.web.servlet.DispatcherServletservlet-class>  
        2load-on-startup>  
    servlet>  
      
        hyservlet-name>  
        /url-pattern>  
    servlet-mapping>  

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

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

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

3.1 起用注解; TokenEndpoint与AuthorizationEndpoint需要

  
  

3.2 TokenServices 配置

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

  
      
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

  
      
      
beans:bean>  

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

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

  
      
beans:bean>  

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

  
      
beans:bean>  

3.5 OAuth2AuthenticationEntryPoint配置

  

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

  
      
authentication-manager>  

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

  
      
          
    authentication-provider>  
authentication-manager>

userService是一个实现UserDetailsService的Bean

3.7 OAuth2AccessDeniedHandler配置, 实现AccessDeniedHandler接口

  

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

  
beans:bean>  

3.9 authorization-server配置, 核心

  
      
      
      
      
      
oauth2:authorization-server>  

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

  

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

  
      
          
              
              
              
        beans:list>  
    beans:constructor-arg>  
beans:bean>  

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

  
  
  
 

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

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

  
      
beans:bean>  

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

  
      
      
      
  
      
      
http>  

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

  
      
  
      
  
      
      
http>  
  
  
  
      
  
      
  
      
      
http>  

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

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

  
      
      
  
      
      
      
http>  

到此, securiy.xml 配置完毕.

当然,还有些额外的工作你需要做, 如配置dataSource, 创建数据库, 添加用户用户信息, 管理ClientDetails等等.
Oauth相关的数据都是存放在数据库, 我们就可以根据表结果创建domain来实现管理.

参考内容:从无到有搭建中小型互联网公司后台服务架构与运维架构

你可能感兴趣的:(架构师之路-如何构建rest接口的安全性访问(dubbox+oatuh2+rest))