or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application.mdasync-io.mdauth.mddistributed.mddns.mdemail.mdhttp.mdindex.mdlogging.mdprotocols.mdssh.mdtesting.md

auth.mddocs/

0

# Authentication and Authorization

1

2

Pluggable authentication and authorization system with support for various credential types, checkers, and realms for securing network services. Twisted Cred provides a flexible framework for implementing authentication across different protocols.

3

4

## Capabilities

5

6

### Portal and Realm

7

8

Core authentication coordination and user domain management.

9

10

```python { .api }

11

class portal.Portal:

12

"""

13

Authentication coordinator that manages checkers and realms.

14

15

Attributes:

16

- realm: Authentication realm (IRealm)

17

- checkers: Dict of credential interfaces to checker lists

18

"""

19

realm = None

20

checkers = None

21

22

def __init__(self, realm, checkers=None):

23

"""

24

Args:

25

realm: Authentication realm (IRealm)

26

checkers: Sequence of credential checkers

27

"""

28

29

def registerChecker(self, checker, interface=None):

30

"""

31

Register a credentials checker.

32

33

Args:

34

checker: Credentials checker (ICredentialsChecker)

35

interface: Credential interface this checker handles

36

"""

37

38

def login(self, credentials, mind, *interfaces):

39

"""

40

Authenticate user and return avatar.

41

42

Args:

43

credentials: User credentials (ICredentials)

44

mind: User's perspective object

45

*interfaces: Requested avatar interfaces

46

47

Returns:

48

Deferred: Fires with (interface, avatar, logout) tuple

49

"""

50

51

class portal.IRealm:

52

"""

53

Interface for authentication realms.

54

55

Realms define the domain of authenticated users and create

56

avatars representing users in the system.

57

"""

58

def requestAvatar(avatarId, mind, *interfaces):

59

"""

60

Create avatar for authenticated user.

61

62

Args:

63

avatarId: Unique user identifier

64

mind: User's perspective object

65

*interfaces: Requested avatar interfaces

66

67

Returns:

68

tuple: (interface, avatar, logout_callable)

69

"""

70

```

71

72

**Portal Usage Example**:

73

74

```python

75

from twisted.cred import portal, checkers

76

from twisted.internet import defer

77

78

class SimpleRealm:

79

"""Simple realm that creates user avatars."""

80

81

def requestAvatar(self, avatarId, mind, *interfaces):

82

if IUser in interfaces:

83

avatar = User(avatarId)

84

logout = lambda: None # Cleanup function

85

return (IUser, avatar, logout)

86

raise NotImplementedError("Interface not supported")

87

88

# Create portal with realm and checker

89

realm = SimpleRealm()

90

checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()

91

checker.addUser(b"alice", b"password123")

92

93

portal_obj = portal.Portal(realm, [checker])

94

95

# Login user

96

from twisted.cred.credentials import UsernamePassword

97

credentials = UsernamePassword(b"alice", b"password123")

98

99

d = portal_obj.login(credentials, None, IUser)

100

d.addCallback(lambda result: print(f"Logged in: {result[1]}"))

101

```

102

103

### Credentials

104

105

Different types of user credentials for authentication.

106

107

```python { .api }

108

class credentials.ICredentials:

109

"""

110

Base interface for user credentials.

111

"""

112

113

class credentials.IUsernamePassword:

114

"""

115

Interface for username/password credentials.

116

117

Attributes:

118

- username: Username (bytes)

119

- password: Password (bytes)

120

"""

121

username = None

122

password = None

123

124

class credentials.UsernamePassword:

125

"""

126

Username and password credentials.

127

"""

128

def __init__(self, username, password):

129

"""

130

Args:

131

username (bytes): Username

132

password (bytes): Password

133

"""

134

135

def checkPassword(self, password):

136

"""

137

Check if password matches.

138

139

Args:

140

password (bytes): Password to check

141

142

Returns:

143

bool: True if password matches

144

"""

145

146

class credentials.IUsernameHashedPassword:

147

"""

148

Interface for username with hashed password credentials.

149

150

Attributes:

151

- username: Username (bytes)

152

- hashed: Hashed password (bytes)

153

"""

154

username = None

155

hashed = None

156

157

class credentials.UsernameHashedPassword:

158

"""

159

Username and hashed password credentials.

160

"""

161

def __init__(self, username, hashed):

162

"""

163

Args:

164

username (bytes): Username

165

hashed (bytes): Hashed password

166

"""

167

168

def checkPassword(self, password):

169

"""

170

Check password against hash.

171

172

Args:

173

password (bytes): Plain password to check

174

175

Returns:

176

bool: True if password matches hash

177

"""

178

179

class credentials.IAnonymous:

180

"""

181

Interface for anonymous credentials.

182

"""

183

184

class credentials.Anonymous:

185

"""

186

Anonymous credentials for unauthenticated access.

187

"""

188

189

class credentials.ISSHPrivateKey:

190

"""

191

Interface for SSH private key credentials.

192

193

Attributes:

194

- username: Username (bytes)

195

- algName: Key algorithm name (bytes)

196

- keyData: Public key data (bytes)

197

- signature: Authentication signature (bytes)

198

"""

199

username = None

200

algName = None

201

keyData = None

202

signature = None

203

204

class credentials.SSHPrivateKey:

205

"""

206

SSH private key credentials.

207

"""

208

def __init__(self, username, algName, keyData, signature, sigData):

209

"""

210

Args:

211

username (bytes): Username

212

algName (bytes): Key algorithm

213

keyData (bytes): Public key data

214

signature (bytes): Signature

215

sigData (bytes): Signed data

216

"""

217

```

218

219

### Credential Checkers

220

221

Implementations for verifying different types of credentials.

222

223

```python { .api }

224

class checkers.ICredentialsChecker:

225

"""

226

Interface for credential verification.

227

228

Attributes:

229

- credentialInterfaces: Supported credential types

230

"""

231

credentialInterfaces = None

232

233

def requestAvatarId(credentials):

234

"""

235

Verify credentials and return avatar ID.

236

237

Args:

238

credentials: User credentials (ICredentials)

239

240

Returns:

241

Deferred: Fires with avatar ID on success

242

"""

243

244

class checkers.InMemoryUsernamePasswordDatabaseDontUse:

245

"""

246

In-memory username/password database.

247

248

WARNING: For testing only - stores passwords in plain text.

249

"""

250

def __init__(self):

251

"""Initialize empty user database."""

252

self.users = {}

253

254

def addUser(self, username, password):

255

"""

256

Add user to database.

257

258

Args:

259

username (bytes): Username

260

password (bytes): Password

261

"""

262

263

def requestAvatarId(self, credentials):

264

"""

265

Check username/password credentials.

266

267

Args:

268

credentials: Username/password credentials

269

270

Returns:

271

Deferred: Avatar ID on success

272

"""

273

274

class checkers.FilePasswordDB:

275

"""

276

File-based password database.

277

"""

278

def __init__(self, filename, delim=b':', usernameField=0, passwordField=1, caseSensitive=True, hash=None, cache=False):

279

"""

280

Args:

281

filename (str): Password file path

282

delim (bytes): Field delimiter

283

usernameField (int): Username field index

284

passwordField (int): Password field index

285

caseSensitive (bool): Case-sensitive usernames

286

hash: Password hash function

287

cache (bool): Cache file contents

288

"""

289

290

def requestAvatarId(self, credentials):

291

"""

292

Check credentials against file database.

293

294

Args:

295

credentials: Username/password credentials

296

297

Returns:

298

Deferred: Avatar ID on success

299

"""

300

301

class checkers.AllowAnonymousAccess:

302

"""

303

Checker that allows anonymous access.

304

"""

305

credentialInterfaces = (credentials.IAnonymous,)

306

307

def requestAvatarId(self, credentials):

308

"""

309

Allow anonymous access.

310

311

Args:

312

credentials: Anonymous credentials

313

314

Returns:

315

Deferred: Anonymous avatar ID

316

"""

317

318

class checkers.SSHPublicKeyDatabase:

319

"""

320

SSH public key database checker.

321

"""

322

def checkKey(self, credentials):

323

"""

324

Verify SSH public key credentials.

325

326

Args:

327

credentials: SSH key credentials

328

329

Returns:

330

Deferred: Avatar ID on success

331

"""

332

333

def requestAvatarId(self, credentials):

334

"""

335

Check SSH key credentials.

336

337

Args:

338

credentials: SSH private key credentials

339

340

Returns:

341

Deferred: Avatar ID on success

342

"""

343

```

344

345

**Checker Usage Example**:

346

347

```python

348

from twisted.cred import checkers, credentials

349

from twisted.internet import defer

350

351

# In-memory checker

352

memory_checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()

353

memory_checker.addUser(b"admin", b"secret")

354

memory_checker.addUser(b"user", b"password")

355

356

# File-based checker

357

file_checker = checkers.FilePasswordDB("/etc/passwd", delim=b":")

358

359

# Anonymous access checker

360

anon_checker = checkers.AllowAnonymousAccess()

361

362

# Test authentication

363

creds = credentials.UsernamePassword(b"admin", b"secret")

364

d = memory_checker.requestAvatarId(creds)

365

d.addCallback(lambda avatar_id: print(f"Authenticated: {avatar_id}"))

366

d.addErrback(lambda failure: print(f"Auth failed: {failure.value}"))

367

```

368

369

### Authentication Errors

370

371

Exception types for authentication failures.

372

373

```python { .api }

374

class error.Unauthorized:

375

"""

376

Base class for authentication failures.

377

"""

378

379

class error.UnauthorizedLogin:

380

"""

381

Login attempt with invalid credentials.

382

"""

383

384

class error.UnhandledCredentials:

385

"""

386

No suitable checker found for credential type.

387

"""

388

389

class error.LoginFailed:

390

"""

391

Generic login failure.

392

"""

393

394

class error.LoginDenied:

395

"""

396

Login denied by policy.

397

"""

398

```

399

400

### String-based Credential Configuration

401

402

Utilities for configuring authentication from strings.

403

404

```python { .api }

405

def strcred.makeChecker(description):

406

"""

407

Create credential checker from string description.

408

409

Args:

410

description (str): Checker specification

411

412

Returns:

413

ICredentialsChecker: Configured checker

414

"""

415

416

# String checker formats:

417

# "memory:user1:pass1:user2:pass2" - In-memory database

418

# "file:/path/to/passwd" - File-based database

419

# "unix" - Unix system accounts

420

# "anonymous" - Allow anonymous access

421

```

422

423

**String Configuration Example**:

424

425

```python

426

from twisted.cred import strcred

427

428

# Create checkers from string descriptions

429

memory_checker = strcred.makeChecker("memory:alice:secret:bob:password")

430

file_checker = strcred.makeChecker("file:/etc/twisted-passwd")

431

anon_checker = strcred.makeChecker("anonymous")

432

433

# Use in portal

434

from twisted.cred.portal import Portal

435

portal_obj = Portal(realm, [memory_checker, file_checker, anon_checker])

436

```

437

438

### Protocol Integration

439

440

Integration points for using authentication in network protocols.

441

442

```python { .api }

443

# HTTP authentication example

444

from twisted.web.guard import HTTPAuthSessionWrapper, BasicCredentialFactory, DigestCredentialFactory

445

446

# Create credential factories

447

basic_factory = BasicCredentialFactory("My Realm")

448

digest_factory = DigestCredentialFactory("md5", "My Realm")

449

450

# Wrap resource with authentication

451

protected_resource = HTTPAuthSessionWrapper(portal_obj, [basic_factory, digest_factory])

452

453

# SSH authentication integration

454

from twisted.conch.ssh import factory

455

456

class MySSHFactory(factory.SSHFactory):

457

def __init__(self, portal):

458

self.portal = portal

459

460

def buildProtocol(self, addr):

461

protocol = factory.SSHFactory.buildProtocol(self, addr)

462

protocol.portal = self.portal

463

return protocol

464

```

465

466

### Custom Authentication

467

468

Patterns for implementing custom authentication mechanisms.

469

470

```python { .api }

471

# Custom credentials class

472

class TokenCredentials:

473

"""Custom token-based credentials."""

474

475

def __init__(self, token):

476

self.token = token

477

478

# Custom checker

479

class TokenChecker:

480

"""Custom token validation checker."""

481

482

credentialInterfaces = (TokenCredentials,)

483

484

def __init__(self, token_validator):

485

self.token_validator = token_validator

486

487

def requestAvatarId(self, credentials):

488

if self.token_validator.validate(credentials.token):

489

return defer.succeed(credentials.token.user_id)

490

else:

491

return defer.fail(error.UnauthorizedLogin("Invalid token"))

492

493

# Custom realm

494

class MyRealm:

495

"""Custom realm for creating user avatars."""

496

497

def requestAvatar(self, avatarId, mind, *interfaces):

498

if IMyUser in interfaces:

499

user = MyUser(avatarId)

500

logout = lambda: user.logout()

501

return (IMyUser, user, logout)

502

raise NotImplementedError()

503

```

504

505

**Complete Authentication Example**:

506

507

```python

508

from twisted.cred import portal, checkers, credentials

509

from twisted.internet import defer

510

from twisted.web import guard, resource, server

511

from twisted.application import internet, service

512

513

# Define user interface and avatar

514

class IUser(Interface):

515

pass

516

517

class User:

518

def __init__(self, username):

519

self.username = username

520

521

# Create realm

522

class MyRealm:

523

def requestAvatar(self, avatarId, mind, *interfaces):

524

if IUser in interfaces:

525

user = User(avatarId.decode())

526

return (IUser, user, lambda: None)

527

raise NotImplementedError()

528

529

# Set up authentication

530

realm = MyRealm()

531

checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()

532

checker.addUser(b"admin", b"password")

533

534

portal_obj = portal.Portal(realm, [checker])

535

536

# Create protected web resource

537

protected_resource = resource.Resource()

538

539

# Wrap with HTTP authentication

540

credential_factory = guard.BasicCredentialFactory("Protected Area")

541

wrapper = guard.HTTPAuthSessionWrapper(portal_obj, [credential_factory])

542

543

# Add to service

544

site = server.Site(wrapper)

545

web_service = internet.TCPServer(8080, site)

546

547

# Create application

548

application = service.Application("AuthApp")

549

web_service.setServiceParent(application)

550

```