Skip to content

Commit bf067d6

Browse files
committed
Add Logging to Resource Server
Closes gh-9000
1 parent 593a556 commit bf067d6

File tree

7 files changed

+61
-5
lines changed

7 files changed

+61
-5
lines changed

oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/NimbusJwtDecoder.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
5252
import com.nimbusds.jwt.proc.DefaultJWTProcessor;
5353
import com.nimbusds.jwt.proc.JWTProcessor;
54+
import org.apache.commons.logging.Log;
55+
import org.apache.commons.logging.LogFactory;
5456

5557
import org.springframework.cache.Cache;
5658
import org.springframework.core.convert.converter.Converter;
@@ -80,6 +82,8 @@
8082
*/
8183
public final class NimbusJwtDecoder implements JwtDecoder {
8284

85+
private final Log logger = LogFactory.getLog(getClass());
86+
8387
private static final String DECODING_ERROR_MESSAGE_TEMPLATE = "An error occurred while attempting to decode the Jwt: %s";
8488

8589
private final JWTProcessor<SecurityContext> jwtProcessor;
@@ -126,6 +130,7 @@ public void setClaimSetConverter(Converter<Map<String, Object>, Map<String, Obje
126130
public Jwt decode(String token) throws JwtException {
127131
JWT jwt = parse(token);
128132
if (jwt instanceof PlainJWT) {
133+
this.logger.trace("Failed to decode unsigned token");
129134
throw new BadJwtException("Unsupported algorithm of " + jwt.getHeader().getAlgorithm());
130135
}
131136
Jwt createdJwt = createJwt(token, jwt);
@@ -137,6 +142,7 @@ private JWT parse(String token) {
137142
return JWTParser.parse(token);
138143
}
139144
catch (Exception ex) {
145+
this.logger.trace("Failed to parse token", ex);
140146
throw new BadJwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex);
141147
}
142148
}
@@ -155,15 +161,18 @@ private Jwt createJwt(String token, JWT parsedJwt) {
155161
// @formatter:on
156162
}
157163
catch (RemoteKeySourceException ex) {
164+
this.logger.trace("Failed to retrieve JWK set", ex);
158165
if (ex.getCause() instanceof ParseException) {
159166
throw new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, "Malformed Jwk set"));
160167
}
161168
throw new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex);
162169
}
163170
catch (JOSEException ex) {
171+
this.logger.trace("Failed to process JWT", ex);
164172
throw new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex);
165173
}
166174
catch (Exception ex) {
175+
this.logger.trace("Failed to process JWT", ex);
167176
if (ex.getCause() instanceof ParseException) {
168177
throw new BadJwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, "Malformed payload"));
169178
}

oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationProvider.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818

1919
import java.util.Collection;
2020

21+
import org.apache.commons.logging.Log;
22+
import org.apache.commons.logging.LogFactory;
23+
2124
import org.springframework.core.convert.converter.Converter;
2225
import org.springframework.security.authentication.AbstractAuthenticationToken;
2326
import org.springframework.security.authentication.AuthenticationProvider;
@@ -60,6 +63,8 @@
6063
*/
6164
public final class JwtAuthenticationProvider implements AuthenticationProvider {
6265

66+
private final Log logger = LogFactory.getLog(getClass());
67+
6368
private final JwtDecoder jwtDecoder;
6469

6570
private Converter<Jwt, ? extends AbstractAuthenticationToken> jwtAuthenticationConverter = new JwtAuthenticationConverter();
@@ -83,6 +88,7 @@ public Authentication authenticate(Authentication authentication) throws Authent
8388
Jwt jwt = getJwt(bearer);
8489
AbstractAuthenticationToken token = this.jwtAuthenticationConverter.convert(jwt);
8590
token.setDetails(bearer.getDetails());
91+
this.logger.debug("Authenticated token");
8692
return token;
8793
}
8894

@@ -91,6 +97,7 @@ private Jwt getJwt(BearerTokenAuthenticationToken bearer) {
9197
return this.jwtDecoder.decode(bearer.getToken());
9298
}
9399
catch (BadJwtException failed) {
100+
this.logger.debug("Failed to authenticate since the JWT was invalid");
94101
throw new InvalidBearerTokenException(failed.getMessage(), failed);
95102
}
96103
catch (JwtException failed) {

oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtGrantedAuthoritiesConverter.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@
2121
import java.util.Collection;
2222
import java.util.Collections;
2323

24+
import org.apache.commons.logging.Log;
25+
import org.apache.commons.logging.LogFactory;
26+
2427
import org.springframework.core.convert.converter.Converter;
28+
import org.springframework.core.log.LogMessage;
2529
import org.springframework.security.core.GrantedAuthority;
2630
import org.springframework.security.core.authority.SimpleGrantedAuthority;
2731
import org.springframework.security.oauth2.jwt.Jwt;
@@ -37,6 +41,8 @@
3741
*/
3842
public final class JwtGrantedAuthoritiesConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
3943

44+
private final Log logger = LogFactory.getLog(getClass());
45+
4046
private static final String DEFAULT_AUTHORITY_PREFIX = "SCOPE_";
4147

4248
private static final Collection<String> WELL_KNOWN_AUTHORITIES_CLAIM_NAMES = Arrays.asList("scope", "scp");
@@ -98,8 +104,12 @@ private String getAuthoritiesClaimName(Jwt jwt) {
98104
private Collection<String> getAuthorities(Jwt jwt) {
99105
String claimName = getAuthoritiesClaimName(jwt);
100106
if (claimName == null) {
107+
this.logger.trace("Returning no authorities since could not find any claims that might contain scopes");
101108
return Collections.emptyList();
102109
}
110+
if (this.logger.isTraceEnabled()) {
111+
this.logger.trace(LogMessage.format("Looking for scopes in claim %s", claimName));
112+
}
103113
Object authorities = jwt.getClaim(claimName);
104114
if (authorities instanceof String) {
105115
if (StringUtils.hasText((String) authorities)) {

oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerAuthenticationManagerResolver.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@
2626
import javax.servlet.http.HttpServletRequest;
2727

2828
import com.nimbusds.jwt.JWTParser;
29+
import org.apache.commons.logging.Log;
30+
import org.apache.commons.logging.LogFactory;
2931

3032
import org.springframework.core.convert.converter.Converter;
33+
import org.springframework.core.log.LogMessage;
3134
import org.springframework.lang.NonNull;
3235
import org.springframework.security.authentication.AuthenticationManager;
3336
import org.springframework.security.authentication.AuthenticationManagerResolver;
@@ -151,6 +154,8 @@ public String convert(@NonNull HttpServletRequest request) {
151154
private static class TrustedIssuerJwtAuthenticationManagerResolver
152155
implements AuthenticationManagerResolver<String> {
153156

157+
private final Log logger = LogFactory.getLog(getClass());
158+
154159
private final Map<String, AuthenticationManager> authenticationManagers = new ConcurrentHashMap<>();
155160

156161
private final Predicate<String> trustedIssuer;
@@ -162,10 +167,17 @@ private static class TrustedIssuerJwtAuthenticationManagerResolver
162167
@Override
163168
public AuthenticationManager resolve(String issuer) {
164169
if (this.trustedIssuer.test(issuer)) {
165-
return this.authenticationManagers.computeIfAbsent(issuer, (k) -> {
166-
JwtDecoder jwtDecoder = JwtDecoders.fromIssuerLocation(issuer);
167-
return new JwtAuthenticationProvider(jwtDecoder)::authenticate;
168-
});
170+
AuthenticationManager authenticationManager = this.authenticationManagers.computeIfAbsent(issuer,
171+
(k) -> {
172+
this.logger.debug("Constructing AuthenticationManager");
173+
JwtDecoder jwtDecoder = JwtDecoders.fromIssuerLocation(issuer);
174+
return new JwtAuthenticationProvider(jwtDecoder)::authenticate;
175+
});
176+
this.logger.debug(LogMessage.format("Resolved AuthenticationManager for issuer '%s'", issuer));
177+
return authenticationManager;
178+
}
179+
else {
180+
this.logger.debug("Did not resolve AuthenticationManager since issuer is not trusted");
169181
}
170182
return null;
171183
}

oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProvider.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
import java.time.Instant;
2020
import java.util.Collection;
2121

22+
import org.apache.commons.logging.Log;
23+
import org.apache.commons.logging.LogFactory;
24+
2225
import org.springframework.security.authentication.AbstractAuthenticationToken;
2326
import org.springframework.security.authentication.AuthenticationProvider;
2427
import org.springframework.security.authentication.AuthenticationServiceException;
@@ -61,6 +64,8 @@
6164
*/
6265
public final class OpaqueTokenAuthenticationProvider implements AuthenticationProvider {
6366

67+
private final Log logger = LogFactory.getLog(getClass());
68+
6469
private OpaqueTokenIntrospector introspector;
6570

6671
/**
@@ -89,6 +94,7 @@ public Authentication authenticate(Authentication authentication) throws Authent
8994
OAuth2AuthenticatedPrincipal principal = getOAuth2AuthenticatedPrincipal(bearer);
9095
AbstractAuthenticationToken result = convert(principal, bearer.getToken());
9196
result.setDetails(bearer.getDetails());
97+
this.logger.debug("Authenticated token");
9298
return result;
9399
}
94100

@@ -97,6 +103,7 @@ private OAuth2AuthenticatedPrincipal getOAuth2AuthenticatedPrincipal(BearerToken
97103
return this.introspector.introspect(bearer.getToken());
98104
}
99105
catch (BadOpaqueTokenException failed) {
106+
this.logger.debug("Failed to authenticate since token was invalid");
100107
throw new InvalidBearerTokenException(failed.getMessage());
101108
}
102109
catch (OAuth2IntrospectionException failed) {

oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/NimbusOpaqueTokenIntrospector.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import com.nimbusds.oauth2.sdk.TokenIntrospectionSuccessResponse;
3030
import com.nimbusds.oauth2.sdk.http.HTTPResponse;
3131
import com.nimbusds.oauth2.sdk.id.Audience;
32+
import org.apache.commons.logging.Log;
33+
import org.apache.commons.logging.LogFactory;
3234

3335
import org.springframework.core.convert.converter.Converter;
3436
import org.springframework.http.HttpHeaders;
@@ -58,6 +60,8 @@
5860
*/
5961
public class NimbusOpaqueTokenIntrospector implements OpaqueTokenIntrospector {
6062

63+
private final Log logger = LogFactory.getLog(getClass());
64+
6165
private Converter<String, RequestEntity<?>> requestEntityConverter;
6266

6367
private RestOperations restOperations;
@@ -128,6 +132,7 @@ public OAuth2AuthenticatedPrincipal introspect(String token) {
128132
// relying solely on the authorization server to validate this token (not checking
129133
// 'exp', for example)
130134
if (!introspectionSuccessResponse.isActive()) {
135+
this.logger.trace("Did not validate token since it is inactive");
131136
throw new BadOpaqueTokenException("Provided token isn't active");
132137
}
133138
return convertClaimsSet(introspectionSuccessResponse);

oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/BearerTokenAuthenticationFilter.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import javax.servlet.http.HttpServletRequest;
2424
import javax.servlet.http.HttpServletResponse;
2525

26+
import org.springframework.core.log.LogMessage;
2627
import org.springframework.security.authentication.AuthenticationDetailsSource;
2728
import org.springframework.security.authentication.AuthenticationManager;
2829
import org.springframework.security.authentication.AuthenticationManagerResolver;
@@ -105,10 +106,12 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
105106
token = this.bearerTokenResolver.resolve(request);
106107
}
107108
catch (OAuth2AuthenticationException invalid) {
109+
this.logger.trace("Sending to authentication entry point since failed to resolve bearer token", invalid);
108110
this.authenticationEntryPoint.commence(request, response, invalid);
109111
return;
110112
}
111113
if (token == null) {
114+
this.logger.trace("Did not process request since did not find bearer token");
112115
filterChain.doFilter(request, response);
113116
return;
114117
}
@@ -120,11 +123,14 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
120123
SecurityContext context = SecurityContextHolder.createEmptyContext();
121124
context.setAuthentication(authenticationResult);
122125
SecurityContextHolder.setContext(context);
126+
if (this.logger.isDebugEnabled()) {
127+
this.logger.debug(LogMessage.format("Set SecurityContextHolder to %s", authenticationResult));
128+
}
123129
filterChain.doFilter(request, response);
124130
}
125131
catch (AuthenticationException failed) {
126132
SecurityContextHolder.clearContext();
127-
this.logger.debug("Authentication request for failed!", failed);
133+
this.logger.trace("Failed to process authentication request", failed);
128134
this.authenticationFailureHandler.onAuthenticationFailure(request, response, failed);
129135
}
130136
}

0 commit comments

Comments
 (0)