При следующей конфигурации я могу получить токен. Но при использовании токена для запроса информации о пользователе на этом сервере ответ 401 не авторизован. Что еще более странно, информация о пользователе может быть возвращена, используя имя пользователя / пароль, вместо использования какого-либо токена. Я также попробовал это с авторизацией почтальона oauth2, какой бы токен я ни поставил, если cook ie верен, информация о пользователе будет возвращена. Я сравнил код со многими учебниками и не смог найти проблему. настроить сервер oauth2:
@EnableAuthorizationServer
@Configuration
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("customizedClientDetailsService")
ClientDetailsService clientDetailsService;
AuthenticationManager authenticationManager;
public AuthorizationServerConfig(AuthenticationConfiguration authenticationConfiguration) throws Exception {
this.authenticationManager = authenticationConfiguration.getAuthenticationManager();
}
/**
* Exposes 2 endpoints for checking tokens. By default, they are denyAll(). To allow get token (using code) through
* /oauth/token, tokenKeyAccess should be permitAll().
*
* @param security
* @throws Exception
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()").allowFormAuthenticationForClients();
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.authenticationManager(this.authenticationManager)
.accessTokenConverter(accessTokenConverter())
.tokenStore(tokenStore());
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
// converter.setKeyPair(this.keyPair); // Using RSA private key to encrypt.
converter.setSigningKey("myscretekey");
return converter;
}
настроить пользователя:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* Using in memory user for demo. In practice, it is loaded from redis or db table.
* @return
*/
@Bean
@Override
public UserDetailsService userDetailsService() {
return new InMemoryUserDetailsManager(
User.withDefaultPasswordEncoder()
.username("enduser")
.password("password")
.roles("USER")
.build());
}
настроить клиента:
@Component("customizedClientDetailsService")
public class CustomizedClientDetailsService implements ClientDetailsService {
/**
* Local initialized clientDetails for demo.
* @param clientId
* @return
* @throws ClientRegistrationException
*/
@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
BaseClientDetails details = new BaseClientDetails();
details.setClientId("first-client");
details.setClientSecret("{noop}noonewilleverguess");
// could be one or many of "authorization_code", "password", "client_credentials", "implicit", "refresh_token"
details.setAuthorizedGrantTypes(Arrays.asList("authorization_code", "refresh_token"));
details.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));
details.setScope(Arrays.asList("read", "write")); // Without a given scope, Spring security kept asking for grant.
details.setRefreshTokenValiditySeconds(1800);
details.setAccessTokenValiditySeconds(1800);
Set<String> set = new HashSet<>();
set.add("http://localhost:8080/oauth/login/client-app");
details.setRegisteredRedirectUri(set);
return details;
}
}
информация о пользователе:
@RestController
public class UserInfoController {
@GetMapping("user/info")
public Object getUserInfo() {
Authentication a = SecurityContextHolder.getContext().getAuthentication();
return a.getPrincipal();
}
}
получить токен:
curl -X POST \
'http://localhost:8080/oauth/token?grant_type=authorization_code&client_id=first-client&client_secret=noonewilleverguess&code=b19dqe'
получить информацию о пользователе:
curl -X GET \
http://localhost:8080/user/info \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1ODg1MTE2NjgsInVzZXJfbmFtZSI6ImVuZHVzZXIiLCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwianRpIjoiZmViZDgzMTMtMjllMS00M2M4LWEzNGUtMTU5OWM0NmYyNTE4IiwiY2xpZW50X2lkIjoiZmlyc3QtY2xpZW50Iiwic2NvcGUiOlsicmVhZCJdfQ.0rq-tFnA9amh7LT-3wyCN1GK9ZpF1ry9rsN-kXT4Xec'