Spring Authorization Server使用

介绍

OAuth 1.0 组织已经开始开发基于对OAuth的支持,该框架就是Spring Security OAuth。其实现了大部分的OAuth规范,并提供了资源服务器、客户端和授权服务器。
2018年1月,Spring 官方发布了一个将会停更Spring Security OAuth的通知,并开始在 Spring Security 5.0中构建下一代0Auth2.0支持

2019年11月,Spring Security 0Auth中客户端、资源服务器的功能大部分已迁移到Spring Security 5>中,在5.3版本中完成了迁移工作,并添加了许多新功能,比如对OpenID Connect 1.0的支持。同时还宣布不再支持授权服务器,因为Spring觉得授权服务器更像是一个产品,而Spring Security作为框架,并不适合做这件事情,而且已经有大量商业和开源并且成熟的授权服务器。

2022年5月31日,Spring Security OAuth正式归档。

GitHub - spring-attic/spring-security-oauth: Support for adding OAuth1(a) and OAuth2 features (consumer and provider) for Spring web applications.

** Spring Authorization Server**

`Spring Security OAuth的停止维护,以及Spring Security不再提供授权服务器这件事,在社区一石激起千层浪,引起很多人的反对,经过Spring社区的努力,Spring决定在2020年4月开始启动新的授权服务器项目。
Spring Authorization Server是一个授权服务器框架,提供 OAuth 2.1 和 OpenID Connect 1.0 规范及其他相关规范的实现。它建立在 Spring Security 之上,为构建开发标准的授权服务器产品提供了一个安全、轻量级和可定制的基础。

Spring Authorization Server

Spring Authorization Server

功能特性

授权模式支持:

  • 授权码模式
  • 客户端模式
  • 刷新令牌模式

令牌格式:

  • JWT
  • JWS

客户端认证方式支持

  • client_secret_basic:基于Basic消息头认证

header里面的Authorization值为 Basic base64(clientId:clientSecret)

  • client_secret_post:POST请求进行认证

直接将clientId、clientSecret、grant_type放入表单元素中

  • private_key_jwt: 基于JWT 进行认证,请求方使用私钥对JWT签名,授权服务器使用对应公钥进行验签认证
  • client_secret_jwt:基于JWT 进行认证,对JWT使用客户端密码+签名算法 签名
  • none (public clients):公共客户端

协议端点支持:

  • OAuth2 Authorization Endpoint:申请授权端点,默认为/oauth2/authorize
  • OAuth2 Token Endpoint:获取访问令牌端点,默认为/oauth2/token
  • OAuth2 Token Introspection Endpoint:令牌自省端点,默认为/oauth2/introspect
  • OAuth2 Token Revocation Endpoint:令牌撤销端点,默认为/oauth2/revoke
  • OAuth2 Authorization Server Metadata Endpoint:获取授权服务器元信息的端点,默认为/.well-known/oauth-authorization-server
  • JWK Set Endpoint:JWK信息端点,默认为/oauth2/jwks
  • OpenID Connect 1.0 Provider Configuration Endpoint:查询提供者配置端点,默认为/.well-known/openid-configuration
  • OpenID Connect 1.0 UserInfo Endpoint:用户信息端点,默认为/userinfo
  • OpenID Connect 1.0 Client Registration Endpoint:客户端注册端点,默认为/connect/register

环境搭建

依赖

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-authorization-server</artifactId>
</dependency>
数据库存储client需要使用jdbc
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
</dependency>

数据库新建

配置类:

@Configuration
public class SecurityConfig {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Bean
    @Order(1)
    public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
            throws Exception {
        OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);

        http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
                .oidc(Customizer.withDefaults());    // Enable OpenID Connect 1.0
        http
                // Redirect to the login page when not authenticated from the
                // authorization endpoint
                .exceptionHandling((exceptions) -> exceptions
                        .authenticationEntryPoint(
                                new LoginUrlAuthenticationEntryPoint("/login"))
                );
        // Accept access tokens for User Info and/or Client Registration
//			.oauth2ResourceServer();
        return http.build();
    }

    @Bean
    @Order(2)
    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
            throws Exception {
        http
                .authorizeHttpRequests(
                        (authorize) -> authorize
                                .requestMatchers("/test/**").permitAll()
                                .anyRequest().authenticated()
                )
                // Form login handles the redirect to the login page from the
                // authorization server filter chain
                .formLogin(Customizer.withDefaults());

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails userDetails = User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build();

        return new InMemoryUserDetailsManager(userDetails);
    }

    @Bean
    public RegisteredClientRepository registeredClientRepository() {
        return new JdbcRegisteredClientRepository(jdbcTemplate);
    }

    @Bean
    public JWKSource<SecurityContext> jwkSource() {
        KeyPair keyPair = generateRsaKey();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        RSAKey rsaKey = new RSAKey.Builder(publicKey)
                .privateKey(privateKey)
                .keyID(UUID.randomUUID().toString())
                .build();
        JWKSet jwkSet = new JWKSet(rsaKey);
        return new ImmutableJWKSet<>(jwkSet);
    }

    private static KeyPair generateRsaKey() {
        KeyPair keyPair;
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(2048);
            keyPair = keyPairGenerator.generateKeyPair();
        } catch (Exception ex) {
            throw new IllegalStateException(ex);
        }
        return keyPair;
    }

    @Bean
    public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
        return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
    }

    @Bean
    public AuthorizationServerSettings authorizationServerSettings() {
        return AuthorizationServerSettings.builder().build();
    }

}

获取token

客户端模式

url:http://localhost:8080/oauth2/token

Spring Resource Server

准备

最小依赖:

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-resource-server</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-jose</artifactId>
</dependency>

配置:

@Configuration
@EnableWebFluxSecurity
public class ResourceConfig {

    @Bean
    public SecurityWebFilterChain securityFilterChain(ServerHttpSecurity http) {
        return http
                // 统一资源服务器JWT Token校验
                .oauth2ResourceServer(oauth2 ->
                        oauth2
                                .jwt(Customizer.withDefaults())
                )
                .csrf(ServerHttpSecurity.CsrfSpec::disable)
                // 通过认证后的处理器
                .build();
    }
}

yml文件

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
        #需要把认证服务器的jwk地址写上
          jwk-set-uri: http://localhost:8080/oauth2/jwks

token获取以及流程:

画板

使用

直接将从认证服务器中拿到的token,来访问资源服务器即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值