4、oauth2之认证服务配置类EnableAuthorizationServer

前几节主要介绍了什么是oauth2,以及spring security oauth2的简单用法。下面我们来看下oauth2的认证服务和资源服务它们是怎么配置的,流程又是什么样的,首先来看下认证服务。

使用方式:

1、添加注解@EnableAuthorizationServer

2、继承AuthorizationServerConfigurerAdapter

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter{

}

spring security oauth2的任务服务是通过注解@EnableAuthorizationServer引入的。该注解会导入AuthorizationServerSecurityConfiguration和AuthorizationServerEndpointsConfiguration两个配置类

AuthorizationServerEndpointsConfiguration:主要是配置了任务服务的一些端点请求。比如oauth/token、oauth/authorize、oauth/check_token、oauth/confirm_access、oauth/error等

@Configuration
@Import(TokenKeyEndpointRegistrar.class)
public class AuthorizationServerEndpointsConfiguration {

   private AuthorizationServerEndpointsConfigurer endpoints = new AuthorizationServerEndpointsConfigurer();

   @Autowired
   private ClientDetailsService clientDetailsService;

   @Autowired
   private List<AuthorizationServerConfigurer> configurers = Collections.emptyList();

   @PostConstruct
   public void init() {
      for (AuthorizationServerConfigurer configurer : configurers) {
         try {
            configurer.configure(endpoints);
         } catch (Exception e) {
            throw new IllegalStateException("Cannot configure enpdoints", e);
         }
      }
      endpoints.setClientDetailsService(clientDetailsService);
   }

//oauth/authorize
   @Bean
   public AuthorizationEndpoint authorizationEndpoint() throws Exception {
      AuthorizationEndpoint authorizationEndpoint = new AuthorizationEndpoint();
      FrameworkEndpointHandlerMapping mapping = getEndpointsConfigurer().getFrameworkEndpointHandlerMapping();
      authorizationEndpoint.setUserApprovalPage(extractPath(mapping, "/oauth/confirm_access"));
      authorizationEndpoint.setProviderExceptionHandler(exceptionTranslator());
      authorizationEndpoint.setErrorPage(extractPath(mapping, "/oauth/error"));
      authorizationEndpoint.setTokenGranter(tokenGranter());
      authorizationEndpoint.setClientDetailsService(clientDetailsService);
      authorizationEndpoint.setAuthorizationCodeServices(authorizationCodeServices());
      authorizationEndpoint.setOAuth2RequestFactory(oauth2RequestFactory());
      authorizationEndpoint.setOAuth2RequestValidator(oauth2RequestValidator());
      authorizationEndpoint.setUserApprovalHandler(userApprovalHandler());
      authorizationEndpoint.setRedirectResolver(redirectResolver());
      return authorizationEndpoint;
   }

//oauth/token
   @Bean
   public TokenEndpoint tokenEndpoint() throws Exception {
      TokenEndpoint tokenEndpoint = new TokenEndpoint();
      tokenEndpoint.setClientDetailsService(clientDetailsService);
      tokenEndpoint.setProviderExceptionHandler(exceptionTranslator());
      tokenEndpoint.setTokenGranter(tokenGranter());
      tokenEndpoint.setOAuth2RequestFactory(oauth2RequestFactory());
      tokenEndpoint.setOAuth2RequestValidator(oauth2RequestValidator());
      tokenEndpoint.setAllowedRequestMethods(allowedTokenEndpointRequestMethods());
      return tokenEndpoint;
   }

//oauth/check_token
   @Bean
   public CheckTokenEndpoint checkTokenEndpoint() {
      CheckTokenEndpoint endpoint = new CheckTokenEndpoint(getEndpointsConfigurer().getResourceServerTokenServices());
      endpoint.setAccessTokenConverter(getEndpointsConfigurer().getAccessTokenConverter());
      endpoint.setExceptionTranslator(exceptionTranslator());
      return endpoint;
   }

//oauth/confirm_access
   @Bean
   public WhitelabelApprovalEndpoint whitelabelApprovalEndpoint() {
      return new WhitelabelApprovalEndpoint();
   }

//oauth/error
   @Bean
   public WhitelabelErrorEndpoint whitelabelErrorEndpoint() {
      return new WhitelabelErrorEndpoint();
   }
   ......
}

AuthorizationServerSecurityConfiguration:该类继承了WebSecurityConfigurerAdapter,提供了认证服务的一些相关配置,比如对访问/oauth/token、/oauth/token_key、/oauth/check_token请求要有相对应的访问权限,新增了AuthorizationServerSecurityConfigurer的可配置类,用来配置对token的认证请求过滤器,比如ClientCredentialsTokenEndpointFilter,该过滤器会拦截oauth/token请求,并且对client_id和client_secret进行认证。除此之外,还配置了对实现了AuthorizationServerConfigurer的类进行回调,这样的话,只要实现AuthorizationServerConfigurer接口就可以自由的对认证服务进行相关的业务配置。

@Configuration
@Order(0)
@Import({ ClientDetailsServiceConfiguration.class, AuthorizationServerEndpointsConfiguration.class })
public class AuthorizationServerSecurityConfiguration extends WebSecurityConfigurerAdapter {

   @Autowired
   private List<AuthorizationServerConfigurer> configurers = Collections.emptyList();

   @Autowired
   private ClientDetailsService clientDetailsService;

   @Autowired
   private AuthorizationServerEndpointsConfiguration endpoints;

   @Autowired
   public void configure(ClientDetailsServiceConfigurer clientDetails) throws Exception {
      //回调AuthorizationServerConfigurer
      for (AuthorizationServerConfigurer configurer : configurers) {
         configurer.configure(clientDetails);
      }
   }

   @Override
   protected void configure(AuthenticationManagerBuilder auth) throws Exception {
     ...
   }

 //设置/oauth/token、/oauth/token_key、/oauth/check_token的认证规则
   @Override
   protected void configure(HttpSecurity http) throws Exception {
      AuthorizationServerSecurityConfigurer configurer = new AuthorizationServerSecurityConfigurer();
      FrameworkEndpointHandlerMapping handlerMapping = endpoints.oauth2EndpointHandlerMapping();
      http.setSharedObject(FrameworkEndpointHandlerMapping.class, handlerMapping);
      configure(configurer);
      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()
           .requestMatchers()
               .antMatchers(tokenEndpointPath, tokenKeyPath, checkTokenPath)
        .and()
           .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
      // @formatter:on
      http.setSharedObject(ClientDetailsService.class, clientDetailsService);
   }

   protected void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
      //回调AuthorizationServerConfigurer
      for (AuthorizationServerConfigurer configurer : configurers) {
         configurer.configure(oauthServer);
      }
   }

}

附流程图

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OAuth2是一种授权协议,用于授权第三方应用程序访问用户资源。Spring Security是一个强大的安全框架,可以与OAuth2协议一起使用来构建安全的应用程序。Spring Boot框架可以轻松地构建基于Spring Security和OAuth2的认证服务器。 下面是实现Spring Boot OAuth2认证服务器的步骤: 1. 添加Spring Security和OAuth2依赖项。在pom.xml文件中添加以下依赖项: ```xml <dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> <version>2.4.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` 2. 配置Spring Security。创建一个SecurityConfig,继承WebSecurityConfigurerAdapter,并覆盖configure方法: ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/oauth/token").permitAll() .anyRequest().authenticated() .and() .httpBasic(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } ``` 这里定义了一个UserDetailsService来获取用户信息,并使用BCryptPasswordEncoder来加密密码。configure方法定义了认证和授权的规则,这里允许访问/oauth/token路径。 3. 配置OAuth2。创建一个AuthorizationServerConfig,继承AuthorizationServerConfigurerAdapter,并覆盖configure方法: ```java @Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Autowired private UserDetailsService userDetailsService; @Autowired private DataSource dataSource; @Autowired private PasswordEncoder passwordEncoder; @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.jdbc(dataSource).passwordEncoder(passwordEncoder); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager) .userDetailsService(userDetailsService); } } ``` 这里使用了JDBC存储客户端信息和令牌,使用PasswordEncoder来加密客户端密码。configure方法定义了授权服务器的配置,包括客户端信息、令牌存储方式、身份验证管理器和用户详细信息服务。 4. 配置数据源。在application.properties文件中配置数据源,例如使用MySQL数据库: ``` spring.datasource.url=jdbc:mysql://localhost:3306/oauth2?useSSL=false spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver ``` 5. 测试OAuth2认证服务器。启动应用程序并访问/oauth/token路径,可以获取访问令牌。例如: ``` curl -X POST \ http://localhost:8080/oauth/token \ -H 'Authorization: Basic Y2xpZW50OnNlY3JldA==' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=password&username=user&password=password' ``` 这里使用了基本身份验证来验证客户端,用户名为client,密码为secret。授权型为密码,用户名为user,密码为password。成功获取访问令牌后,可以使用该令牌来访问需要授权的资源。 以上就是使用Spring Boot实现OAuth2认证服务器的步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值