1+ package org .baeldung .config ;
2+
3+ import java .util .Collections ;
4+ import java .util .List ;
5+
6+ import org .springframework .security .access .AccessDeniedException ;
7+ import org .springframework .security .authentication .AnonymousAuthenticationToken ;
8+ import org .springframework .security .authentication .InsufficientAuthenticationException ;
9+ import org .springframework .security .core .Authentication ;
10+ import org .springframework .security .core .context .SecurityContextHolder ;
11+ import org .springframework .security .oauth2 .client .resource .OAuth2AccessDeniedException ;
12+ import org .springframework .security .oauth2 .client .resource .OAuth2ProtectedResourceDetails ;
13+ import org .springframework .security .oauth2 .client .resource .UserRedirectRequiredException ;
14+ import org .springframework .security .oauth2 .client .token .AccessTokenProvider ;
15+ import org .springframework .security .oauth2 .client .token .AccessTokenRequest ;
16+ import org .springframework .security .oauth2 .client .token .ClientTokenServices ;
17+ import org .springframework .security .oauth2 .client .token .OAuth2AccessTokenSupport ;
18+ import org .springframework .security .oauth2 .common .OAuth2AccessToken ;
19+ import org .springframework .security .oauth2 .common .OAuth2RefreshToken ;
20+ import org .springframework .security .oauth2 .common .exceptions .OAuth2Exception ;
21+
22+ public class MyAccessTokenProviderChain extends OAuth2AccessTokenSupport implements AccessTokenProvider {
23+
24+ private final List <AccessTokenProvider > chain ;
25+
26+ private ClientTokenServices clientTokenServices ;
27+
28+ public MyAccessTokenProviderChain (List <? extends AccessTokenProvider > chain ) {
29+ this .chain = chain == null ? Collections .<AccessTokenProvider > emptyList () : Collections .unmodifiableList (chain );
30+ }
31+
32+ public void setClientTokenServices (ClientTokenServices clientTokenServices ) {
33+ this .clientTokenServices = clientTokenServices ;
34+ }
35+
36+ public boolean supportsResource (OAuth2ProtectedResourceDetails resource ) {
37+ for (AccessTokenProvider tokenProvider : chain ) {
38+ if (tokenProvider .supportsResource (resource )) {
39+ return true ;
40+ }
41+ }
42+ return false ;
43+ }
44+
45+ public boolean supportsRefresh (OAuth2ProtectedResourceDetails resource ) {
46+ for (AccessTokenProvider tokenProvider : chain ) {
47+ if (tokenProvider .supportsRefresh (resource )) {
48+ return true ;
49+ }
50+ }
51+ return false ;
52+ }
53+
54+ public OAuth2AccessToken obtainAccessToken (OAuth2ProtectedResourceDetails resource , AccessTokenRequest request ) throws UserRedirectRequiredException , AccessDeniedException {
55+ System .out .println ("Obtain new token=====" );
56+ OAuth2AccessToken accessToken = null ;
57+ OAuth2AccessToken existingToken = null ;
58+ Authentication auth = SecurityContextHolder .getContext ().getAuthentication ();
59+ System .out .println ("The authentication is ---- " + auth );
60+ if (auth instanceof AnonymousAuthenticationToken ) {
61+ if (!resource .isClientOnly ()) {
62+ throw new InsufficientAuthenticationException ("Authentication is required to obtain an access token (anonymous not allowed)" );
63+ }
64+ }
65+
66+ if (resource .isClientOnly () || (auth != null && auth .isAuthenticated ())) {
67+ existingToken = request .getExistingToken ();
68+ System .out .println ("checking existing token =====" );
69+ if (existingToken == null && clientTokenServices != null ) {
70+ System .out .println ("get existing token from clientTokenServices ==== " );
71+ existingToken = clientTokenServices .getAccessToken (resource , auth );
72+ }
73+
74+ if (existingToken != null ) {
75+ if (existingToken .isExpired ()) {
76+ System .out .println ("expired token" );
77+ if (clientTokenServices != null ) {
78+ clientTokenServices .removeAccessToken (resource , auth );
79+ }
80+ OAuth2RefreshToken refreshToken = existingToken .getRefreshToken ();
81+ if (refreshToken != null ) {
82+ System .out .println ("let's refresh it" );
83+ accessToken = refreshAccessToken (resource , refreshToken , request );
84+ }
85+ } else {
86+ System .out .println ("use existing because not expired yet" );
87+ accessToken = existingToken ;
88+ }
89+ }
90+ }
91+
92+ if (accessToken == null ) {
93+ System .out .println ("no token so let get it" );
94+ accessToken = obtainNewAccessTokenInternal (resource , request );
95+
96+ if (accessToken == null ) {
97+ throw new IllegalStateException ("An OAuth 2 access token must be obtained or an exception thrown." );
98+ }
99+ }
100+
101+ if (clientTokenServices != null && auth != null && auth .isAuthenticated ()) {
102+ clientTokenServices .saveAccessToken (resource , auth , accessToken );
103+ }
104+
105+ return accessToken ;
106+ }
107+
108+ protected OAuth2AccessToken obtainNewAccessTokenInternal (OAuth2ProtectedResourceDetails details , AccessTokenRequest request ) throws UserRedirectRequiredException , AccessDeniedException {
109+
110+ if (request .isError ()) {
111+ throw OAuth2Exception .valueOf (request .toSingleValueMap ());
112+ }
113+
114+ for (AccessTokenProvider tokenProvider : chain ) {
115+ if (tokenProvider .supportsResource (details )) {
116+ System .out .println ("we will use this provider to get it => " + tokenProvider .getClass ().getName ());
117+ return tokenProvider .obtainAccessToken (details , request );
118+ }
119+ }
120+
121+ throw new OAuth2AccessDeniedException ("Unable to obtain a new access token for resource '" + details .getId () + "'. The provider manager is not configured to support it." , details );
122+ }
123+
124+ public OAuth2AccessToken refreshAccessToken (OAuth2ProtectedResourceDetails resource , OAuth2RefreshToken refreshToken , AccessTokenRequest request ) throws UserRedirectRequiredException {
125+ for (AccessTokenProvider tokenProvider : chain ) {
126+ if (tokenProvider .supportsRefresh (resource )) {
127+ System .out .println ("we will use this provider to refresh it => " + tokenProvider .getClass ().getName ());
128+ return tokenProvider .refreshAccessToken (resource , refreshToken , request );
129+ }
130+ }
131+ throw new OAuth2AccessDeniedException ("Unable to obtain a new access token for resource '" + resource .getId () + "'. The provider manager is not configured to support it." , resource );
132+ }
133+
134+ }
0 commit comments