欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring Security OAuth2 (一)基础SpringBoot整合OAuth

程序员文章站 2022-06-04 11:00:35
...

今天简单记录一下SpringBoot整合OAuth2的代码步骤

SpringBoot的1.5.21版本同SpringBoot 2.x版本有区别

本文记录的是密码式的授权方式

1、导入依赖

        <!-- 以下是安全相关 -->
        <!-- spring security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!-- spring security oauth2 -->
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.0.17.RELEASE</version>
        </dependency>
        <!-- spring security jwt -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-jwt</artifactId>
            <version>1.0.9.RELEASE</version>
        </dependency>

2、OAuth2.0使用JWT

jwt 配置类

@Configuration
public class JwtTokenConfig {

    @Component("customJwtTokenEnhancer")
    public class CustomJwtTokenEnhancer implements TokenEnhancer {

        //实现TokenEhancer(令牌增强器)中的 ehance方法,增加额外的信息
        @Override
        public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
            //token增强逻辑,务必确保保存的信息基本不变
            Map<String, Object> additionalInfo = new HashMap<>();
            //可以获取到代表当前用户的信息
            Object userAuthentication = authentication.getPrincipal();
            additionalInfo.put("customInfo", "some_stuff_here");
//            Object userAuthentication = authentication.getPrincipal();
//            if (userAuthentication instanceof User) {
//                User user = (User) userAuthentication;
//                additionalInfo.put("id", user.getId());
//                additionalInfo.put("unitId", user.getUnitId());
//                additionalInfo.put("proviceSeqNo", user.getProvinceSeqNo());
//                additionalInfo.put("role", user.getRole());
//            }
            ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
            return accessToken;
        }
    }

    配置token模式
    @Bean
    public TokenStore tokenStore(){
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    jwt配置
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter(){
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
        jwtAccessTokenConverter.setSigningKey("ting");
        return jwtAccessTokenConverter;
    }

}

3、授权服务器

自定义授权服务器 继承  AuthorizationServerConfigurerAdapter

@Configuration
@EnableAuthorizationServer// 这个注解告诉 Spring 这个应用是 OAuth2 的授权服务器//
// 提供/oauth/authorize,/oauth/token,/oauth/check_token,/oauth/confirm_access,/oauth/error
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private JwtTokenConfig.CustomJwtTokenEnhancer customJwtTokenEnhancer;

    //jwt配置
    @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.allowFormAuthenticationForClients()				//表单认证(申请令牌)
        ;

    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //使用内存存储client凭证,可根据情况改用jdbc存储
        clients.inMemory()
                .withClient("ti")
//                .secret(passwordEncoder.encode("g304")) //SpringBoot2.X版本需要加密
                .secret("ti")
                .authorizedGrantTypes("password")
                .scopes("all")
                .accessTokenValiditySeconds(7200);
    }

    //jwtTokenStore存储
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService);
        //将增强的token设置到增强链中
        TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
        enhancerChain.setTokenEnhancers(Arrays.asList(customJwtTokenEnhancer, jwtAccessTokenConverter));
        endpoints.tokenStore(tokenStore)
                .accessTokenConverter(jwtAccessTokenConverter)
                .tokenEnhancer(enhancerChain);
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    // 设置添加用户信息,正常应该从数据库中读取
    @Bean
    UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager userDetailsService = new InMemoryUserDetailsManager();
        userDetailsService.
                createUser(User.withUsername("user_1").
                        password(passwordEncoder().encode("123456"))
                        .authorities("ROLE_USER").build());
        userDetailsService.createUser(User.withUsername("user_2").password(passwordEncoder().encode("123456"))
                .authorities("ROLE_USER").build());
        return userDetailsService;
    }
}

访问链接/oauth/token 就可以访问成功

Spring Security OAuth2 (一)基础SpringBoot整合OAuth

以上是使用SpringBoot1.5.21,如果使用SpringBoot2.x版本需要进行的修改:

1、AuthenticationManager注入失败

Spring Security OAuth2 (一)基础SpringBoot整合OAuth

解决办法:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

2、运行时报错和警告,是因为clients的密码格式不匹配

Spring Security OAuth2 (一)基础SpringBoot整合OAuth

Spring Security OAuth2 (一)基础SpringBoot整合OAuth

解决办法:

Spring Security OAuth2 (一)基础SpringBoot整合OAuth

编写代码时报错的异常:

1、访问/oauth/token时候报401 authentication is required

在/oauth/token 的请求中我们指定了client_id和client_secret,所以会走ClientCredentialsTokenEndpointFilter,此时需要我们配置支持allowFormAuthenticationForClients。
在认证服务配置类中进行配置:

Spring Security OAuth2 (一)基础SpringBoot整合OAuth

 

参考:

https://blog.csdn.net/wx2007xing/article/details/87856630

https://blog.csdn.net/weixin_44062339/article/details/102494070

https://blog.csdn.net/weixin_37769855/article/details/102840606

相关标签: oauth