Spring Cloud Security OAuth2.0入门: AuthorizationServer搭建(一)

最近在学习微服务相关的知识及各种框架的使用,在搭建的过程中,遇到了不少问题,但是都没有记录下来,导致过一段时间后,就没有什么印象了.. 所以决定在掘金写文章。 一是为了记录自己在写代码过程中的知识点以及解决的问题,方便查阅; 二是为了能与其它朋友一起讨论,可以吸收不同思想及不同方案,扩展思路。

标题之所以为Spring Cloud Security,是因为想要写Spring Cloud相关的一系列技术。而Spring Cloud依赖Springbootsecurity还是Spring Security模块的东西,本质上没有太大的区别。

在写的过程中,遇到自己不熟悉或没有把握的概念及知识,会谨慎的求证。也会尽量保证发布的任何代码都是可运行的。 但是由于自己技术能力有限,难免会有错误,包括但不限于拼写错误代码错误有代码洁癖的人看着缩进不舒服概念理解有偏差代码不够优雅等等,希望各位可以不吝指教,不喜勿喷~

知识储备

阮一峰老师的OAuth2.0介绍

新建microservice,作为所有服务的parent, 同时引入依赖


    org.springframework.boot
    spring-boot-starter-parent
    2.1.5.RELEASE
     


    Greenwich.RELEASE
    2.1.5.RELEASE


        
            
                org.springframework.cloud
                spring-cloud-dependencies
                ${spring.cloud.dependencies.version}
                <type>pomtype>
                import
            
            
                org.springframework.security.oauth.boot
                spring-security-oauth2-autoconfigure
                ${spring-security-oauth2-autoconfigure.version}
            
        

复制代码

新建uaa-service,作为认证授权服务,引入依赖


    
        org.springframework.boot
        spring-boot-starter-web
    
    
        org.springframework.cloud
        spring-cloud-starter-oauth2
        
            
                org.springframework.security.oauth.boot
                spring-security-oauth2-autoconfigure
            
        
    
    
        org.springframework.security.oauth.boot
        spring-security-oauth2-autoconfigure
        2.1.5.RELEASE
    

复制代码

spring-cloud-starter-oauth2这个依赖应该已经包含了spring security相关的jar,但是 spring-cloud-dependencies版本为Greenwich.RELEASE时,spring-security-oauth2-autoconfigure子module中引入的版本一直是2.1.0.M4,不管是重新import还是删除本地maven repository都不管用, 在官方的issue中也有人遇到的相同的问题, 所以以上依赖暂时使用单独引入spring-security-oauth2-autoconfigureversion还必须在子module中指定,不知你们是否也碰到这种问题.

Authorization Server 配置

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

	@Autowired
	private AuthenticationManager authenticationManager;

	@Autowired
	private PasswordEncoder passwordEncoder;

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

	@Override
	public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
		clients.inMemory()
				.withClient("client-id")
				.secret(passwordEncoder.encode("client-secret"))
				.scopes("read", "write")
				.authorizedGrantTypes("password", "refresh_token")
				.authorities("user:view");
	}

	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
		endpoints
			.authenticationManager(authenticationManager)
			.tokenStore(tokenStore());
	}

	@Bean
	public TokenStore tokenStore() {
		return new InMemoryTokenStore();
	}
}
复制代码
  • 使用@EnableAuthorizationServer注解告诉Spring激活authorization server
  • 同时@Configuration注解的实现了AuthorizationServerConfigurer接口的类表明这是一个authorization server配置类。
  • 这里使用的AuthorizationServerConfigurerAdapterSpring提供的默认实现AuthorizationServerConfigurer接口的类,里面都是空方法
  • 注入authenticationManager,这是Spring默认提供的,如果需要使用password模式,必须显示地配置endpoints.authenticationManager(authenticationManager)
  • 一般项目中密码之类的字段都不会使用明文加密, 所以这里注入passwordEncoder,用于用户登录时密码校验以及创建用户时密码的加密
  • tokenStore这里暂时使用InMemoryTokenStore,Spring同时也提供了如下几种存储token方式
  • ClientDetailsServiceConfigurer是配置authorization server颁发的client的凭证
    • client.inMemory()是在内存中存储client信息
    • withClientsecret是client的usernamepassword
    • scopes是授权范围,例如该client可以进行读和写
    • authorizedGrantTypes是配置授权方式, 可以是OAuth2.0中支持的方式,也可以是自定义的

配置用户

@Configuration
@EnableGlobalMethodSecurity(proxyTargetClass = true, prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth
		    .inMemoryAuthentication()
		    .withUser("admin")
		    .password(passwordEncoder().encode("password"))
		    .roles("ADMIN");
	}

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

	@Bean
	@Override
	public AuthenticationManager authenticationManagerBean() throws Exception {
		return super.authenticationManagerBean();
	}
}
复制代码
  • @EnableGlobalMethodSecurity(proxyTargetClass = true, prePostEnabled = true)开启方法级别权限验证
  • AuthenticationManagerBuilder在内存中配置一个用户,用于password模式获取token
  • BCryptPasswordEncoder配置加密实现类

获取token

以上项目启动完成之后,启动项目,spring security会为我们提供几个endpoint, 其中一个就是获取token的: /oauth/token。使用的http请求工具是postman

如上图所示,输入之后,会把之前配置的clientusernamepasswordbase64编码放在http header

http body中输入

发送请求之后,得到响应, 其中的access_token就是我们后续请求接口使用的令牌

总结

以上就是利用spring security简单地搭建authorization server, 可以看到还是蛮方便的。但是如果是用在生产环境,还远不够,例如用户信息、client信息、token信息的持久化,各种异常的处理,资源服务器的配置等等,在后续的文章也会不断的完善,感谢!

你可能感兴趣的:(java,postman)