There's a support for OpenAPI in this project. You can access OpenApi's access token and make authenticated calls to OpenAPI resources right inside a LTI SpringBoot Security powered application.
This project has a fully functional implementation and can be used as an example
The support relies in Spring AOP and Oauth2. Just make sure there's these dependencies in your pom.xml
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
See pom.xml in this project
In your ApplicationSecurity class:
-
Mark your Application with the annotations:
@EnableOAuth2Clientto allow oauth2 client calls
@EnableAspectJAutoProxyto allow Advices in the app -
Define a
OAuth2ClientContext oauth2ClientContext. This will be injected by Spring Security thanks to@EnableOAuth2Client:@Autowired OAuth2ClientContext oauth2ClientContext; -
Define the filter for redirecting to OpenAPI:
private OpenApiClientFilter openapiFilter() { OpenApiClientFilter openApiFilter = new OpenApiClientFilter(OPEN_API_URI); openApiFilter.setRestTemplate(openApiRestTemplate()); return openApiFilter; } @Bean @ConfigurationProperties("openapi.client") public AuthorizationCodeResourceDetails openapi() { return new AuthorizationCodeResourceDetails(); } @Bean public FilterRegistrationBean oauth2ClientFilterRegistration( OAuth2ClientContextFilter filter) { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(filter); registration.setOrder(-100); return registration; } @Bean public OAuth2RestOperations openApiRestTemplate() { return new OAuth2RestTemplate(openapi(), oauth2ClientContext); } -
Add the filter to your filter chain:
@Override protected void configure(HttpSecurity http) throws Exception { http ... // your configuration .and().addFilterBefore(openapiFilter(), BasicAuthenticationFilter.class) ...// your configuration } -
Define the advice bean:
@Bean public OpenApiAuthorizedAspect openApiAuthorizedAspect() { final OpenApiAuthorizedAspect openApiAuthorizedAspect = new OpenApiAuthorizedAspect(); openApiAuthorizedAspect.setRedirectUri("/login/openapi"); return openApiAuthorizedAspect; }The URI in
openApiAuthorizedAspect.setRedirectUriMUST be the same as the uri of theOpenApiClientFilter.
See edu.uoc.elearn.lti.provider.config.ApplicationSecurity.java in this project
Add to your application.properties the configuration for OpenAPI:
# Open API Client Configuration
openapi.client.accessTokenUri=https://cv.uoc.edu/webapps/uocapi/oauth/token
openapi.client.userAuthorizationUri=https://cv.uoc.edu/webapps/uocapi/oauth/authorize
openapi.client.tokenName=access_token
openapi.client.clientAuthenticationScheme=form
openapi.client.authenticationScheme=query
openapi.client.scope=READ READ_GRADEBOOK
Adapt the scope's to your application's needs.
Adapt the URL's as well if you are targeting others environments.
See application.properties in this project
We store client id and secret in a configuration file (typically application-{devel|pro}.yml):
# Open Api client
openapi:
client:
clientId: "your_client_id"
clientSecret: "your_secret"
See application.properties in this project
The annotation edu.uoc.elearn.openapi.spring.OpenApiAuthorized defines methods to be called only when the application has been authorized by the user in OpenApi.
If the application hasn't been authorized (and the application has been configured the filter properly), the application redirects itself to the authorization process in OpenAPI
See edu.uoc.elearn.lti.provider.controller.UserController.java in this project
If you want OpenApi to redirect exactly where you were, just add a parameter HttpServletRequest request to your edu.uoc.elearn.openapi.spring.OpenApiAuthorized's annotated method
See edu.uoc.elearn.lti.provider.controller.UserController.java in this project
Add urls in application.properties:
openapi.client.resource.user=https://cv.uoc.edu/webapps/uocapi/api/v1/user
-
Add beans in your controller:
@Autowired OAuth2RestOperations openApiRestTemplate; @Value("${openapi.client.resource.user}") private String userResourceUrl; -
Make the call:
Map userData = openApiRestTemplate.getForObject(userResourceUrl, Map.class);
See edu.uoc.elearn.lti.provider.controller.UserController.java in this project
We should definitely improve this, making a client library with objects