|  | @@ -0,0 +1,108 @@
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * Copyright 2002-2018 the original author or authors.
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Licensed under the Apache License, Version 2.0 (the "License");
 | 
	
		
			
				|  |  | + * you may not use this file except in compliance with the License.
 | 
	
		
			
				|  |  | + * You may obtain a copy of the License at
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + *      https://www.apache.org/licenses/LICENSE-2.0
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Unless required by applicable law or agreed to in writing, software
 | 
	
		
			
				|  |  | + * distributed under the License is distributed on an "AS IS" BASIS,
 | 
	
		
			
				|  |  | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
	
		
			
				|  |  | + * See the License for the specific language governing permissions and
 | 
	
		
			
				|  |  | + * limitations under the License.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +package sample;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import java.net.URL;
 | 
	
		
			
				|  |  | +import java.security.interfaces.RSAPrivateCrtKey;
 | 
	
		
			
				|  |  | +import java.security.interfaces.RSAPrivateKey;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import com.nimbusds.jose.EncryptionMethod;
 | 
	
		
			
				|  |  | +import com.nimbusds.jose.JWEAlgorithm;
 | 
	
		
			
				|  |  | +import com.nimbusds.jose.JWSAlgorithm;
 | 
	
		
			
				|  |  | +import com.nimbusds.jose.jwk.JWKSet;
 | 
	
		
			
				|  |  | +import com.nimbusds.jose.jwk.KeyUse;
 | 
	
		
			
				|  |  | +import com.nimbusds.jose.jwk.RSAKey;
 | 
	
		
			
				|  |  | +import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
 | 
	
		
			
				|  |  | +import com.nimbusds.jose.jwk.source.JWKSource;
 | 
	
		
			
				|  |  | +import com.nimbusds.jose.jwk.source.RemoteJWKSet;
 | 
	
		
			
				|  |  | +import com.nimbusds.jose.proc.JWEDecryptionKeySelector;
 | 
	
		
			
				|  |  | +import com.nimbusds.jose.proc.JWEKeySelector;
 | 
	
		
			
				|  |  | +import com.nimbusds.jose.proc.JWSKeySelector;
 | 
	
		
			
				|  |  | +import com.nimbusds.jose.proc.JWSVerificationKeySelector;
 | 
	
		
			
				|  |  | +import com.nimbusds.jose.proc.SecurityContext;
 | 
	
		
			
				|  |  | +import com.nimbusds.jose.util.Base64URL;
 | 
	
		
			
				|  |  | +import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
 | 
	
		
			
				|  |  | +import com.nimbusds.jwt.proc.DefaultJWTProcessor;
 | 
	
		
			
				|  |  | +import com.nimbusds.jwt.proc.JWTProcessor;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import org.springframework.beans.factory.annotation.Value;
 | 
	
		
			
				|  |  | +import org.springframework.context.annotation.Bean;
 | 
	
		
			
				|  |  | +import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 | 
	
		
			
				|  |  | +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 | 
	
		
			
				|  |  | +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 | 
	
		
			
				|  |  | +import org.springframework.security.oauth2.jwt.JwtDecoder;
 | 
	
		
			
				|  |  | +import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * @author Josh Cummings
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +@EnableWebSecurity
 | 
	
		
			
				|  |  | +public class OAuth2ResourceServerSecurityConfiguration extends WebSecurityConfigurerAdapter {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	private final JWSAlgorithm jwsAlgorithm = JWSAlgorithm.RS256;
 | 
	
		
			
				|  |  | +	private final JWEAlgorithm jweAlgorithm = JWEAlgorithm.RSA_OAEP_256;
 | 
	
		
			
				|  |  | +	private final EncryptionMethod encryptionMethod = EncryptionMethod.A256GCM;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	@Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}")
 | 
	
		
			
				|  |  | +	URL jwkSetUri;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	@Value("${sample.jwe-key-value}")
 | 
	
		
			
				|  |  | +	RSAPrivateKey key;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	@Override
 | 
	
		
			
				|  |  | +	protected void configure(HttpSecurity http) throws Exception {
 | 
	
		
			
				|  |  | +		// @formatter:off
 | 
	
		
			
				|  |  | +		http
 | 
	
		
			
				|  |  | +			.authorizeRequests()
 | 
	
		
			
				|  |  | +				.antMatchers("/message/**").hasAuthority("SCOPE_message:read")
 | 
	
		
			
				|  |  | +				.anyRequest().authenticated()
 | 
	
		
			
				|  |  | +				.and()
 | 
	
		
			
				|  |  | +			.oauth2ResourceServer()
 | 
	
		
			
				|  |  | +				.jwt();
 | 
	
		
			
				|  |  | +		// @formatter:on
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	@Bean
 | 
	
		
			
				|  |  | +	JwtDecoder jwtDecoder() {
 | 
	
		
			
				|  |  | +		return new NimbusJwtDecoder(jwtProcessor());
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	private JWTProcessor<SecurityContext> jwtProcessor() {
 | 
	
		
			
				|  |  | +		JWKSource<SecurityContext> jwsJwkSource = new RemoteJWKSet<>(this.jwkSetUri);
 | 
	
		
			
				|  |  | +		JWSKeySelector<SecurityContext> jwsKeySelector =
 | 
	
		
			
				|  |  | +				new JWSVerificationKeySelector<>(this.jwsAlgorithm, jwsJwkSource);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		JWKSource<SecurityContext> jweJwkSource = new ImmutableJWKSet<>(new JWKSet(rsaKey()));
 | 
	
		
			
				|  |  | +		JWEKeySelector<SecurityContext> jweKeySelector =
 | 
	
		
			
				|  |  | +				new JWEDecryptionKeySelector<>(this.jweAlgorithm, this.encryptionMethod, jweJwkSource);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		ConfigurableJWTProcessor<SecurityContext> jwtProcessor = new DefaultJWTProcessor<>();
 | 
	
		
			
				|  |  | +		jwtProcessor.setJWSKeySelector(jwsKeySelector);
 | 
	
		
			
				|  |  | +		jwtProcessor.setJWEKeySelector(jweKeySelector);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		return jwtProcessor;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	private RSAKey rsaKey() {
 | 
	
		
			
				|  |  | +		RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey) this.key;
 | 
	
		
			
				|  |  | +		Base64URL n = Base64URL.encode(crtKey.getModulus());
 | 
	
		
			
				|  |  | +		Base64URL e = Base64URL.encode(crtKey.getPublicExponent());
 | 
	
		
			
				|  |  | +		return new RSAKey.Builder(n, e)
 | 
	
		
			
				|  |  | +				.privateKey(this.key)
 | 
	
		
			
				|  |  | +				.keyUse(KeyUse.ENCRYPTION)
 | 
	
		
			
				|  |  | +				.build();
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +}
 |