A Classic ASP MVC web application running on IIS (Windows). It uses the RouteKit framework (front-controller pattern) with Keycloak OpenID Connect for authentication. The database is Microsoft Access (.accdb). There is no Node, npm, or build step — everything is server-side VBScript served by IIS.
public/ IIS site root — point IIS here
Default.asp Front controller and route table
web.config App settings, URL rewrite rules
core/ Framework internals — do not modify
autoload_core.asp
mvc.asp
router.wsc
lib.*.asp Core libraries (see below)
app/
controllers/ Controller classes (one per feature area)
views/ View partials (folders match controller name)
shared/ Header, footer, layout partials
models/ POBO (plain-old business objects)
repositories/ Data access classes
db/
migrations/ Sequential migration scripts
webdata.accdb Access database
tests/ Dev-only aspunit test harness (separate IIS app)
scripts/ VBScript code generators
| File | Purpose |
|---|---|
lib.Keycloak.asp |
OpenID Connect / Keycloak auth helper |
lib.Routes.asp |
Route registration and URL helpers |
lib.ControllerRegistry.asp |
Controller whitelist (security) |
lib.DAL.asp |
Database access layer |
lib.Data.asp |
Data helpers |
lib.Collections.asp |
Dictionary/list helpers |
lib.Enumerable.asp |
Collection iteration helpers |
lib.Validations.asp |
Input validation |
lib.Flash.asp |
Flash message helpers |
lib.FormCache.asp |
Form value re-population |
lib.HTML.asp |
HTML rendering helpers |
lib.HTML.Security.asp |
XSS escaping (H() function) |
lib.Strings.asp |
String utilities |
lib.Automapper.asp |
Object mapping helpers |
lib.ErrorHandler.asp |
Error handling |
lib.Migrations.asp |
Migration runner |
lib.json.asp |
JSON parsing/serialization |
lib.Upload.asp |
File upload helper |
lib.CDOEmail.asp |
Email via CDO |
lib.ad.auth.asp |
Active Directory auth |
lib.crypto.helper.asp |
Crypto utilities |
Defined in public/Default.asp:
| Method | Path | Controller | Action |
|---|---|---|---|
| GET | / |
HomeController | Index |
| GET | /home |
HomeController | Index |
| GET | /auth/login |
AuthController | Login |
| GET | /auth/callback |
AuthController | Callback |
| GET | /auth/logout |
AuthController | Logout |
| GET | /404 |
ErrorController | NotFound |
All requests are rewritten through Default.asp by the IIS URL Rewrite rule. Static assets (css/, js/, images/, favicon.ico) bypass the rewrite.
| Key | Description |
|---|---|
ConnectionString |
ACE OLEDB path to webdata.accdb |
Environment |
Development, Staging, or Production |
KeycloakBaseUrl |
Keycloak server base URL (no /realms/...) |
KeycloakRealm |
Keycloak realm name |
KeycloakClientId |
Client ID |
KeycloakClientSecret |
Client secret — never commit real values |
KeycloakRedirectUri |
Absolute callback URL, e.g. http://localhost:8080/auth/callback |
KeycloakLogoutRedirectUri |
Post-logout redirect URL |
KeycloakScope |
OIDC scopes (default: openid profile email) |
KeycloakEnableLogging |
true/false — diagnostic log for auth failures |
KeycloakLogPath |
Path to Keycloak log file |
EnableErrorLogging |
true/false |
ErrorLogPath |
Path to error log file |
The helper in core/lib.Keycloak.asp implements the OpenID Connect authorization-code flow.
Key functions:
KeycloakLogin() ' Redirect to Keycloak
KeycloakHandleCallback() ' Exchange code, store tokens — returns True on success
KeycloakIsLoggedIn() ' True if access token is in Session
KeycloakCurrentUser() ' Returns userinfo dictionary
KeycloakAccessToken() ' Raw access token string
KeycloakRefreshToken()
KeycloakIdToken()
KeycloakTokenClaims(token) ' Decode JWT payload into dictionary
KeycloakRequireLogin(returnToPath) ' Gate a page — redirects if not logged in
KeycloakConsumePostLoginRedirectPath("/") ' Get and clear stored return path
KeycloakHasRealmRole("admin") ' Role check against ID token
KeycloakHasClientRole(clientId, role)
KeycloakLogout("") ' Clear session and redirect to Keycloak logout
Session keys use the Keycloak_ prefix. Tokens are stored in Session, not cookies.
cscript //nologo scripts\generateMigration.vbs create_my_table
cscript //nologo scripts\runMigrations.vbs
cscript //nologo scripts\GenerateRepo.vbs /table:my_table /pk:id
Move generated files to app/models/ and app/repositories/.
cscript //nologo scripts\generateController.vbs MyController "Index;Show(id);Create;Store"
Move generated file to app/controllers/.
RegisterController "mycontroller"app/views/MyController/Tests live in tests/ and run as a separate IIS application (never through the production public/ root).
tests/aspunit/ (vendored)run-all.asp in the test IIS apptests/test-manifest.asp — register new test pages here manuallytests/bootstrap.asp — shared setup for all test pagesTest tiers:
| Folder | Use for |
|---|---|
tests/unit/ |
Deterministic helper and registry tests |
tests/component/ |
Controlled controller/object tests |
tests/integration/ |
Router/dispatch smoke tests, config behavior, rendered-page capture |
After changing tests/web.config, sync nested configs:
cscript //nologo tests\sync-webconfigs.vbs
Or sync and open in one step:
tests\run-tests.cmd
core/ — these are framework internals.ControllerRegistry — the MVC dispatcher will reject unregistered names.KeycloakClientSecret values — inject per environment.public/.public/ IIS app to run tests.H() from lib.HTML.Security.asp when rendering user-supplied data to prevent XSS.Powered by TurnKey Linux.