springCloud 授权服务器

之前弄好了非常非常简单的限流,现在就是登陆进来的用户,我们需要对他进行认证。这个时候就要用到我们的授权服务器了。

什么是授权服务器,就是给客户端一个身份,一个token。让我们的服务器认识他。

springCloud是提供了这样的模块的oauth2,先上依赖

<!--        服务发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>

然后实现我们自己的授权服务配置类,需要继承AuthorizationServerConfigurerAdapter

这个类的资料网上都有,我这里照搬一下

AuthorizationServerConfigurer是配置OAUth2 授权服务器的配置类接口,添加了@EnableAuthorizationServer,spring会自动注入。接口有三个方法,可以实现客户端配置、安全功能、以及各个Endpoint(端点)的相关配置

public class AuthorizationServerConfigurerAdapter implements AuthorizationServerConfigurer {

	@Override
	public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
	}

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

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

}

根据入参的名称,我们可以知道,这三个方法对应的功能

AuthorizationServerSecurityConfigurer  配置安全功能

ClientDetailsServiceConfigurer  配置我们客户端的信息

AuthorizationServerEndpointsConfigurer 配置我们端点的各个功能。

Spring Security OAuth2 是有默认的配置类的OAuth2AuthorizationServerConfiguration,当我们没有自己定义配置类时,是获取这个配置信息。这里不贴代码了

我们自己实现了配置类,重写configure(ClientDetailsServiceConfigurer clients),模拟一个客户端,

/**
     * 添加第三方的客户端
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("api") //第三方客户端的名称
                .secret(passwordEncoder.encode("secret")) //第三方客户端的密钥
                .scopes("all") //第三方客户端的授权范围
                .accessTokenValiditySeconds(3600) //获取token的有效期
                .refreshTokenValiditySeconds(7*3600); //refresh_token的有效期
        super.configure(clients);
    }

重写configure(AuthorizationServerEndpointsConfigurer endpoints),因为我们主要的是想看看一个token的生成以及相应的认证

/**
     * 配置验证管理器,UserDetailService
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService)
                .tokenStore(jwtTokenStore())
                .tokenEnhancer(jwtAccessTokenConverter());
                //.tokenStore(redisTokenStore());
        super.configure(endpoints);
    }

我们来解析一下都做了什么事

// Security 设置我们的认证管理器authenticationManager,需要我们定义一个管理器对象endpoints.authenticationManager(authenticationManager)
// 重写我们的userDetailsService,后面我们可以自己模拟用户,也可以通过数据库查询我们的用户信息
.userDetailsService(userDetailsService)

//令牌的存储服务,使用JWT来为我们存储token,主要是为了把我们用户信息以及认证信息都放在token里,这样就不用一直请求我们认证服务器来获取用户的信息,减少授权服务器压力

.tokenStore(jwtTokenStore())

private TokenStore jwtTokenStore() {
        JwtTokenStore jwtTokenStore = new JwtTokenStore(jwtAccessTokenConverter());
        return jwtTokenStore;
    }

    private JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();

        //加载私钥
        ClassPathResource classPathResource = new ClassPathResource("test.jks");
        KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(classPathResource,"test".toCharArray());
        jwtAccessTokenConverter.setKeyPair(keyStoreKeyFactory.getKeyPair("test","test".toCharArray()));
        return jwtAccessTokenConverter;
    }

额,还是先捋一捋用JWT(Json Web Token)能干啥

我们可以用公钥和私钥来加密我们的用户信息,使用Keytool来生成我们密钥对

keytool -genkeypair -alias test-keyalg RSA -keypass test

-keystore test.jks -validity 365 -storepass test

完了把我们生成好的文件放在我们的res下

 //我们的token增强就是使用我们JwtAccessTokenConverter 

.tokenEnhancer(jwtAccessTokenConverter());

我们的token就生成好了。

不过,我们漏掉了两个东西,先上代码

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.authorizeRequests().anyRequest().authenticated();
        //super.configure(http);
    }

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

    @Bean
    public UserDetailsService userDetailsService(){
        InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
        User user = new User("admin","123456", Arrays.asList(new SimpleGrantedAuthority("Role_Admin")));
        inMemoryUserDetailsManager.createUser(user);
        return inMemoryUserDetailsManager;
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance();
    }
}

这个适配器帮我们定义了

AuthenticationManager,
UserDetailsService,
PasswordEncoder的策略,我们现在是模拟了一个用户出来,后续可以通过查数据库来重写UserDetailsService,认证管理器以及验证管理器先不设置了
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值