Skip to content
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@
"devDependencies": {
"@commitlint/cli": "^16.1.0",
"@commitlint/config-conventional": "^16.0.0",
"@types/jest": "^29.5.12",
"@types/node": "^20.19.1",
"@typescript-eslint/eslint-plugin": "^5.12.1",
"@typescript-eslint/parser": "^5.12.1",
"@vitest/coverage-v8": "^3.2.4",
"chalk": "^5.4.1",
"componentsjs-generator": "^3.1.2",
"eslint": "^8.10.0",
Expand Down
17 changes: 12 additions & 5 deletions packages/css/config/uma/overrides/jwks.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,18 @@
"overrideParameter": { "@id": "WaterfallHandler:_handlers" },
"overrideTarget": 0,
"overrideValue": {
"@id": "urn:solid-server:default:JwksHandler",
"@type": "JwksHandler",
"path": "/.well-known/jwks.json",
"generator": {
"@id": "urn:solid-server:default:JwkGenerator"
"@id": "urn:solid-server:default:JwksRouterHandler",
"@type": "RouterHandler",
"baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
"targetExtractor": { "@id": "urn:solid-server:default:TargetExtractor" },
"allowedPathNames": [ "^/.well-known/jwks.json" ],
"allowedMethods": [ "HEAD", "GET" ],
"handler": {
"@id": "urn:solid-server:default:JwksHandler",
"@type": "JwksHandler",
"generator": {
"@id": "urn:solid-server:default:JwkGenerator"
}
}
}
}]
Expand Down
3 changes: 1 addition & 2 deletions packages/css/config/uma/overrides/token-extractor.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
"@type": "UmaTokenExtractor",
"client": { "@id": "urn:solid-server:default:UmaClient" },
"targetExtractor": { "@id": "urn:solid-server:default:TargetExtractor" },
"ownerUtil": { "@id": "urn:solid-server:default:OwnerUtil" },
"introspect": false
"ownerUtil": { "@id": "urn:solid-server:default:OwnerUtil" }
}
}
]
Expand Down
7 changes: 0 additions & 7 deletions packages/css/config/uma/parts/owner-util.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,9 @@
"podStore": {
"@id": "urn:solid-server:default:PodStore"
},
"accountStore": {
"@id": "urn:solid-server:default:AccountStore"
},
"storageStrategy": {
"@id": "urn:solid-server:default:StorageLocationStrategy"
},
"umaPatStore": {
"@id": "urn:solid-server:default:UmaPatStore",
"@type": "MemoryMapStorage"
},
"umaServerURL": {
"@id": "urn:solid-server:uma:variable:AuthorizationServer"
}
Expand Down
2 changes: 1 addition & 1 deletion packages/css/config/uma/parts/resource-registrar.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"comment": "Listens to the activities emitted by the MonitoringStore.",
"@id": "urn:solid-server:default:ResourceRegistrar",
"@type": "ResourceRegistrar",
"store": {
"emitter": {
"@id": "urn:solid-server:default:ResourceStore"
},
"ownerUtil": {
Expand Down
4 changes: 1 addition & 3 deletions packages/css/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@
"types": "./dist/index.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"require": "./dist/index.js"
}
".": "./dist/index.js"
},
"files": [
".componentsignore",
Expand Down
131 changes: 0 additions & 131 deletions packages/css/src/authentication/UmaTokenExtractor.test.ts

This file was deleted.

40 changes: 19 additions & 21 deletions packages/css/src/authentication/UmaTokenExtractor.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { CredentialsExtractor, getLoggerFor, HttpRequest,
NotImplementedHttpError, BadRequestHttpError, Credentials, TargetExtractor } from '@solid/community-server';
import {
CredentialsExtractor, getLoggerFor, HttpRequest,
NotImplementedHttpError, BadRequestHttpError, Credentials, TargetExtractor, createErrorMessage
} from '@solid/community-server';
import { UmaClaims, UmaClient } from '../uma/UmaClient';
import { OwnerUtil } from '../util/OwnerUtil';

Expand All @@ -13,10 +15,13 @@ export class UmaTokenExtractor extends CredentialsExtractor {

/**
* Credentials extractor which interprets the contents of the Bearer authorization token as a UMA Access Token.
* @param {UMATokenExtractorArgs} args - properties
* @param client - {@link UmaClient} to verify tokens.
* @param targetExtractor - {@link TargetExtractor} to extract identifier from request.
* @param ownerUtil - {@link OwnerUtil} to find owners and issuers.
* @param introspect - If introspection should be used on incoming tokens.
*/
public constructor(
private client: UmaClient,
private client: UmaClient,
private targetExtractor: TargetExtractor,
private ownerUtil: OwnerUtil,
private introspect: boolean = false,
Expand All @@ -34,26 +39,26 @@ export class UmaTokenExtractor extends CredentialsExtractor {
}
}

/**
* ...
*/
public async handle(request: HttpRequest): Promise<UmaCredentials> {
this.logger.info('Extracting token from ' + request.headers.authorization);

const token = request.headers.authorization?.replace(/^Bearer/, '')?.trimStart();
if (!token) throw new BadRequestHttpError('Found empty Bearer token.');

try {
const target = await this.targetExtractor.handle({ request });
const target = await this.targetExtractor.handleSafe({ request });
const owners = await this.ownerUtil.findOwners(target);
const issuers = await Promise.all(owners.map(o => this.ownerUtil.findIssuer(o)))
const validIssuers = issuers.filter((i): i is string => i !== undefined);

if (this.introspect) {
this.logger.debug('Performing token introspection.');
const results = await Promise.allSettled(owners.map(owner => this.tryIntrospection(token, owner)));
const results = await Promise.allSettled(
validIssuers.map(issuer => this.client.verifyOpaqueToken(token, issuer)));
const succeeded = results.filter((r): r is PromiseFulfilledResult<UmaClaims> => r.status === 'fulfilled');
if (succeeded.length === 0) throw new Error ();
if (succeeded.length === 0)
throw new BadRequestHttpError(`Introspection failed: ${
results.map((r): string => createErrorMessage((r as PromiseRejectedResult).reason)).join(',')}`);
return { uma: { rpt: succeeded[0].value }};
} else {
this.logger.debug('Verifying JWT.');
Expand All @@ -62,16 +67,9 @@ export class UmaTokenExtractor extends CredentialsExtractor {
return { uma: { rpt } };
}
} catch (error: unknown) {
const msg = `Error verifying WebID via Bearer access token: ${(error as Error).message}`;
const msg = `Error verifying WebID via Bearer access token: ${createErrorMessage(error)}`;
this.logger.warn(msg);
throw new BadRequestHttpError(msg, {cause: error});
}
}

private async tryIntrospection(token: string, owner: string): Promise<UmaClaims> {
const issuer = await this.ownerUtil.findIssuer(owner);
if (!issuer) return Promise.reject();
return this.client.verifyOpaqueToken(token, issuer)
}

}
6 changes: 3 additions & 3 deletions packages/css/src/authorization/UmaAuthorizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ export const WWW_AUTH = namedNode('urn:css:http:headers:www-authenticate');

/**
* Authorizer that bases its decision on that of another Authorizer.
* It discovers the relevant UMA Authorization Server for the requeste resource(s),
* It discovers the relevant UMA Authorization Server for the requested resource(s),
* and checks whether that server protects the resource or whether it is public.
* If the resource is not public and access is not granted by the other Authorizer,
* the UmaAuthorizer includes a UMA Permission Ticket in the resulting error.
* the UmaAuthorizer includes an UMA Permission Ticket in the resulting error.
*/
export class UmaAuthorizer extends Authorizer {
protected readonly logger = getLoggerFor(this);

/**
* The UmaAuthorizer bases its decisions on those of another {@link Authorizer}.
* It uses an {@link OwnerUtil} to retrieve the relevant UMA issuer,
* and an {@link UmaCLient} to communicate with that issuer.
* and an {@link UmaClient} to communicate with that issuer.
* @param authorizer - {@link Authorizer} that makes the main decision.
* @param ownerUtil - {@link OwnerUtil} that links resources to owners and issuers.
* @param umaClient - {@link UmaClient} that communicates with UMA issuers.
Expand Down
46 changes: 0 additions & 46 deletions packages/css/src/authorization/UmaPermissionReader.test.ts

This file was deleted.

Loading