OAuth 2 spring Webclient for password grant - java

In the Rest template I was able to to do the following. I'm trying to implement the same using spring webclient and so far I couldn't find any documentation on how to set this up.
#Bean
public OAuth2RestTemplate createRestTemplate() {
ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
resource.setAccessTokenUri(accessTokenUri);
resource.setClientId(clientID);
resource.setClientSecret(clientSecret);
resource.setGrantType("password");
resource.setScope(Arrays.asList(scope));
resource.setUsername("user");
resource.setPassword("pass");
return new OAuth2RestTemplate(resource);
}

Related

How to retrieve the configured base URL from the Spring WebClient?

The Spring reactive WebClient can be built with a base URL:
import org.springframework.web.reactive.function.client.WebClient;
...
#Bean
public WebClient webClient(WebClient.Builder builder) {
return builder
.baseUrl("http://example.org")
.build();
// or alternatively a shortcut
// return WebClient.create("http://example.org");
}
Is there a way to retrieve the configured base URL back from an already existing WebClient instance?
Something like:
#Autowired
private WebClient webClient;
...
String baseUrl = webClient.getBaseUrl(); // I want to know how this WebClient is configured
assertEquals("http://example.org", baseUrl);
Or something like
var configuration = webClient.getConfiguration();
String baseUrl = configuration.getBaseUrl();
assertEquals("http://example.org", baseUrl);
WebClient is an interface with no API to get back the base URL, so maybe some implementation class has one but that will make your code dependent on the chosen one.

How do I configure a client Java application which must request a token from an authorization server using a 'password' grant type?

I need to implement a client Java application with Maven which makes requests from a resource server. In order for a request to be authorized a bearer token has to be provided in the header of the request. To obtain the token, another request has to be done before. The server provides me all parameters needed to make the token request: client_id, client_secret, username, password, etc. The grant_type of the token request is 'password'.
The server is based on GraphQL so I'm using the following Maven plugin in order to generate the Java classes which perform the GraphQL queries:
https://github.com/graphql-java-generator/graphql-maven-plugin-project
They provide a tutorial on how to "Access to an OAuth2 GraphQL server":
https://graphql-maven-plugin-project.graphql-java-generator.com/client_oauth2.html
As they mention in the tutorial, in order to connect to the OAuth server, I must use Spring. The tutorial explains how to access a server which uses 'client_credentials' grant type. I am not familiar with spring and spring-security so I didn't manage to configure my Spring client for 'password' grant type (all I did was to change in the application.properties the grant_type from 'client_credentials' to 'password'). Where the username and password need to be configured? What additional configurations do I need to make? Is there any way to do this without Spring? What I'm trying to obtain is way which requests the token from the authorization server and (under the hood) adds the token to the resource requests.
Following is the piece of code which I have following the tutorial:
#SpringBootApplication(scanBasePackageClasses = { MinimalSpringApp.class, GraphQLConfiguration.class})
public class MinimalSpringApp implements CommandLineRunner
{
/**
* The executor, that allows to execute GraphQL queries. The class name is the one defined in the GraphQL schema.
*/
#Autowired
QueryExecutor queryExecutor;
public static void main( String[] args )
{
SpringApplication.run( MinimalSpringApp.class, args );
}
/**
* This method is started by Spring, once the Spring context has been loaded. This is run, as this class implements
* {#link CommandLineRunner}
*/
#Override
public void run( String... args ) throws Exception
{
// Create query
GraphQLRequest softwareTechnologyRequest = queryExecutor.getSoftwareTechnologyGraphQLRequest( "{ id name }" );
SoftwareTechnologyFilter filter = new SoftwareTechnologyFilter();
// Execute query
List<SoftwareTechnology> technologies =
queryExecutor.softwareTechnology( softwareTechnologyRequest, filter, 0, "", 1000, "", 0,
Collections.emptyList() );
System.out.println( technologies );
}
#Bean
ServerOAuth2AuthorizedClientExchangeFilterFunction serverOAuth2AuthorizedClientExchangeFilterFunction(
ReactiveClientRegistrationRepository clientRegistrations) {
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrations, new UnAuthenticatedServerOAuth2AuthorizedClientRepository());
oauth.setDefaultClientRegistrationId("provider_test");
return oauth;
}
When I run the application it throws an IllegalStateException caused by '401 Unauthorized from POST'.
SOLVED
I needed to create my own client manager bean, where the username and password are set. There is an example in the Spring official documentation at the "Resource Owner Password Credentials" section:
https://docs.spring.io/spring-security/site/docs/5.2.0.RELEASE/reference/htmlsingle/#oauth2client
#Bean
public ReactiveOAuth2AuthorizedClientManager authorizedClientManager( ReactiveClientRegistrationRepository clientRegistrationRepository,
ReactiveOAuth2AuthorizedClientService authorizedClientService)
{
ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
ReactiveOAuth2AuthorizedClientProviderBuilder.builder().password().refreshToken().build();
AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager =
new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager( clientRegistrationRepository, authorizedClientService );
authorizedClientManager.setAuthorizedClientProvider( authorizedClientProvider );
authorizedClientManager.setContextAttributesMapper( contextAttributesMapper() );
return authorizedClientManager;
}
private Function<OAuth2AuthorizeRequest, Mono<Map<String, Object>>> contextAttributesMapper()
{
return authorizeRequest -> {
Map<String, Object> contextAttributes = new HashMap<>();
contextAttributes.put( OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, "username" );
contextAttributes.put( OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, "password" );
return Mono.just(contextAttributes);
};
}
Then the bean from the graphql java generator plugin tutorial needed to be adapted in order to use the provided client manager:
#Bean
ServerOAuth2AuthorizedClientExchangeFilterFunction serverOAuth2AuthorizedClientExchangeFilterFunction(
ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(
authorizedClientManager);
oauth.setDefaultClientRegistrationId("provider_test");
return oauth;
}

Spring security Oauth2 set different token per browser tap

I want to get different token per browser tap to get differents roles and user logged against oauth server in the same browser
I have requested oauth login against own oauth server. I develop own client using Spring security Oauth2...
OAUTHCONF.JAVA
Spring security client...
/**
* Called after executed Configuration "addFilterBefore"
*
* #return OAuth2ClientAuthenticationProcessingFilter
*/
private OAuth2ClientAuthenticationProcessingFilter oauthFilter() {
OAuth2ClientAuthenticationProcessingFilter oauthFilter = new OAuth2ClientAuthenticationProcessingFilter("/login");
// OAuth2RestTemplate > Spring Boot does not automatically create such a bean,
OAuth2RestTemplate oauthTemplate = new OAuth2RestTemplate(oauth(), oauth2ClientContext);
UserInfoTokenServices tokenServices = new UserInfoTokenServices(oauthResource().getUserInfoUri(), oauth().getClientId());
tokenServices.setRestTemplate(oauthTemplate);
oauthFilter.setRestTemplate(oauthTemplate);
oauthFilter.setTokenServices(tokenServices);
return oauthFilter;
}
oauth configuration...
#Autowired
private OAuth2ClientContext oauth2ClientContext;
#Bean
#ConfigurationProperties("oauth.resource")
public ResourceServerProperties oauthResource() {
return resourceServerProperties;
}
#Bean
#ConfigurationProperties("oauth.client")
public AuthorizationCodeResourceDetails oauth() {
return authorizationCodeResourceDetails;
}
INDEX.HTML
View...
if (oauth2ClientContext!=null && oauth2ClientContext.getAccessToken()!=null) {
labelInformation.setText("Access token > " + oauth2ClientContext.getAccessToken());
}
In this mode, in the first tap I have requested the token. In the second tab shows me directly token... Is there a way to request different token via Spring security per tab?

How to configure OAuth2 RestTemplate for spring boot config client

How can I configure a spring boot config client microservice to fetch its configuration from an OAuth2 configServer which is #EnableResourceServer ?
I have one OAuth2 Authorization server (#EnableAuthorizationServer). There is a configServer (#EnableConfigServer) which I have configured to respond only to valid requests authorized by authorization server containing JWT tokens.
There is also a microservice client APP1 of the config server which needs to fetch its configuration upon startup from the aforementioned config server. Since the server only responds to requests containing valid access tokens (jwt tokens) I tried to inject OAuth2RestTemplate into ConfigServicePropertySourceLocator so that my config client (APP1) could fetch its config.
In order to do that I tried the partial solution which was discussed here.
This is my OAuth2 ready RestTemplate that I want to inject
#Configuration
public class OAuthConfig {
#Bean
public OAuth2RestTemplate oauth2RestTemplate(OAuth2ClientContext oauth2ClientContext,
OAuth2ProtectedResourceDetails details) {
return new OAuth2RestTemplate(details, oauth2ClientContext);
}}
and this is my custom property locator
public class CustomConfigServicePropertySourceLocator {
#Autowired
private ConfigurableEnvironment environment;
#Autowired
private RestTemplate restTemplate;
#Bean
public ConfigClientProperties configClientProperties() {
ConfigClientProperties client = new ConfigClientProperties(this.environment);
client.setEnabled(false);
return client;
}
#Bean
#Primary
public ConfigServicePropertySourceLocator configServicePropertySourceLocator() {
ConfigClientProperties clientProperties = configClientProperties();
ConfigServicePropertySourceLocator configServicePropertySourceLocator = new ConfigServicePropertySourceLocator(
clientProperties);
configServicePropertySourceLocator.setRestTemplate(restTemplate);
return configServicePropertySourceLocator;
}}
I Followed the instructions in Customizing the Bootstrap Configuration
I created a META_INF > spring.factories file containing
org.springframework.cloud.bootstrap.BootstrapConfiguration=com.company.mcapp.CustomConfigServicePropertySourceLocator
By debugging I can see that this custom locator will get called but my APP1 is failing to contact config server to fetch the configurations.
In initialize method of PropertySourceBootstrapConfiguration (below) I can see that the propertySourceLocators does not contain my CustomConfigServicePropertySourceLocator.
#Override
public void initialize(ConfigurableApplicationContext applicationContext) {
CompositePropertySource composite = new CompositePropertySource(
BOOTSTRAP_PROPERTY_SOURCE_NAME);
AnnotationAwareOrderComparator.sort(this.propertySourceLocators);
boolean empty = true;
ConfigurableEnvironment environment = applicationContext.getEnvironment();
for (PropertySourceLocator locator : this.propertySourceLocators) {
PropertySource<?> source = null;
source = locator.locate(environment);
if (source == null) {
continue;
}
logger.info("Located property source: " + source);
composite.addPropertySource(source);
empty = false;
}
.
.
.
UPDATE: The issue was a silly mistake That I made. Instead of creating META-INF I created META_INF.

Google Oauth2 login with spring boot using OAuth2ClientAuthenticationProcessingFilter

1.Using spring security oauth2 dependcy.Making successful authentication to google but i cant get refresh token.How do i get refresh token ?ı can get only access token from PrincapalUser object.
in WebSecurityConfigurer Adapter
2.
private OAuth2ClientAuthenticationProcessingFilter filter() {
// Creating the filter for "/google/login" url
OAuth2ClientAuthenticationProcessingFilter oAuth2Filter = new
OAuth2ClientAuthenticationProcessingFilter(
"/google/login");
authorizationCodeResourceDetails.setPreEstablishedRedirectUri("http://localhost:8080/");
List<String> scopes = authorizationCodeResourceDetails.getScope();
authorizationCodeResourceDetails.setGrantType("authorization_code");
// Creating the rest template for getting connected with OAuth service.
// The configuration parameters will inject while creating the bean.
OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(authorizationCodeResourceDetails,
oauth2ClientContext);
oAuth2Filter.setRestTemplate(oAuth2RestTemplate);
// setting the token service. It will help for getting the token and
// user details from the OAuth Service
String userInfo = resourceServerProperties.getUserInfoUri();
String clientId = resourceServerProperties.getClientId();
UserInfoTokenServices tokenService = new UserInfoTokenServices(resourceServerProperties.getUserInfoUri(),
resourceServerProperties.getClientId());
// tokenService.setTokenType(DefaultOAuth2AccessToken.REFRESH_TOKEN);
oAuth2Filter.setTokenServices(tokenService);
// oAuth2Filter.setTokenServices(defaultToken());
return oAuth2Filter;
}
I added google url param requriments , spring boot application.yml social authentication configuration.

Categories

Resources