Skip to content
This repository was archived by the owner on Jan 20, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions code/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@
<groupId>com.networknt</groupId>
<artifactId>cors</artifactId>
</dependency>
<dependency>
<groupId>com.networknt</groupId>
<artifactId>resource</artifactId>
</dependency>
<dependency>
<groupId>com.networknt</groupId>
<artifactId>server</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@
import io.undertow.server.session.SessionCookieConfig;
import io.undertow.util.Methods;

/**
* Please don't use this in the service.yml but use handler.yml instead. Please check test/resources/config
* for more details. We will gradually update all the extenalized config files.
*
* @deprecated
*/
public class PathHandlerProvider implements HandlerProvider {
private static final String SPNEGO_SERVICE_PASSWORD = "spnegoServicePassword";
private static final String SECRET_CONFIG = "secret";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.networknt.oauth.code.handler;

import com.networknt.config.Config;
import com.networknt.oauth.security.LightBasicAuthenticationMechanism;
import com.networknt.oauth.security.LightGSSAPIAuthenticationMechanism;
import com.networknt.oauth.security.LightIdentityManager;
import io.undertow.security.api.AuthenticationMechanism;
import io.undertow.security.api.AuthenticationMode;
import io.undertow.security.api.GSSAPIServerSubjectFactory;
import io.undertow.security.handlers.AuthenticationCallHandler;
import io.undertow.security.handlers.AuthenticationConstraintHandler;
import io.undertow.security.handlers.AuthenticationMechanismsHandler;
import io.undertow.security.handlers.SecurityInitialHandler;
import io.undertow.security.idm.IdentityManager;
import io.undertow.security.impl.CachedAuthenticatedSessionMechanism;
import io.undertow.security.impl.FormAuthenticationMechanism;
import io.undertow.server.HttpHandler;
import io.undertow.server.session.InMemorySessionManager;
import io.undertow.server.session.SessionAttachmentHandler;
import io.undertow.server.session.SessionCookieConfig;

import javax.security.auth.Subject;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.networknt.oauth.spnego.KerberosKDCUtil.login;

public class BaseWrapper {

private static final String SPNEGO_SERVICE_PASSWORD = "spnegoServicePassword";
private static final String SECRET_CONFIG = "secret";
private static final String SERVER_CONFIG = "server";
private static final Map<String, Object> secret = Config.getInstance().getJsonMapConfig(SECRET_CONFIG);
private static final Map<String, Object> server = Config.getInstance().getJsonMapConfigNoCache(SERVER_CONFIG);
private static final String spnegoServicePassword = (String)secret.get(SPNEGO_SERVICE_PASSWORD);

final IdentityManager basicIdentityManager = new LightIdentityManager();

protected HttpHandler addGetSecurity(final HttpHandler toWrap, final IdentityManager identityManager) {
HttpHandler handler = toWrap;
handler = new AuthenticationCallHandler(handler);
handler = new AuthenticationConstraintHandler(handler);
List<AuthenticationMechanism> mechanisms = new ArrayList<>();
// bypass the SPNEGO if service password is not even configured.
if(spnegoServicePassword != null) {
mechanisms.add(new LightGSSAPIAuthenticationMechanism(new SubjectFactory()));
}
mechanisms.add(new LightBasicAuthenticationMechanism("OAuth"));
handler = new AuthenticationMechanismsHandler(handler, mechanisms);
handler = new SecurityInitialHandler(AuthenticationMode.PRO_ACTIVE, identityManager, handler);

return handler;
}

private class SubjectFactory implements GSSAPIServerSubjectFactory {
@Override
public Subject getSubjectForHost(String hostName) throws GeneralSecurityException {
return login("HTTP/" + hostName, spnegoServicePassword.toCharArray());
}
}

protected HttpHandler addFormSecurity(final HttpHandler toWrap, final IdentityManager identityManager) {
HttpHandler handler = toWrap;
handler = new AuthenticationCallHandler(handler);
handler = new AuthenticationConstraintHandler(handler);
final List<AuthenticationMechanism> mechanisms = new ArrayList<>();
mechanisms.add(new CachedAuthenticatedSessionMechanism());
mechanisms.add(new FormAuthenticationMechanism("oauth2", "/login", "/error", "/oauth2/code"));
handler = new AuthenticationMechanismsHandler(handler, mechanisms);
handler = new SecurityInitialHandler(AuthenticationMode.PRO_ACTIVE, identityManager, handler);
handler = new SessionAttachmentHandler(handler, new InMemorySessionManager("oauth2"), new SessionCookieConfig());

return handler;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.networknt.oauth.code.handler;

import com.networknt.handler.LightHttpHandler;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;

public class CodeGetHandlerWrapper extends BaseWrapper implements LightHttpHandler {

HttpHandler handler;

public CodeGetHandlerWrapper() {
handler = addGetSecurity(new Oauth2CodeGetHandler(), basicIdentityManager);
}

@Override
public void handleRequest(HttpServerExchange httpServerExchange) throws Exception {
handler.handleRequest(httpServerExchange);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.networknt.oauth.code.handler;

import com.networknt.handler.LightHttpHandler;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;

public class CodePostHandlerWrapper extends BaseWrapper implements LightHttpHandler {
HttpHandler handler;

public CodePostHandlerWrapper() {
handler = addFormSecurity(new Oauth2CodePostHandler(), basicIdentityManager);
}

@Override
public void handleRequest(HttpServerExchange httpServerExchange) throws Exception {
handler.handleRequest(httpServerExchange);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ public void run() {
latch.await(10, TimeUnit.SECONDS);
int statusCode = reference.get().getResponseCode();
String body = reference.get().getAttachment(Http2Client.RESPONSE_BODY);
System.out.println("statusCode = " + statusCode);
System.out.println("body = " + body);

//Assert.assertEquals(statusCode, 302);
// at this moment, an exception will help as it is redirected to localhost:8080 and it is not up.
} catch (Exception e) {
Expand Down
95 changes: 95 additions & 0 deletions code/src/test/resources/config/handler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Handler middleware chain configuration
---
enabled: true

#------------------------------------------------------------------------------
# Support individual handler chains for each separate endpoint. It allows framework
# handlers like health check, server info to bypass majority of the middleware handlers
# and allows mixing multiple frameworks like OpenAPI and GraphQL in the same instance.
#
# handlers -- list of handlers to be used across chains in this microservice
# including the routing handlers for ALL endpoints
# -- format: fully qualified handler class name@optional:given name
# chains -- allows forming of [1..N] chains, which could be wholly or
# used to form handler chains for each endpoint
# ex.: default chain below, reused partially across multiple endpoints
# paths -- list all the paths to be used for routing within the microservice
# ---- path: the URI for the endpoint (ex.: path: '/v1/pets')
# ---- method: the operation in use (ex.: 'post')
# ---- exec: handlers to be executed -- this element forms the list and
# the order of execution for the handlers
#
# IMPORTANT NOTES:
# - to avoid executing a handler, it has to be removed/commented out in the chain
# or change the enabled:boolean to false for a middleware handler configuration.
# - all handlers, routing handler included, are to be listed in the execution chain
# - for consistency, give a name to each handler; it is easier to refer to a name
# vs a fully qualified class name and is more elegant
# - you can list in chains the fully qualified handler class names, and avoid using the
# handlers element altogether
#------------------------------------------------------------------------------
handlers:
# Light-framework cross-cutting concerns implemented in the microservice
- com.networknt.exception.ExceptionHandler@exception
- com.networknt.metrics.MetricsHandler@metrics
- com.networknt.traceability.TraceabilityHandler@traceability
- com.networknt.correlation.CorrelationHandler@correlation
# Cors handler to handler post/put pre-flight
- com.networknt.cors.CorsHttpHandler@cors
- com.networknt.openapi.OpenApiHandler@specification
# - com.networknt.openapi.JwtVerifyHandler@security
# - com.networknt.body.BodyHandler@body
# - com.networknt.audit.AuditHandler@audit
# - com.networknt.sanitizer.SanitizerHandler@sanitizer
- com.networknt.openapi.ValidatorHandler@validator
# Header middleware to manipulate request and/or response headers before or after downstream server
# - com.networknt.header.HeaderHandler@header
# Direct requests to named services based on the request path
# - com.networknt.router.middleware.PathPrefixServiceHandler@path
# - com.networknt.router.RouterHandler@router
- com.networknt.resource.PathResourceHandler@resource
# Customer business domain specific cross-cutting concerns handlers
# - com.example.validator.CustomizedValidator@custvalidator
# Framework endpoint handlers
- com.networknt.health.HealthGetHandler@health
- com.networknt.info.ServerInfoGetHandler@info
- com.networknt.oauth.code.handler.CodeGetHandlerWrapper@get
- com.networknt.oauth.code.handler.CodePostHandlerWrapper@post
# - com.networknt.metrics.prometheus.PrometheusGetHandler@getprometheus

chains:
default:
- exception
- traceability
- correlation
- cors
- specification
- validator

paths:
- path: '/oauth2/code'
method: 'GET'
exec:
- default
- get

- path: '/oauth2/code'
method: 'POST'
exec:
- default
- post

- path: '/health/com.networknt.oauth2-code-1.0.0'
method: 'get'
exec:
- health

# In most case, the /server/info endpoint shouldn't be exposed. If it is, then it must be protected by OAuth 2.0 or Basic Auth
- path: '/server/info'
method: 'get'
exec:
- info


defaultHandlers:
- resource
14 changes: 0 additions & 14 deletions code/src/test/resources/config/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -139,17 +139,3 @@ paths:
- j_password
- response_type
- client_id
/health/{serviceId}:
get:
description: Return OK with response code 200 to indicate healthy
operationId: getHealth
parameters:
- name: serviceId
description: 'serviceId for the code service'
in: path
required: true
schema:
type: string
responses:
'200':
description: Successful Operation
8 changes: 8 additions & 0 deletions code/src/test/resources/config/path-resource.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
path: /
# This is the base used by docker
# base: /login-view/build
# This is the base that is used for IDE debugging
base: /home/steve/networknt/light-oauth2/login-view/build
prefix: true
transferMinSize: 10485760
directoryListingEnabled: false
26 changes: 0 additions & 26 deletions code/src/test/resources/config/service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,12 @@ singletons:
# Default decryptor implementation
- com.networknt.utility.Decryptor:
- com.networknt.decrypt.AESDecryptor
# HandlerProvider implementation
- com.networknt.handler.HandlerProvider:
- com.networknt.oauth.code.PathHandlerProvider
# StartupHookProvider implementations, there are one to many and they are called in the same sequence defined.
- com.networknt.server.StartupHookProvider:
- com.networknt.oauth.cache.CacheStartupHookProvider
# ShutdownHookProvider implementations, there are one to many and they are called in the same sequence defined.
- com.networknt.server.ShutdownHookProvider:
- com.networknt.oauth.cache.CacheShutdownHookProvider
# MiddlewareHandler implementations, the calling sequence is as defined in the request/response chain.
- com.networknt.handler.MiddlewareHandler:
# Exception Global exception handler that needs to be called first to wrap all middleware handlers and business handlers
- com.networknt.exception.ExceptionHandler
# Metrics handler to calculate response time accurately, this needs to be the second handler in the chain.
- com.networknt.metrics.MetricsHandler
# Traceability Put traceabilityId into response header from request header if it exists
- com.networknt.traceability.TraceabilityHandler
# Correlation Create correlationId if it doesn't exist in the request header and put it into the request header
- com.networknt.correlation.CorrelationHandler
# Cors handler to handler post/put pre-flight
- com.networknt.cors.CorsHttpHandler
# Parsing OpenAPI 3.0 specification based on request uri and method.
- com.networknt.openapi.OpenApiHandler
# Body Parse body based on content type in the header.
- com.networknt.body.BodyHandler
# SimpleAudit Log important info about the request into audit log
- com.networknt.audit.AuditHandler
# Sanitizer Encode cross site scripting
- com.networknt.sanitizer.SanitizerHandler
# Validator Validate request based on OpenAPI 3.0 specification (depending on OpenApiHandler and BodyHandler)
- com.networknt.openapi.ValidatorHandler

# Authenticator implementation mapping
- com.networknt.oauth.auth.Authenticator<com.networknt.oauth.auth.DefaultAuth>:
- com.networknt.oauth.auth.DefaultAuthenticator
Expand Down
23 changes: 23 additions & 0 deletions login-view/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
Loading