• Spring Authorization Server 全新授权服务器整合使用


    前言

    • Spring Authorization Server 是 Spring 团队最新开发适配 OAuth 协议的授权服务器项目,旨在替代原有的 Spring Security OAuth

    • 经过半年的开发和孵化,目前已经发布了 0.1.0 版本,初步支持授权码、客户端、刷新、注销等 OAuth 协议

    • 本文环境基于 Spring Boot 2.4.2 && authorization-server 0.1.0

    Server 搭建

    1. maven 依赖

    <!--oauth2 server-->
    <dependency>
      <groupId>org.springframework.security.experimental</groupId>
      <artifactId>spring-security-oauth2-authorization-server</artifactId>
      <version>0.1.0</version>
    </dependency>
    <!--security dependency-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    

    2. 初始化配置

    • 由于官方还未提供对应的 Spring Boot Starter 自动化配置,需要自己配置相关的 @Bean
    • 本配置基于 Spring Boot 2.4.2 请知悉
    @Configuration
    @EnableWebSecurity
    @Import(OAuth2AuthorizationServerConfiguration.class)
    public class AuthServerConfiguration {
    
    	//  定义 spring security 拦击链规则
    	@Bean
    	SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
    		http
    				.authorizeRequests(authorizeRequests ->
    						authorizeRequests.anyRequest().authenticated()
    				)
    				.formLogin(withDefaults());
    		return http.build();
    	}
    
      // 创建默认登录用户 lengleng / 123456
    	@Bean
    	public UserDetailsService userDetailsService() {
    		UserDetails userDetails = User.builder()
    				.username("lengleng")
    				.password("{noop}123456")
    				.authorities("ROLE_USER")
    				.build();
    		return new InMemoryUserDetailsManager(userDetails);
    	}
    
      // 创建默认的bean 登录客户端,基于 授权码、 刷新令牌的能力
    	@Bean
    	public RegisteredClientRepository registeredClientRepository() {
    		RegisteredClient client = RegisteredClient.withId("pig")
    				.clientId("pig")
    				.clientSecret("pig")
    				.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC)
    				.authorizationGrantTypes(authorizationGrantTypes -> {
    					authorizationGrantTypes.add(AuthorizationGrantType.AUTHORIZATION_CODE);
    					authorizationGrantTypes.add(AuthorizationGrantType.REFRESH_TOKEN);
    				})
    				.redirectUri("https://pig4cloud.com")
    				.build();
    		return new InMemoryRegisteredClientRepository(client);
    	}
    
    
      // 指定token 生成的加解密密钥
    	@Bean
    	@SneakyThrows
    	public JWKSource<SecurityContext> jwkSource() {
    		KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    		keyPairGenerator.initialize(2048);
    		KeyPair keyPair = keyPairGenerator.generateKeyPair();
    		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
    		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
    
    		// @formatter:off
    		RSAKey rsaKey= new RSAKey.Builder(publicKey)
    				.privateKey(privateKey)
    				.keyID(UUID.randomUUID().toString())
    				.build();
    		JWKSet jwkSet = new JWKSet(rsaKey);
    		return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
    	}
    }
    

    测试

    授权码认证

    curl --location --request GET 'http://localhost:3000/oauth2/authorize?client_id=pig&client_secret=pig&response_type=code&redirect_uri=https://pig4cloud.com'
    

    获取令牌

    curl --location --request POST 'http://localhost:3000/oauth2/token' 
    --header 'Authorization: Basic cGlnOnBpZw==' 
    --header 'Content-Type: application/x-www-form-urlencoded' 
    --data-urlencode 'grant_type=authorization_code' 
    --data-urlencode 'code={code}' 
    --data-urlencode 'redirect_uri=https://pig4cloud.com'
    

    刷新令牌

    curl --location --request POST 'http://localhost:3000/oauth2/token' 
    --header 'Authorization: Basic cGlnOnBpZw==' 
    --header 'Content-Type: application/x-www-form-urlencoded' 
    --data-urlencode 'grant_type=refresh_token' 
    --data-urlencode 'refresh_token={refresh_token}' 
    

    撤销令牌

    • 通过 access_token
    curl --location --request POST 'http://localhost:3000/oauth2/revoke' 
    --header 'Authorization: Basic cGlnOnBpZw==' 
    --header 'Content-Type: application/x-www-form-urlencoded' 
    --data-urlencode 'token={access_token}' 
    --data-urlencode 'token_type_hint=access_token'
    
    • 通过 refresh_token
    curl --location --request POST 'http://localhost:3000/oauth2/revoke' 
    --header 'Authorization: Basic cGlnOnBpZw==' 
    --header 'Content-Type: application/x-www-form-urlencoded' 
    --data-urlencode 'token={refresh_token}' 
    --data-urlencode 'token_type_hint=refresh_token'
    

    内容扩展 | Token 个性化

    • RegisteredClient 支持个性化 token 设置的入参
    RegisteredClient..tokenSettings()
    
    • 默认配置如下, 包括令牌有效期,刷新令牌控制等
    	protected static Map<String, Object> defaultSettings() {
    		Map<String, Object> settings = new HashMap<>();
    		settings.put(ACCESS_TOKEN_TIME_TO_LIVE, Duration.ofMinutes(5));
    		settings.put(REUSE_REFRESH_TOKENS, true);
    		settings.put(REFRESH_TOKEN_TIME_TO_LIVE, Duration.ofMinutes(60));
    		return settings;
    	}
    

    总结

    >>> 源码 https://gitee.com/log4j/pig,欢迎署名转载 <<<

  • 相关阅读:
    ALV控件的简单案例之二:自定义ALV…
    上传文件时显示选择窗口
    RZ10设置ECC系统参数
    下载时,弹出下载地址选择窗口
    使用程序实现多client切换
    ALV控制某列的颜色
    WebService&nbsp;创建&nbsp;&nbsp;发布&nbsp;调用整个流…
    出口增强&nbsp;以EXIT_SAPLSZAR_001为例
    使用SAP&nbsp;memory&nbsp;调用标…
    FunctionModel调用ALV时,自定义工…
  • 原文地址:https://www.cnblogs.com/leng-leng/p/14434252.html
Copyright © 2020-2023  润新知