Spring SecuritySpring SecurityOauth2

Spring security OAuth2 深入解析

2017-12-22  本文已影响259人  CatalpaFlat

Spring security OAuth2 深入解析

一、OAuth2 概要

1.1.OAuth2基本流程

话不多说,先上图:


OAuth2流程图

分析一波:

其实不管微信或者QQ大体上都是使用这种OAuth2的基本流程:

  1. 第三方应用请求用户授权;
  2. 用户同意授权,并返回一个授权码(code);
  3. 第三方应用根据授权码(code)向授权认证服务进行授权;
  4. 授权服务器根据授权码(code),校验通过,并返回给第三方应用令牌(Access Token);
  5. 第三方应用根据令牌(Access Token)向资源服务请求相关资源;
  6. 资源服务器验证令牌(Access Token),校验通过,并返回第三方所请求的资源。

1.2.服务类型

OAuth2 在服务提供者上可分为两类:


@Configuration
@EnableAuthorizationServer
public class CustomAuthenticationServerConfig extends AuthorizationServerConfigurerAdapter 

@Configuration
@EnableResourceServer
public class CustomResourceServerConfig extends ResourceServerConfigurerAdapter

注:这两者有时候可能存在同一个应用程序中(即SOA架构)。在Spring OAuth中可以简便的将其分配到两个应用中(即微服务),而且可多个资源获取服务共享一个授权认证服务。

1.3.授权认证服务

主要的操作:

  1. 获取第三方应用发送的授权码(code)以及第三方应用标识
  2. 根据授权码及标识进行校验
  3. 校验通过,发送令牌(Access Token)

分析一波:
1)第一步操作

注:其中client_id和client_secret都是授权服务器发送给第三方应用的,如:微信等一系列授权,在其平台上注册,获取其appid和secret同样道理(个人理解为账号密码)。

既然是账号秘密,总不能以get请求,也太不安全了。因此,OAuth2要求该请求必须是POST请求,同时,还必须时HTTPS服务,以此保证获取到的安全凭证(Access Token)的安全性。

2)第二步操作

3)第三步操作

1.4.资源获取服务

主要的操作:

二、Spring Security OAuth2的使用

1.授权认证服务

spring OAuth2中,我们配置一个授权认证服务,我们最主要有以下三点:

  1. 第三方用户客户端详情 → Client
  2. 令牌的生成管理 → Access Token
  3. 端点接入 → endpoints

spring中有三个配置与这三点一一对应:

1.1.第三方用户客户端详情

除了上面说到的client_id和client_secret,还需要一些服务附带一些授权认证参数。

1).Grant Type

其实OAuth2不仅提供授权码(code)这种格式授权方式,还提供几个其他类型。其中用Grant Type代表当前授权的类型。 Grant Type包括:


2).scope

其实授权赋予第三方用户可以在资源服务器获取资源,经常就是调取Api请求附带令牌,然而调取api有增删查改等功能,而scopes的值就是all(全部权限),read,write等权限。就是第三方访问资源的一个权限,访问范围。


3).accessTokenValiditySeconds

还可以设置accessTokenValiditySeconds属性来设置Access Token的存活时间。

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

    clients.inMemory()
            .withClient("catalpaFlat")
            .secret("catalpaFlat-secret")
            .accessTokenValiditySeconds(7200)
            .authorizedGrantTypes("refresh_token","password")
            .scopes("all");
}

1.2.令牌的生成和管理

AccessToken的存在意义:

1).AuthorizationServerTokenServices
AuthorizationServerTokenServices 提供了对AccessToken的相关操作创建、刷新、获取。

public interface AuthorizationServerTokenServices {

    OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) throws AuthenticationException;

    
    OAuth2AccessToken refreshAccessToken(String refreshToken, TokenRequest tokenRequest)
            throws AuthenticationException;

    
    OAuth2AccessToken getAccessToken(OAuth2Authentication authentication);

}

2).DefaultTokenServices

AuthorizationServerTokenServices竟然可以操作AccessToken,那么OAuth2就默认为我们提供了一个默认的DefaultTokenServices。包含了一些有用实现,可以使用它来修改令牌的格式和令牌的存储等,但是生成的token是随机数。

3).TokenStore

创建AccessToken完之后,除了发放给第三方,肯定还得保存起来,才可以使用。因此,TokenStore为我们完成这一操作,将令牌(AccessToken)保存或持久化。
TokenStore也有一个默认的实现类InMemoryTokenStore,从名字就知道是通过保存到内存进而实现保存Access Token。
TokenStore的实现有多种类型,可以根据业务需求更改Access Token的保存类型:

4).JWT Token

想使用jwt令牌,需要在授权服务中配置JwtTokenStore。之前说了,jwt将一些信息数据编码后存放在令牌,那么其实在传输的时候是很不安全的,所以Spring OAuth2提供了JwtAccessTokenConverter来怼令牌进行编码和解码。适用JwtAccessTokenConverter可以自定义秘签(SigningKey)。SigningKey用处就是在授权认证服务器生成进行签名编码,在资源获取服务器根据SigningKey解码校验。

JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();

 jwtAccessTokenConverter.setSigningKey("CatalpaFlat")
jwt存储

1.3.端点接入-endpoints

授权认证是使用AuthorizationEndpoint这个端点来进行控制,一般使用AuthorizationServerEndpointsConfigurer 来进行配置。

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {}

1).端点(endpoints)的相关属性配置:

2).端点(endpoints)的授权url:
要授权认证,肯定得由url请求,才可以传输。因此OAuth2提供了配置授权端点的URL。
AuthorizationServerEndpointsConfigurer ,还是这个配置对象进行配置,其中由一个pathMapping()方法进行配置授权端点URL路径,默认提供了两个参数defaultPath和customPath:

public AuthorizationServerEndpointsConfigurer pathMapping(String defaultPath, String customPath) {
        this.patternMap.put(defaultPath, customPath);
        return this;
}

pathMapping的defaultPath有:

注:pathMapping的两个参数都将以 "/" 字符为开始的字符串

1.4.自定义错误处理(Error Handling)

实际上我们上面说到的端点,其实可以看成Controller,用于返回不同端点的响应内容。

授权服务的错误信息是使用标准的Spring MVC来进行处理的,也就是 @ExceptionHandler 注解的端点方法,我们可以提供一个 WebResponseExceptionTranslator 对象。最好的方式是改变响应的内容而不是直接进行渲染。

2.资源获取服务

资源服务器,其实就是存放一些受令牌保护的资源,只有令牌并且有效正确才能获取到资源。 内部是通过Spring OAuth2的Spring Security Authentication filter 的过滤链来进行保护。

2.1.ResourceServerConfigurerAdapter

我们可以继承ResourceServerConfigurerAdapter,来使用 ResourceServerSecurityConfigurer进行相关配置。

public class ResourceServerConfigurerAdapter implements ResourceServerConfigurer {

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated();
    }
}

2.2.ResourceServerSecurityConfigurer的相关属性

2.3.ResourceServerTokenServices

ResourceServerTokenServices 是组成授权服务的另一半。

1).若是资源服务器和授权服务在同一个应用,可以使用DefaultTokenServices

2).若是分离的。ResourceServerTokenServices必须知道令牌的如何解码。

ResourceServerTokenServices解析令牌的方法:

注:授权认证服务需要把/oauth/check_toke暴露出来,并且附带上权限访问。

@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
    oauthServer.tokenKeyAccess("isAnonymous() || hasAuthority('ROLE_TRUSTED_CLIENT')")
        .checkTokenAccess("hasAuthority('ROLE_TRUSTED_CLIENT')");
}

(~ ̄▽ ̄)~未完待续... ...

上一篇 下一篇

猜你喜欢

热点阅读