Spring Boot Restful WebAPI集成 OAuth2

系统采用前后端分离的架构,采用OAuth2协议是很自然的事情。

下面开始实战,主要依赖以下两个组件:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
例外还要配置两个Config:

一、认证服务器

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

@Autowired
 private UserApprovalHandler userApprovalHandler;

@Autowired
 private AuthenticationManager authenticationManager;

@Autowired
 private TokenStore tokenStore;

@Autowired
 private MyUserService userService;

@Autowired
 private ClientDetailsService clientDetailsService;

@Override
 public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("aizoukeji")
// .authorizedGrantTypes("password", "authorization_code", "implicit")
 .authorizedGrantTypes("password")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read", "write", "trust")
.secret("18657189775")
.accessTokenValiditySeconds(60 * 2);//Access token is only valid for 2 minutes.
// refreshTokenValiditySeconds(600);//Refresh token is only valid for 10 minutes.
 }

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

@Bean
 public TokenStore tokenStore() {
return new InMemoryTokenStore();
}

@Bean
@Autowired
 public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore){
TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
handler.setTokenStore(tokenStore);
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
handler.setClientDetailsService(clientDetailsService);
return handler;
}

@Bean
@Autowired
 public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
}

二、资源服务器

@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "my_rest_api";

@Override
 public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).stateless(true);
}

@Override
 public void configure(HttpSecurity http) throws Exception {
// http.requestMatchers().antMatchers("/**")
// .and()
// .authorizeRequests().antMatchers("/v1/**").authenticated()
// .and()
// .exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());

 http.authorizeRequests().antMatchers("/v1/**").authenticated()
.and()
.exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}

踩过的坑

        一开始一直在配置WebSecurityConfigurerAdapter,其实这个跟ResourceServerConfigurerAdapter是冲突的,如果用OAuth来做认证的话,那么只要配置ResourceServerConfigurerAdapter就可以了

延伸

        Spring OAuth中有个SSO注解,可以帮助实现单点登录。等项目发展起来以后,我们可以用这个来实现账号的统一授权。

原文地址:https://www.cnblogs.com/mkxzy/p/7089066.html