@Test public void testFilterNoToken() throws Exception { try { System.setProperty(OAuthFilter.CONFIG_AUTH_OAUTH_SHARED_SECRET, "y7MCBmoOx7TH70q1fabSGLzOrEYx+liUmLWPkwIPUTfWMXn/J5MDZuepBd8mcRObUDYYQN3MIS8p40ZT5EhvWw=="); when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("Bearer"); final OAuthFilter filter = new OAuthFilter(); filter.filter(mockContext); verify(mockContext, never()).setSecurityContext(any()); } finally { System.clearProperty(OAuthFilter.CONFIG_AUTH_OAUTH_SHARED_SECRET); } }
@Override public void filter(final ContainerRequestContext requestContext) throws IOException { final boolean secure = ofNullable(requestContext.getSecurityContext()).filter(SecurityContext::isSecure) .isPresent(); getOAuthToken(requestContext) .map(token -> authenticate(token) .<RuntimeException>orElseThrow(() -> new NotAuthorizedException(challenge))) .ifPresent(principal -> requestContext .setSecurityContext(new OAuthSecurityContext(secure, principal))); }
/** * Create an OAuth filter. */ @Inject public OAuthFilter() { this(buildAuthenticator()); }
public static List<ContainerRequestFilter> getAuthFilters(final TrellisConfiguration config) { // Authentication final List<ContainerRequestFilter> filters = new ArrayList<>(); final AuthConfiguration auth = config.getAuth(); if (auth.getJwt().getEnabled()) { filters.add(new OAuthFilter(getJwtAuthenticator(auth.getJwt()))); } if (auth.getBasic().getEnabled() && nonNull(auth.getBasic().getUsersFile())) { filters.add(new BasicAuthFilter(auth.getBasic().getUsersFile())); } return filters; }
@Test public void testFilterGenericFederated() throws Exception { final String passphrase = "password"; try { final String keystorePath = OAuthUtilsTest.class.getResource("/keystore.jks").getPath(); System.setProperty(OAuthFilter.CONFIG_AUTH_OAUTH_KEYSTORE_PATH, keystorePath); System.setProperty(OAuthFilter.CONFIG_AUTH_OAUTH_KEYSTORE_CREDENTIALS, passphrase); System.setProperty(OAuthFilter.CONFIG_AUTH_OAUTH_KEYSTORE_IDS, "trellis,trellis-ec"); final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(getClass().getResourceAsStream("/keystore.jks"), passphrase.toCharArray()); final Key privateKey = ks.getKey("trellis", passphrase.toCharArray()); final String token = Jwts.builder().setHeaderParam(JwsHeader.KEY_ID, "trellis") .setSubject(WEBID2).signWith(privateKey, SignatureAlgorithm.RS256).compact(); when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("Bearer " + token); final OAuthFilter filter = new OAuthFilter(); filter.filter(mockContext); verify(mockContext).setSecurityContext(securityArgument.capture()); assertEquals(WEBID2, securityArgument.getValue().getUserPrincipal().getName(), "Unexpected agent IRI!"); } finally { System.clearProperty(OAuthFilter.CONFIG_AUTH_OAUTH_KEYSTORE_PATH); System.clearProperty(OAuthFilter.CONFIG_AUTH_OAUTH_KEYSTORE_CREDENTIALS); System.clearProperty(OAuthFilter.CONFIG_AUTH_OAUTH_KEYSTORE_IDS); } }
@Test public void testFilterInvalidAuth() throws Exception { final String key = "BdEaIIfv67jl8mRL+/vnuf3RzfVfpkxtel8icx2B8uSudOcwVXr7zpwj92UtKCOkVGi2FaE+O4q55P3p7UE7Eg=="; final String token = Jwts.builder().setSubject(WEBID1).signWith(hmacShaKeyFor(key.getBytes(UTF_8))).compact(); when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("Bearer " + token); final OAuthFilter filter = new OAuthFilter(new JwtAuthenticator(hmacShaKeyFor(key.replaceFirst("B", "A") .getBytes()))); assertThrows(NotAuthorizedException.class, () -> filter.filter(mockContext)); }
@Test public void testFilterNotBasicAuth() throws Exception { try { System.setProperty(OAuthFilter.CONFIG_AUTH_OAUTH_SHARED_SECRET, "y7MCBmoOx7TH70q1fabSGLzOrEYx+liUmLWPkwIPUTfWMXn/J5MDZuepBd8mcRObUDYYQN3MIS8p40ZT5EhvWw=="); final String token = Jwts.builder().claim("webid", WEBID1) .signWith(hmacShaKeyFor(getConfiguration() .get(OAuthFilter.CONFIG_AUTH_OAUTH_SHARED_SECRET).getBytes(UTF_8))).compact(); when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("Basic " + token); final OAuthFilter filter = new OAuthFilter(); filter.filter(mockContext); verify(mockContext, never()).setSecurityContext(any()); } finally { System.clearProperty(OAuthFilter.CONFIG_AUTH_OAUTH_SHARED_SECRET); } }
@Test public void testFilterGenericNoAuth() throws Exception { final Key key = secretKeyFor(SignatureAlgorithm.HS512); final String token = Jwts.builder().claim("webid", WEBID1).signWith(key).compact(); when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("Bearer " + token); final OAuthFilter filter = new OAuthFilter(); assertThrows(NotAuthorizedException.class, () -> filter.filter(mockContext)); }
@Test public void testFilterGenericWebid() throws Exception { try { System.setProperty(OAuthFilter.CONFIG_AUTH_OAUTH_SHARED_SECRET, "y7MCBmoOx7TH70q1fabSGLzOrEYx+liUmLWPkwIPUTfWMXn/J5MDZuepBd8mcRObUDYYQN3MIS8p40ZT5EhvWw=="); final String token = Jwts.builder().claim("webid", WEBID1).signWith(hmacShaKeyFor(getConfiguration() .get(OAuthFilter.CONFIG_AUTH_OAUTH_SHARED_SECRET).getBytes(UTF_8))).compact(); when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("Bearer " + token); final OAuthFilter filter = new OAuthFilter(); filter.filter(mockContext); verify(mockContext).setSecurityContext(securityArgument.capture()); assertAll("Validate security context", checkSecurityContext(securityArgument.getValue(), WEBID1)); } finally { System.clearProperty(OAuthFilter.CONFIG_AUTH_OAUTH_SHARED_SECRET); } }
@Test public void testFilterGenericJwks() throws Exception { final BigInteger exponent = new BigInteger(1, getUrlDecoder().decode("VRPRBm9dCoAJfBbEz5oAHEz7Tnm0i0O6m5yj7N" + "wqAZOj9i4ZwgZ8VZQo88oxZQWNaYd1yKeoQhUsJija_vxQEPXO1Q2q6OqMcwTBH0wyGhIFp--z2dAyRlDVLUTQbJUXyqammdh7b16-i" + "gH-BB67jfolM-cw-O7YaN7GrxCCYX5bI38IipeYfcroeIUXdLYmmUdNy7c8P2_K4O-iHQ6A4AUtQRUOzt2FGOdmlGZihupI9YprshIy" + "9CZq_iA3BcOl4Gcc-ljwwUzT0M_4jt53DCV7oxqWVt9WRdYDNoD62g2FzQ-1nYUqsz4YChk1MuOPV1xFpRklwSpt5dfhuldnbQ")); final BigInteger modulus = new BigInteger(1, getUrlDecoder().decode("oMyjaeUbmnqojRpMBDbWbfBFitd_dQcFJ96CDWw" + "zsVcyAK3_kp4dEvhc2KLBjrmE69gJ-4HRuPF-kulDEmpC-MVx9eOihdUG9XV0ZA_eYWj9RoI_Gt3TUqTxlQH_nJRADTfy82fOCCboKp" + "aQ2idZH55Vb0FDbau2b2462tYRmcnxTFjClP4fDTTubI-3oFJ4tKMjynvUT34mCrZPiM8Q4noxVoyRYpzUTL1USxdUf56IKSB8NduH4" + "38zhMXE5VLC6PzhR3i_4KKpe4nq2otsrJ3KlEc7Me6UeiMXxPYz8rrPovW5L3LFWDmntGs5q923fBZFLFg8yBgMdTineaahEQ")); try { System.setProperty(OAuthFilter.CONFIG_AUTH_OAUTH_JWK_URL, "https://www.trellisldp.org/tests/jwks.json"); final Key key = KeyFactory.getInstance("RSA").generatePrivate(new RSAPrivateKeySpec(modulus, exponent)); final String token = Jwts.builder().setHeaderParam(JwsHeader.KEY_ID, "trellis-test") .setSubject(WEBID2).signWith(key).compact(); when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("Bearer " + token); final OAuthFilter filter = new OAuthFilter(); filter.filter(mockContext); verify(mockContext).setSecurityContext(securityArgument.capture()); assertEquals(WEBID2, securityArgument.getValue().getUserPrincipal().getName(), "Unexpected agent IRI!"); } finally { System.clearProperty(OAuthFilter.CONFIG_AUTH_OAUTH_JWK_URL); } }
@Test public void testFilterGenericJwtSecret() throws Exception { try { System.setProperty(OAuthFilter.CONFIG_AUTH_OAUTH_SHARED_SECRET, "y7MCBmoOx7TH70q1fabSGLzOrEYx+liUmLWPkwIPUTfWMXn/J5MDZuepBd8mcRObUDYYQN3MIS8p40ZT5EhvWw=="); final String token = Jwts.builder().claim("webid", WEBID2).signWith(hmacShaKeyFor(getConfiguration() .get(OAuthFilter.CONFIG_AUTH_OAUTH_SHARED_SECRET).getBytes(UTF_8))).compact(); when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("BEARER " + token); final OAuthFilter filter = new OAuthFilter(); filter.filter(mockContext); verify(mockContext).setSecurityContext(securityArgument.capture()); assertAll("Validate security context", checkSecurityContext(securityArgument.getValue(), WEBID2)); } finally { System.clearProperty(OAuthFilter.CONFIG_AUTH_OAUTH_SHARED_SECRET); } }
@Test public void testFilterWebid() throws Exception { final Key key = secretKeyFor(SignatureAlgorithm.HS512); final String token = Jwts.builder().claim("webid", WEBID2).signWith(key).compact(); when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("Bearer " + token); final OAuthFilter filter = new OAuthFilter(new JwtAuthenticator(key)); filter.filter(mockContext); verify(mockContext).setSecurityContext(securityArgument.capture()); assertEquals(WEBID2, securityArgument.getValue().getUserPrincipal().getName(), "Unexpected agent IRI!"); assertEquals(OAuthFilter.SCHEME, securityArgument.getValue().getAuthenticationScheme(), "Unexpected scheme!"); assertFalse(securityArgument.getValue().isSecure(), "Unexpected secure flag!"); assertTrue(securityArgument.getValue().isUserInRole("some role"), "Not in user role!"); }
@Test public void testFilterExpiredJwt() throws Exception { final Key key = secretKeyFor(SignatureAlgorithm.HS512); final String token = Jwts.builder().claim("webid", WEBID1).setExpiration(from(now().minusSeconds(10))) .signWith(key).compact(); when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("Bearer " + token); final OAuthFilter filter = new OAuthFilter(new JwtAuthenticator(key)); assertThrows(NotAuthorizedException.class, () -> filter.filter(mockContext)); }
@Test public void testFilterAuth() throws Exception { final Key key = secretKeyFor(SignatureAlgorithm.HS512); final String token = Jwts.builder().setSubject(WEBID1).signWith(key).compact(); final ContainerRequestContext mockCtx = mock(ContainerRequestContext.class); when(mockCtx.getSecurityContext()).thenReturn(mockSecurityContext); when(mockCtx.getHeaderString(AUTHORIZATION)).thenReturn("Bearer " + token); final OAuthFilter filter = new OAuthFilter(new JwtAuthenticator(key)); filter.filter(mockCtx); verify(mockCtx).setSecurityContext(securityArgument.capture()); assertEquals(WEBID1, securityArgument.getValue().getUserPrincipal().getName(), "Unexpected agent IRI!"); assertEquals(OAuthFilter.SCHEME, securityArgument.getValue().getAuthenticationScheme(), "Unexpected scheme!"); assertFalse(securityArgument.getValue().isSecure(), "Unexpected secure flag!"); assertTrue(securityArgument.getValue().isUserInRole("some role"), "Not in user role!"); }