SpringSecurity的OAuth2的授权服务器配置

Posted jazon@

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringSecurity的OAuth2的授权服务器配置相关的知识,希望对你有一定的参考价值。

OAUTH2概念里有资源服务器与授权服务器
先看授权服务的配置
通常,我们会写一个AuthorizationServerConfiguration类继承自AuthorizationServerConfigurerAdapter,并且在类上加@Configuration注解

  • 授权服务器的配置
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter 
    

  • 其中@EnableAuthorizationServer是开启授权服务器,这是一个复合注解,利用@Import引入了AuthorizationServerSecurityConfiguration类,而该类继承了WebSecurityConfigurerAdapter类,这个类很熟悉,是前一篇文章说的Security配置入口
public class AuthorizationServerSecurityConfiguration extends WebSecurityConfigurerAdapter 
    protected void configure(HttpSecurity http) throws Exception 
		AuthorizationServerSecurityConfigurer configurer = new AuthorizationServerSecurityConfigurer();
		FrameworkEndpointHandlerMapping handlerMapping = endpoints.oauth2EndpointHandlerMapping();
		http.setSharedObject(FrameworkEndpointHandlerMapping.class, handlerMapping);
        // 这里开放了配置AuthorizationServerSecurityConfigurer的入口
		configure(configurer);
        // 将AuhtorizationServerSecurityConfigurer应用到httpSecurity,通过这种方式开放了httpSecurity部分配置给用户
		http.apply(configurer);
		String tokenEndpointPath = handlerMapping.getServletPath("/oauth/token");
		String tokenKeyPath = handlerMapping.getServletPath("/oauth/token_key");
		String checkTokenPath = handlerMapping.getServletPath("/oauth/check_token");
		if (!endpoints.getEndpointsConfigurer().isUserDetailsServiceOverride()) 
			UserDetailsService userDetailsService = http.getSharedObject(UserDetailsService.class);
			endpoints.getEndpointsConfigurer().userDetailsService(userDetailsService);
		
		// @formatter:off
		http
        	.authorizeRequests()
            	.antMatchers(tokenEndpointPath).fullyAuthenticated()
            	.antMatchers(tokenKeyPath).access(configurer.getTokenKeyAccess())
            	.antMatchers(checkTokenPath).access(configurer.getCheckTokenAccess())
        .and()
        //之前文章说过,HttpSecurity最后会变成一个Filter
        // 这里配置RequestMatcher,就意味只有这些url会匹配这个Filter
        	.requestMatchers()
            	.antMatchers(tokenEndpointPath, tokenKeyPath, checkTokenPath)
        .and()
        	.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
		// @formatter:on
		http.setSharedObject(ClientDetailsService.class, clientDetailsService);
	
    
    protected void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception 
		for (AuthorizationServerConfigurer configurer : configurers) 
			configurer.configure(oauthServer);
		
	

可以看到,OAUTH2的授权服务器过滤器实现,匹配了几个url,分配至/oauth/token; /oauth/token_key;/oauth/check_token;暴露给用户可以配置的为AuthorizationServerSecurityConfigurer

public final class AuthorizationServerSecurityConfigurer extends
		SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> 

    // 配置身份信息异常的处理器
	private AuthenticationEntryPoint authenticationEntryPoint;

    // 配置拒绝访问的处理器
	private AccessDeniedHandler accessDeniedHandler = new OAuth2AccessDeniedHandler();

    // 配置client scret的密码编码策略
	private PasswordEncoder passwordEncoder; // for client secrets

    // WWW-Authenticate头使用realm字段字符串提示为了访问指定Url所需要的保护策略
    // WWW-Authenticate <type> realm=<realm>
	private String realm = "oauth2/client";

    // 允许client/scret验证以表单方式提交
	private boolean allowFormAuthenticationForClients = false;

    // /oauth/token_key的访问策略,/oauth/token_key暴露token的签名算法,适用于JWT的时候
	private String tokenKeyAccess = "denyAll()";
    
    // /oauth/check_token的访问策略
	private String checkTokenAccess = "denyAll()";
    // 设置sslOnly
	private boolean sslOnly = false;

  • 分析完了EnableAuthorizationServer 注解,接着分析继承的AuthorizationServerConfigurerAdapter类,该类实现了AuthorizationServerConfigurer接口,这里很重要,说明我们自定义的的AuthorizationServerConfiguration是一个AuthorizationServerConfigurer类型的bean。在AuthorizationServerSecurityConfiguration类中就使用AuthorizationServerConfigurer的bean去配置AuthorizationServerConfigurerClientDetailsServiceConfigurer
public class AuthorizationServerSecurityConfiguration extends WebSecurityConfigurerAdapter 
    @Autowired
	public void configure(ClientDetailsServiceConfigurer clientDetails) throws Exception 
		for (AuthorizationServerConfigurer configurer : configurers) 
			configurer.configure(clientDetails);
		
	
    
    protected void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception 
		for (AuthorizationServerConfigurer configurer : configurers) 
			configurer.configure(oauthServer);
		
	

如上代码所示,分别是使用自定义配置类去配置ClientDetailsServiceConfigurer(配置clientDetailsService)和AuthorizationServerSecurityConfigurer(最后会被应用进HttpSecurity);AuthorizationServerConfigurer接口还有一个定义是

/**
Configure the non-security features of the Authorization Server endpoints, like token store, 
token customizations, user approvals and grant types. You shouldn't need to do anything by default, 
unless you need password grants, in which case you need to provide an AuthenticationManager.
Params:
endpoints – the endpoints configurer
*/
void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception;

它是用来配置AuthorizationServerEndpointsConfigurer的,即这里是用来配置端点非访问安全相关的,比如底层tokenStore,tokenService;认证类型之类的;后续的文章会分析这些类都是用来干嘛的;

  • 总结

自定义的授权服务器配置类,配置三个方面的,一个是AuthorizationServerSecurityConfigurer,这些最终是会应用到HttpSecurity里的,相当于OAUTH2对HttpSecurity配置进行了权限收缩;另一个是ClientDetailsServiceConfigurer,这个是配置ClientDetailsServcie的,每个访问Oauth授权服务器的,都需要一个client身份,就是用这个ClientDetailsService去进行的Client身份认证;最后一个是AuthorizationServerEndpointsConfigurer,这个配置的是授权服务器底层的实现逻辑,比如token如何存储,用户信息如何获取等非接口访问安全的内容;

以上是关于SpringSecurity的OAuth2的授权服务器配置的主要内容,如果未能解决你的问题,请参考以下文章

SpringSecurity的OAuth2的授权服务器配置

SpringSecurity结合OAuth2实现第三方授权

SpringSecurity WithSecurityContext MockMvc OAuth2 总是未经授权

Spring Security实现OAuth2.0授权服务 - 进阶版

Spring Security 与 OAuth2(介绍)

3.spring security oauth2 配置授权服务器(AuthorizationServerConfigurerAdapter)