# How to Use Client Credentials Flow with Spring Security

**URL:** <https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370>\
**Category:** Developer Blog Comments\
**Created:** [May 5, 2021, 2:33pm UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370 "2021-05-05T14:33:23Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![oktadev-blog](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/oktadev-blog/32/3422_2.png) [@oktadev-blog](https://devforum.okta.com/u/oktadev-blog)\
**Post date:** [May 5, 2021, 2:33pm UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/1 "2021-05-05T14:33:23Z")

</div>

[How to Use Client Credentials Flow with Spring Security](https://developer.okta.com/blog/2021/05/05/client-credentials-spring-security)

Learn how to use OAuth 2.0’s client credentials grant to communicate between apps secured by Spring Security.

---

<div class="post-metadata">

**Author:** ![oktadev-blog](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/oktadev-blog/32/3422_2.png) [@oktadev-blog](https://devforum.okta.com/u/oktadev-blog)\
**Post date:** [June 8, 2021, 11:10am UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/2 "2021-06-08T11:10:55Z")

</div>

**Michal Basl**

Hello, thx for great article, seems works as expected with one exception ☹  
I’m receiving from authority server error due to Accept=application/json HTTP header is missing in request.  
Could it be customized, somehow?

---

<div class="post-metadata">

**Author:** ![oktadev-blog](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/oktadev-blog/32/3422_2.png) [@oktadev-blog](https://devforum.okta.com/u/oktadev-blog)\
**Post date:** [June 14, 2021, 7:03am UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/3 "2021-06-14T07:03:27Z")

</div>

**Javier Vazquez**

Thank your for the post! Without doubt the best one about how to do OAuth2 properly with Spring, everything crystal water clear!  
Regards,

---

<div class="post-metadata">

**Author:** ![oktadev-blog](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/oktadev-blog/32/3422_2.png) [@oktadev-blog](https://devforum.okta.com/u/oktadev-blog)\
**Post date:** [September 17, 2021, 4:05am UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/4 "2021-09-17T04:05:46Z")

</div>

**srinivas kucherla**

This is a great post!. When i followed the steps. I am getting error on this line . Its expecting authentication but passed string to principal. Could you please guide me on this ?  
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(“okta”)  
.principal(“Demo Service”)  
.build();

---

<div class="post-metadata">

**Author:** ![oktadev-blog](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/oktadev-blog/32/3422_2.png) [@oktadev-blog](https://devforum.okta.com/u/oktadev-blog)\
**Post date:** [September 17, 2021, 3:01pm UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/5 "2021-09-17T15:01:22Z")

</div>

**srinivas kucherla**

Hi Andrew!..Could you please share your thoughts on the above authorizeRequest. Any help or pointers is a great help.

Thank you   
Shree

---

<div class="post-metadata">

**Author:** ![oktadev-blog](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/oktadev-blog/32/3422_2.png) [@oktadev-blog](https://devforum.okta.com/u/oktadev-blog)\
**Post date:** [September 17, 2021, 4:30pm UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/6 "2021-09-17T16:30:57Z")

</div>

**Brian Demers**

Hey @srinivaskucherla! Can you share the exact error message you are seeing?

---

<div class="post-metadata">

**Author:** ![oktadev-blog](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/oktadev-blog/32/3422_2.png) [@oktadev-blog](https://devforum.okta.com/u/oktadev-blog)\
**Post date:** [September 17, 2021, 7:03pm UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/7 "2021-09-17T19:03:30Z")

</div>

**Brian Demers**

It looks like you changed port to `11033` and added a callback route?   
Are you mixing different examples together? In general, you should let the framework (Spring Security in this case) handle the callback.

Maybe we should take a step back and move this to the [Okta Developer Forum](https://devforum.okta.com/ "https://devforum.okta.com/")? (if you start a thread, please add a link back here so anyone can follow along!)

---

<div class="post-metadata">

**Author:** ![oktadev-blog](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/oktadev-blog/32/3422_2.png) [@oktadev-blog](https://devforum.okta.com/u/oktadev-blog)\
**Post date:** [September 17, 2021, 8:13pm UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/8 "2021-09-17T20:13:45Z")

</div>

**srinivas kucherla**

[https://devforum.okta.com/t…](https://devforum.okta.com/t/authrizerequest/16210 "https://devforum.okta.com/t/authrizerequest/16210") I created a new topic. Also my other question is my local host runs at 11033 port. I have updated that in Application configuration in Okay admin console. Is port number an issue ?

---

<div class="post-metadata">

**Author:** ![oktadev-blog](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/oktadev-blog/32/3422_2.png) [@oktadev-blog](https://devforum.okta.com/u/oktadev-blog)\
**Post date:** [September 18, 2021, 2:13am UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/9 "2021-09-18T02:13:02Z")

</div>

**Brian Demers**

The port number is less of an issue, if you have everything configured. If you have trouble though I usually recommend, getting things working as is, and then changing one thing at a time until get to your end goal.

---

<div class="post-metadata">

**Author:** ![oktadev-blog](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/oktadev-blog/32/3422_2.png) [@oktadev-blog](https://devforum.okta.com/u/oktadev-blog)\
**Post date:** [September 23, 2021, 9:46am UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/10 "2021-09-23T09:46:24Z")

</div>

**Paul Cannon**

Hi Andrew, this was great, thanks for posting, one issue I’m having is I have multiple clients and so require multiple OAuthClientConfiguration classes but can only seem to define the one, any thoughts on how this can be achieved please?  
Thanks!

---

<div class="post-metadata">

**Author:** ![oktadev-blog](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/oktadev-blog/32/3422_2.png) [@oktadev-blog](https://devforum.okta.com/u/oktadev-blog)\
**Post date:** [September 23, 2021, 2:05pm UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/11 "2021-09-23T14:05:32Z")

</div>

**Brian Demers**

You _should_ be able to define multiple `ClientRegistration`, each with a unique id. But you would only define the other beans like the `ClientRegistrationRepository` once.

Does that help?

---

<div class="post-metadata">

**Author:** ![shreekucherla](https://avatars.discourse-cdn.com/v4/letter/s/ccd318/32.png) [@shreekucherla](https://devforum.okta.com/u/shreekucherla)\
**Post date:** [October 27, 2021, 3:16am UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/12 "2021-10-27T03:16:18Z")

</div>

Hi,  
Can you we add clients dynamically after the service starts. If so , how can resolve the clients . Use case : Lets say customer entering the IDP information configuration in a form. We want to make sure entered values are actually valid values and working. So want to create a temp client add it to ClientRegistrationRepository and test it. If the test is successful. Then we can allow the user to save the auth config values. Any thoughts on this would be a great help.

Thank you  
Shree

---

<div class="post-metadata">

**Author:** ![pallavi.bhardwaj](https://avatars.discourse-cdn.com/v4/letter/p/35a633/32.png) [@pallavi.bhardwaj](https://devforum.okta.com/u/pallavi.bhardwaj)\
**Post date:** [December 20, 2021, 4:06pm UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/13 "2021-12-20T16:06:54Z")

</div>

Hi,  
It was a great article but is there any way to use client registration with certificate and private key instead of client secret? I think it’s not yet supported by spring security? Do you have any experience in using client certificate authentication instead of client secret with spring security? I would appreciate if someone would know about it. Else I have to write my own code to handle authentication mechanism.

---

<div class="post-metadata">

**Author:** ![bdemers](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/bdemers/32/23_2.png) [@bdemers](https://devforum.okta.com/u/bdemers)\
**Post date:** [December 20, 2021, 4:34pm UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/14 "2021-12-20T16:34:46Z")

</div>

Hey @pallavi.bhardwaj!

Can you tell me a little more about what you are trying to do? Are you using the retrieved access token to make calls back to the Okta API? If so, you can use our [Java SDK](https://github.com/okta/okta-sdk-java), which supports this flow.

---

<div class="post-metadata">

**Author:** ![sjimil](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/sjimil/32/3729_2.png) [@sjimil](https://devforum.okta.com/u/sjimil)\
**Post date:** [March 2, 2022, 12:13pm UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/15 "2022-03-02T12:13:01Z")

</div>

Hi @oktadev-blog , @bdemers  
Thank you for the great blog and understanding on OIDC and Spring Boot2. I have written a Spring Boot service that utilizes these classes. Specifically, I am fetching the access\_token and refresh\_token from an OAuth2AuthorizedClient object. Can you please guide me on how I can retrieve the id\_token also which is sent by the authorization server in the response.  
This is the code I have currently:

```auto
public class CookieOAuth2AuthorizedClientRepository implements OAuth2AuthorizedClientRepository {
    ...

    @Override
    public void saveAuthorizedClient(OAuth2AuthorizedClient authorizedClient, Authentication principal,
                                     HttpServletRequest request, HttpServletResponse response) {

        OAuth2AccessToken accessToken = authorizedClient.getAccessToken();
        OAuth2RefreshToken refreshToken = authorizedClient.getRefreshToken();
        **// TODO: Get id_token from authorizedClient**

        // create some cookies and send in response
        response.addCookie(cookie1);
        response.addCookie(cookie2);
    }

    ...

}

```

---

<div class="post-metadata">

**Author:** ![bdemers](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/bdemers/32/23_2.png) [@bdemers](https://devforum.okta.com/u/bdemers)\
**Post date:** [March 2, 2022, 8:40pm UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/16 "2022-03-02T20:40:09Z")

</div>

Hey @sjimil!

The short answer is you cannot.

The OAuth client credentials flow is a mechanism for two services to talk to each other without a user  
[https://oauth.net/2/grant-types/client-credentials/](https://oauth.net/2/grant-types/client-credentials/)

Id Token are used by OpenID Connect client when authenticating a user  
[https://oauth.net/id-tokens-vs-access-tokens/](https://oauth.net/id-tokens-vs-access-tokens/)

No getting back to your application, it looks like you are trying to do something with cookies, which typically indicates a user and a browser (I’m guessing, as this is not always the case)?

If that is the case, you can check out this video:

[![](https://img.youtube.com/vi/dURkaz0kBSU/maxresdefault.jpg "Okta CLI + Spring Boot in 2 minutes") ](https://www.youtube.com/watch?v=dURkaz0kBSU)

and corresponding blog post:

> **[Spring Boot and Okta in 2 Minutes](https://developer.okta.com/blog/2020/11/24/spring-boot-okta)**
>
> This 2-minute video shows you how to use the Okta CLI to secure your Spring Boot app in seconds.

After that, you should be able to inject a `@AuthenticationPrincipal OidcUser principal` into your Controller.

If my guess was wrong let me know!

---

<div class="post-metadata">

**Author:** ![sjimil](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/sjimil/32/3729_2.png) [@sjimil](https://devforum.okta.com/u/sjimil)\
**Post date:** [March 3, 2022, 10:10am UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/17 "2022-03-03T10:10:37Z")

</div>

Hi @bdemers ,  
That’s correct. There’s a user and a browser involved.

The browser initiates a call to the Spring Boot service that implements the entire client credentials flow and returns the authenticated user JWT and refresh token along with some other details.

Single Sign-On is working perfectly and now, I want to implement a sort of Single Logout. There’s a logout endpoint that the IDM is providing and it requires that id\_token as a compulsory parameter.  
If I try injecting `@AuthenticationPrincipal OidcUser user` in my controller, I keep getting a `NullPointerException`.

This is my controller signature:

```auto
// does not work, user is null
@GetMapping("/api/access-token")
public ResponseEntity<?> validateJwt(JwtAuthenticationToken authentication, @AuthenticationPrincipal OidcUser user) { ... }

```

where, JwtAuthenticationToken is an entity class defined like so:

```auto
public class JwtAuthenticationToken extends AbstractOAuth2TokenAuthenticationToken<Jwt> {

    public static final String EML_CLAIM = "eml";

    public JwtAuthenticationToken(Jwt jwt, @Nullable Collection<? extends GrantedAuthority> authorities) {
        super(jwt, authorities);
        this.setAuthenticated(true);
    }

    @Override
    public Map<String, Object> getTokenAttributes() {
        return this.getToken().getClaims();
    }

    public String getUserName() {
        return this.getToken().getClaimAsString(EML_CLAIM);
    }
}

```

Is there any way I can send the id\_token to the UI so that it can utilize it when logout is initiated on the browser?

---

<div class="post-metadata">

**Author:** ![bdemers](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/bdemers/32/23_2.png) [@bdemers](https://devforum.okta.com/u/bdemers)\
**Post date:** [March 3, 2022, 3:05pm UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/18 "2022-03-03T15:05:15Z")

</div>

Hi @sjimil!

I think you may be misinterpreting the various OAuth-related flows.  
Basically, if you have a browser (a user) you are NOT using a client credentials flow. You would use an Authorization Code Grant [Authorization Code Grant - OAuth 2.0 Simplified](https://www.oauth.com/oauth2-servers/server-side-apps/authorization-code/)  
(This is the redirect to an IdP, and then back to your application)

For a Spring Boot application, this is configured for you automatically when you include the correct dependencies and configuration properties.

Also, you should NOT send the Id Token from one service to another service, it should only be used by the service that initiated the login.

Lets take a step back, can you describe the type of application you are building (front end and backend), and I’ll try to point you to some resources that would be a good fit.

---

<div class="post-metadata">

**Author:** ![sjimil](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/sjimil/32/3729_2.png) [@sjimil](https://devforum.okta.com/u/sjimil)\
**Post date:** [March 4, 2022, 5:10am UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/19 "2022-03-04T05:10:00Z")

</div>

Hi @bdemers ,  
My apologies for the confusion. I’m new to this technology and could’ve misplaced the terms.  
Taking a step back, I have a web application, where the front-end is built in React and the backend is in Spring Boot. I want users to be able to access the front-end portal after they have successfully authenticated themselves to my IdP via Single Sign-On (SSO).

We have an OAuthApplication service that does the authentication. We are using the OAuth2.0 Authorization Grant flow. I configure my AuthServlet in this application like below:

```auto
@Bean
public ClientRegistrationRepository clientRegistration(SSOProperties ssoProperties) {
        ClientRegistration clientRegistration = ClientRegistration.withRegistrationId(WebConstants.OAUTH_PROVIDER_ID)
                .clientId(ssoProperties.getClientId())
                .clientSecret(ssoProperties.getClientSecret())
                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                .redirectUri(ssoProperties.getApplicationUrl() + "/api/core/authn")
                .authorizationUri(ssoProperties.getUrl() + "/SAAS/auth/oauth2/authorize")
                .tokenUri(ssoProperties.getUrl() + "/SAAS/auth/oauthtoken")
                .userInfoUri(ssoProperties.getUrl() + "/SAAS/jersey/manager/api/userinfo")
                .userNameAttributeName("sub")
                .build();
        return new InMemoryClientRegistrationRepository(clientRegistration);
    }

```

Reading my IdP’s documentation for the /SAAS/auth/oauthtoken endpoint, the response has the following JSON format:

```auto
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9....",
"token_type": "Bearer",
"expires_in": 21599,
"refresh_token": "MBVaM...",
"scope": "openid user email",
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...."
}

```

What I’m trying to achieve here is I’m trying to get the id\_token somewhere from this JSON response and send it back to the UI. Is it recommended to do so? If this is not recommended, can you please also let me know how Single Logout is handled in OAuth2.0 applications otherwise?

Thank you for your time.

---

<div class="post-metadata">

**Author:** ![mraible](https://sea1.discourse-cdn.com/oktadev/user_avatar/devforum.okta.com/mraible/32/37_2.png) [@mraible](https://devforum.okta.com/u/mraible)\
**Post date:** [March 4, 2022, 2:12pm UTC](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370/20 "2022-03-04T14:12:03Z")

</div>

I don’t know if this will help, but here’s how we do it in JHipster:

```java
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.HttpHeaders;
import java.util.Map;

/**
 * REST controller for managing global OIDC logout.
 */
@RestController
public class LogoutResource {
    private final ClientRegistration registration;

    public LogoutResource(ClientRegistrationRepository registrations) {
        this.registration = registrations.findByRegistrationId("oidc");
    }

    /**
     * {@code POST /api/logout} : logout the current user.
     *
     * @param request the {@link HttpServletRequest}.
     * @param idToken the ID token.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and a body with a global logout URL.
     */
    @PostMapping("/api/logout")
    public ResponseEntity<?> logout(HttpServletRequest request,
                                    @AuthenticationPrincipal(expression = "idToken") OidcIdToken idToken) {
        StringBuilder logoutUrl = new StringBuilder();

        String issuerUri = this.registration.getProviderDetails().getIssuerUri();
        if (issuerUri.contains("auth0.com")) {
            logoutUrl.append(issuerUri.endsWith("/") ? issuerUri + "v2/logout" : issuerUri + "/v2/logout");
        } else {
            logoutUrl.append(this.registration.getProviderDetails().getConfigurationMetadata().get("end_session_endpoint").toString());
        }

        String originUrl = request.getHeader(HttpHeaders.ORIGIN);

        if (logoutUrl.indexOf("/protocol") > -1) {
            logoutUrl.append("?redirect_uri=").append(originUrl);
        } else if (logoutUrl.indexOf("auth0.com") > -1) {
            // Auth0
            logoutUrl.append("?client_id=").append(this.registration.getClientId()).append("&returnTo=").append(originUrl);
        } else {
            // Okta
            logoutUrl.append("?id_token_hint=").append(idToken.getTokenValue()).append("&post_logout_redirect_uri=").append(originUrl);
        }

        request.getSession().invalidate();
        return ResponseEntity.ok().body(Map.of("logoutUrl", logoutUrl.toString()));
    }

}

```

You might need to change `oidc` to `WebConstants.OAUTH_PROVIDER_ID` in the constructor for this to work.

[Next page](https://devforum.okta.com/t/how-to-use-client-credentials-flow-with-spring-security/17370.md?page=2)
