spring-boot - 检索访问令牌后,Spring Boot OAuth2“访问此资源需要完全身份验证”
问题描述
我正在用 OAuth2 应用程序编写 Spring Boot。我的课程是:
AuthorizationServerConfig.class
<pre>
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends
AuthorizationServerConfigurerAdapter {
private static String REALM="CRM_REALM";
private static final int TEN_DAYS = 60 * 60 * 24 * 10;
private static final int ONE_DAY = 60 * 60 * 24;
private static final int THIRTY_DAYS = 60 * 60 * 24 * 30;
@Autowired
private DataSource dataSource;
@Autowired
private TokenStore tokenStore;
@Autowired
private UserApprovalHandler userApprovalHandler;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
private CrmUserDetailsService crmUserDetailsService;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws
Exception {
// clients.jdbc(dataSource);
clients.inMemory()
.withClient("crmClient1")
.secret("crmSuperSecret")
.authorizedGrantTypes("password", "refresh_token")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read", "write", "trust")
//.accessTokenValiditySeconds(ONE_DAY)
.accessTokenValiditySeconds(300)
.refreshTokenValiditySeconds(THIRTY_DAYS);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler)
.authenticationManager(authenticationManager)
.userDetailsService(crmUserDetailsService);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer)
throws Exception {
oauthServer.realm(REALM);
}
}
</pre>
资源服务器配置类
<pre>
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
//-- define URL patterns to enable OAuth2 security
http.
anonymous().disable()
.requestMatchers().antMatchers("/api/**")
.and().authorizeRequests()
.antMatchers("/api/**").access("hasRole('ADMIN') or hasRole('USER')")
.and().exceptionHandling().accessDeniedHandler(new
OAuth2AccessDeniedHandler());
}
}
</pre>
安全配置类
<pre>
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
private CrmUserDetailsService crmUserDetailsService;
@Override
@Order(Ordered.HIGHEST_PRECEDENCE)
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf().disable()
.authorizeRequests()
.antMatchers("/about").permitAll()
.antMatchers("/signup").permitAll()
.antMatchers("/oauth/token").permitAll()
//.antMatchers("/api/**").authenticated()
.anyRequest().authenticated()
.and()
.httpBasic()
.realmName("CRM_REALM");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(crmUserDetailsService)
.passwordEncoder(passwordEncoder());
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@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;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
</pre>
SecurityWebApplicationInitializer.class
<pre>
public class SecurityWebApplicationInitializer extends
AbstractSecurityWebApplicationInitializer {
}
</pre>
MethodSecurityConfig.class
<pre>
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration
{
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
</pre>
注册服务类
<pre>
@Service
@Transactional
public class SignupService {
@Autowired
private UserRepository userRepository;
@Autowired
PasswordEncoder passwordEncoder;
public User addUser(User user) {
user.setPassword(passwordEncoder.encode(user.getPassword()));
return userRepository.save(user);
}
/**
*
* set up a default customer with two roles USER and ADMIN
*
*/
@PostConstruct
private void setupDefaultUser() {
if (userRepository.count() == 0) {
userRepository.save(new User("crmadmin",
passwordEncoder.encode("adminpass"),
Arrays.asList(new UserRole("USER"), new
UserRole("ADMIN"))));
}
}
}
</pre>
在我发送请求 localhost:8080/oauth/token 并获得 access_token 和 refresh_token 之后,当我尝试使用 Authorization: Bearer (access_token) 发送 api 请求时,我得到了错误:
<pre>
{
"timestamp": 1534343851414,
"status": 401,
"error": "Unauthorized",
"message": "Full authentication is required to access this resource",
"path": "/api/customers"
}
</pre>
你可以帮帮我吗?
解决方案
推荐阅读
- android - 如果 Android 应用程序不进入 Play 商店,是否需要增加 versionCode?
- node.js - 如何在护照谷歌身份验证回调函数中获取用户个人资料数据?
- r - 是否有适当的方法将图像包含在 R Bookdown 项目的边距中?
- vba - 使用从 VBA 执行的 WinSCP 批处理脚本返回 FTP 上传的状态?
- python - Django-channels 是否可以发送消息并等待响应?
- assembly - 汇编 emu8086 - 如何打印两个相加的数字?
- reactjs - 不能在 JSX 属性中使用布尔值
- java - 无法启动 Maven 服务 - 找不到类#
- java - 从没有特定值的 Hashmap 中删除项目
- java - 同时比较数组中的字符串和整数