Secure Server-to-Server Communication with Spring Boot and OAuth 2.0

Pallavi Darbhamulla

Its the exact same copy/paste from your code except that the log statement goes inside the controller. The exact same version with the Command Line Runner works exactly as your example.
Here is the relevant code:
@Bean
@ConfigurationProperties(“example.oauth2.client”)
protected fun oAuthDetails(): ClientCredentialsResourceDetails {
return ClientCredentialsResourceDetails()
}

@Bean
protected fun restTemplate(): OAuth2RestTemplate {
val defaultUriTemplateHandler = DefaultUriTemplateHandler()
defaultUriTemplateHandler.setBaseUrl(serverBaseUrl)
var oAuth2RestTemplate = OAuth2RestTemplate(oAuthDetails())
oAuth2RestTemplate.uriTemplateHandler = defaultUriTemplateHandler
return oAuth2RestTemplate
}

The ClientApplication class is:
@SpringBootApplication
class AuthClientApplication(val restTemplate: OAuth2RestTemplate) : CommandLineRunner{
private val logger = KotlinLogging.logger(this.javaClass.canonicalName)

override fun run(vararg args: String?) {
logger.info(“MOD: {}”, restTemplate.getForObject("/hello-service", String::class.java))
}

}
fun main(args: Array<string>) {
runApplication<authclientapplication>(*args)
}

This works perfectly.

The controller version is:
class AuthClientController(val restTemplate: OAuth2RestTemplate) {
private val logger = KotlinLogging.logger(this.javaClass.canonicalName)

@GetMapping("/hello")
fun get() {
logger.info(“MOD: {}”, restTemplate.getForObject("/hello-service", String::class.java))

}


}

This code above is where if I try to go to /hello, it takes me to a login page

Brian Demers

Is the login page hosted at /login? If so i’m guessing that is the Spring Security Starter protecting your controller

Pallavi Darbhamulla

I actually didnt create a login page but yeah now that you mention it, its probably the spring security starter interfering. All I did was convert your example to a Kotlin version and tried putting that same log statement in the controller to see if that worked. Thanks!

Yevgeniy Alexeyenko

Hi! Thanks for great article! But, let’s say i have multiple such clients, each with it’s own clientId and secret, and they all request the same resource server. Do I need to specify multiple clients in resource server yml config? How the configuration will change in this case to handle multiple clients?

Brian Demers

Multiple clients shouldn’t be an issue assuming they each ended up with a token from the same IdP. If you need to support multiple IdP’s you may need a little custom code to figure out were to send the token.

Hector Abreu

Hi Brian,
can the client be implemented as a template for any oauth2 server? i’ve seen hundreds of posts about oauth2 client credential implementation, however, none have an adaptable template one can use for any web app. the sample code seems to only be applicable to the accompanying custom server side instance.,
i am looking for a template/example of the this grant where i can make a token request to an aouth2 server; serverX, get a token, then use the received token to make a call to an end point and get data.

can you make such a document? sort of a open ended template anyone can use?

thanks Brian

Brian Demers

Hey @disqus_M76ynP8k49:disqus!
I’m not sure I’m following your question. What portion are you trying to template?

Hector Abreu

Thanks Brian for offering your advice. Please pardon my lack of knowledge on this subject, do you have a sample api call and data to html table sample i could look at?:I am starting to think that perhaps my idea for this app was a bit too ambitious… Hey Brian, in case someone asks me about web development contracts, can i get your contact information? I hope that asking my question is allowed on this forum. again, perhaps you have time to share a sample api call and getting the json reply into a wet table…

Brian Demers

@disqus_M76ynP8k49:disqus, The Spring Security project has a bunch of great samples: https://github.com/spring-p…
I’d suggest starting there!

Vijay Ganapathy

Hey Brian,

Thanks for this article. I am trying to do a similar server to server implementation using .net core. I found few resources in okta docs for .net core, however all of them require a UI for password authentication as a first level of authentication before tokens are issued by okta. I can probably try understanding this article and try mimicking it in .net core. Before that, I would like to know if there are any resources which explains the same in .net core?

Brian Demers

Hey @vijay_ganapathy:disqus !
Take a look at this one: Build Secure Microservices with AWS Lambda and ASP.NET Core

Or this one:
Build a REST API with ASP.NET Core 2.2

Vijay Ganapathy

Thanks for the link Brian. I was able to implement it in .net core by following one of the links you provided. I have a design question so posting it as a separate comment. My scenario is for server to server communication. I have set up a application for the consumer in the okta developer account. I have implemented a token service which basically receives the client id and client secret and returns an access token to the consumer, let’s say this is consumer A. When the consumer A passes the access token in the authorization header, access will be provided to the endpoints. Here comes the question – If there is another consumer B for the same endpoint, for which I believe I’ll set up as a different client application with respective client id and secret in the okta developer account, a separate access token will be provisioned to that consumer and he’ll be able to access the endpoints fine. However, if I want to differentiate between client A and client B, what is the best way to do that? – One way to do that is to store the client id and client secret at the server side and match the credentials provided by the consumer to find out who is calling the method. But I don’t know if that’s the best way to do it.

To simplify - Two consumers(these are servers as well) get authenticated into the system using access tokens. How do I identify the consumer using okta so that I can provide customized access to my endpoints based on who the consumer is?

Brian Demers

Hey @vijay_ganapathy:disqus !
The client id is in the access token as the ‘cid’ claim. This could be retrieved by treating the access token as a JWT (or by using the OAuth introspection endpoint.

Keep us posted!

BK

Hi . I am going through the article, Thanks seems it is straight forward but in developer edition -Okta I am not able to see any place where I can create scope or create service , I am I missing something here ?

Brian Demers

From your Okta Admin Console, you can browse to APIAuthorization Servers → Select “default” from the list.
Finally click the “Scopes” tab

The direct URL is probably something like:
https://dev-123456-admin.ok…
(where you replace the domain name with your Okta domain name)

Yaoming

Thanks for the article. How can I adjust this if I have a custom authorization server ?

Brian Demers

Hey @disqus_NuupYTvdXd:disqus !
You just need to change the issuer, just replace the issuer-uri-from-above with the issuer URL for your Custom authorization server.

Anuj Kumar Verma

Do we really need to specify client_id and client_secret in resource
server since resource server can verify access token by contacting
authorization server so why it needs client_id and client_secret, it can
check the aud: (audience) field to recognize that the token is meant
for its resources only

Anuj Kumar Verma

answering my own question here :
As mentioned in Okta doc

"Note: The /introspect endpoint requires client authentication."
Hence it is required to have one valid clientId/clientSecret on server side , it can be completely different from those given to the users of the API.

Rafael Braga

I’ve tried that exactly same configuration but when I do a request on a resource that needs authentication, I get the 401 error. I’ve double-checked my yml file and aside from the differences in the URLs that I’m using, everything else is the same. Any suggestions?