Create new AuthStrategy
- Lingua principale
- TypeScript
- Stelle
- 8.1k
- Fork
- 1.5k
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Descrizione
### Issue type
**I'm submitting a ...** (check one with "x")
* [ ] bug report
* [X] feature request
### Issue description
**Current behavior:**
Now we have two kind of auth strategy: NbDummyAuthStrategy and NbPasswordAuthStrategy
**Expected behavior:**
I want to implement an Auth strategy based on SOAP, because my server talks with SOAP
**Steps to reproduce:**
I created a new Auth Strategy: class SoapAuthStrategy extends NbAuthStrategy and a new class SoapAuthStrategyOptions extends NbAuthStrategyOptions
The last code shows how i import my new strategy and pass to the NbAuthModule in my Core Module (based on ngx-admin)
The problem is that i get an error that say:
There is no Auth Strategy registered under 'email' name
What am i doing wrong?
**Related code:**
**SoapAuthStrategy **
```
@Injectable()
export class SoapAuthStrategy extends NbAuthStrategy {
protected defaultOptions: SoapAuthStrategyOptions = soapStrategyOptions;
soapClient: Client;
baseUrl = "http://localhost:8000/";
authUrl = this.baseUrl + "security.asmx?wsdl";
static setup(
options: SoapAuthStrategyOptions
): [NbAuthStrategyClass, SoapAuthStrategyOptions] {
return [SoapAuthStrategy, options];
}
constructor(
private zone: NgZone,
) {
super();
createClient(this.authUrl, (err, res) => {
if (err) {
console.error("Errore createClient Auth", err);
}
this.soapClient = res;
});
}
authenticate(data?: any): Observable {
const module = "login";
const method = this.getOption(`${module}.method`);
const url = this.getActionEndpoint(module);
const requireValidToken = false; //this.getOption(`${module}.requireValidToken`);
const authArgs = {
username: data.username,
password: data.password,
ipAddress: "123456789",
workstation: "ciaone1",
clientType: "C",
};
return Observable.create((observer) => {
(this.soapClient as any).Authentication(
authArgs,
(errr, ress: AuthenticationResponse) => {
if (errr) {
console.error(errr);
observer.complete();
return this.handleResponseError(errr, "Autenticazione");
}
console.log(ress);
const sp =
ress.AuthenticationResult.diffgram.SecurityDataSet
.SP_ACT_Autenticazione_GetToken;
const soapHeaderString =
`
` +
sp.SessionDigest +
`
` +
sp.IdPersona +
`
` +
"00000000-0000-0000-0000-000000000000" +
`
` +
"123456789" +
`
`;
const nbb = {
data: {
token: {
rawString: soapHeaderString,
obj: ress.AuthenticationResult.diffgram.SecurityDataSet,
},
},
};
// this.testOk(soapHeaderString);
return this.zone.run(() => {
observer.next(
new NbAuthResult(
true,
ress,
this.getOption(`${module}.redirect.success`),
[],
this.getOption("messages.getter")(module, ress, this.options),
this.createToken(
this.getOption("token.getter")(module, nbb, this.options),
false
)
)
);
observer.complete();
});
}
);
});
}
register(data?: any): Observable {
}
requestPassword(data?: any): Observable {
}
resetPassword(data: any = {}): Observable {
}
logout(): Observable {
}
refreshToken(data?: any): Observable {
}
protected handleResponseError(
res: any,
module: string
): Observable {
}
}
```
**Soap Strategy Options**
```
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
import { HttpErrorResponse, HttpResponse } from '@angular/common/http';
import { NbAuthTokenClass, NbAuthStrategyOptions, getDeepFromObject } from '@nebular/auth';
import { ArteToken } from '../../token/arte-token';
export interface SoapStrategyModule {
alwaysFail?: boolean;
endpoint?: string;
method?: string;
redirect?: {
success?: string | null;
failure?: string | null;
};
requireValidToken?: boolean;
defaultErrors?: string[];
defaultMessages?: string[];
}
export interface SoapStrategyReset extends SoapStrategyModule {
resetPasswordTokenKey?: string;
}
export interface SoapStrategyToken {
class?: NbAuthTokenClass,
key?: string,
getter?: Function,
}
export interface SoapStrategyMessage {
key?: string,
getter?: Function,
}
export class SoapAuthStrategyOptions extends NbAuthStrategyOptions {
baseEndpoint? = '/api/auth/';
login?: boolean | SoapStrategyModule = {
alwaysFail: false,
endpoint: 'login',
method: 'post',
requireValidToken: true,
redirect: {
success: '/',
failure: null,
},
defaultErrors: ['Username/Password combination is not correct, please try again.'],
defaultMessages: ['You have been successfully logged in.'],
};
register?: boolean | SoapStrategyModule = {
alwaysFail: false,
endpoint: 'register',
method: 'post',
requireValidToken: true,
redirect: {
success: '/',
failure: null,
},
defaultErrors: ['Something went wrong, please try again.'],
defaultMessages: ['You have been successfully registered.'],
};
requestPass?: boolean | SoapStrategyModule = {
endpoint: 'request-pass',
method: 'post',
redirect: {
success: '/',
failure: null,
},
defaultErrors: ['Something went wrong, please try again.'],
defaultMessages: ['Reset password instructions have been sent to your email.'],
};
resetPass?: boolean | SoapStrategyReset = {
endpoint: 'reset-pass',
method: 'put',
redirect: {
success: '/',
failure: null,
},
resetPasswordTokenKey: 'reset_password_token',
defaultErrors: ['Something went wrong, please try again.'],
defaultMessages: ['Your password has been successfully changed.'],
};
logout?: boolean | SoapStrategyReset = {
alwaysFail: false,
endpoint: 'logout',
method: 'delete',
redirect: {
success: '/',
failure: null,
},
defaultErrors: ['Something went wrong, please try again.'],
defaultMessages: ['You have been successfully logged out.'],
};
refreshToken?: boolean | SoapStrategyModule = {
endpoint: 'refresh-token',
method: 'post',
requireValidToken: true,
redirect: {
success: null,
failure: null,
},
defaultErrors: ['Something went wrong, please try again.'],
defaultMessages: ['Your token has been successfully refreshed.'],
};
token?: SoapStrategyToken = {
class: ArteToken,
key: 'data.token',
getter: (module: string, res: any, options: SoapAuthStrategyOptions) => getDeepFromObject(
res,
options.token.key,
),
};
errors?: SoapStrategyMessage = {
key: 'data.errors',
getter: (module: string, res: HttpErrorResponse, options: SoapAuthStrategyOptions) => getDeepFromObject(
res.error,
options.errors.key,
options[module].defaultErrors,
),
};
messages?: SoapStrategyMessage = {
key: 'data.messages',
getter: (module: string, res: HttpResponse, options: SoapAuthStrategyOptions) => getDeepFromObject(
res.body,
options.messages.key,
options[module].defaultMessages,
),
};
validation?: {
password?: {
required?: boolean;
minLength?: number | null;
maxLength?: number | null;
regexp?: string | null;
};
email?: {
required?: boolean;
regexp?: string | null;
};
fullName?: {
required?: boolean;
minLength?: number | null;
maxLength?: number | null;
regexp?: string | null;
};
};
}
export const soapStrategyOptions: SoapAuthStrategyOptions = new SoapAuthStrategyOptions();
```
**Custom Token**
```
import { NbAuthToken, NbAuthTokenNotFoundError, NbAuthEmptyTokenError } from "@nebular/auth";
import { SecurityDataSet } from '../../@core/data/security';
export class ArteToken extends NbAuthToken {
genericInfo: {
build: string;
defaultLang: string;
serverUpdatePath: string;
};
rawString: string;
obj: SecurityDataSet;
static NAME = "nb:auth:arte:token";
constructor(
protected readonly token: any,
protected readonly ownerStrategyName: string,
protected createdAt?: Date
) {
super();
//console.log("token: ", token, this.payload);
//this.payload = token.obj;
try {
this.parsePayload();
} catch (err) {
if (!(err instanceof NbAuthTokenNotFoundError)) {
// token is present but has got a problem, including illegal
throw err;
}
}
this.createdAt = this.prepareCreatedAt(createdAt);
}
protected parsePayload(): any {
//this.payload = null;
if (!this.token) {
throw new NbAuthTokenNotFoundError("Token not found.");
} else {
if (!Object.keys(this.token).length) {
throw new NbAuthEmptyTokenError(
"Cannot extract payload from an empty token."
);
}
}
this.payload = this.token;
}
protected prepareCreatedAt(date: Date) {
return date ? date : new Date();
}
/**
* Returns the token's creation date
* @returns {Date}
*/
getCreatedAt(): Date {
return this.createdAt;
}
/**
* Returns the token value
* @returns string
*/
getValue(): string {
return this.token;
}
getOwnerStrategyName(): string {
return this.ownerStrategyName;
}
/**
* Is non empty and valid
* @returns {boolean}
*/
isValid(): boolean {
return !!this.getValue();
}
/**
* Validate value and convert to string, if value is not valid return empty string
* @returns {string}
*/
toString(): string {
return !!this.token ? this.token : "";
}
}
```
**Core Module**
```
export const NB_CORE_PROVIDERS = [
...MockDataModule.forRoot().providers,
...SoapDataModule.forRoot().providers,
...DATA_SERVICES,
SoapAuthStrategy,
...NbAuthModule.forRoot({
strategies: [
SoapAuthStrategy.setup({
name: "soap",
//delay: 3000,
}),
],
forms: {
login: {
socialLinks: socialLinks,
},
register: {
socialLinks: socialLinks,
},
},
}).providers,
NbSecurityModule.forRoot({
accessControl: {
guest: {
view: "*",
},
user: {
parent: "guest",
create: "*",
edit: "*",
remove: "*",
},
},
}).providers,
{
provide: NbRoleProvider,
useClass: NbSimpleRoleProvider,
},
AnalyticsService,
LayoutService,
PlayerService,
SeoService,
StateService,
];
@NgModule({
imports: [CommonModule],
exports: [NbAuthModule],
declarations: [],
})
export class CoreModule {
constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
throwIfAlreadyLoaded(parentModule, "CoreModule");
}
static forRoot(): ModuleWithProviders {
return {
ngModule: CoreModule,
providers: [...NB_CORE_PROVIDERS],
};
}
}
```
### Other information:
**npm, node, OS, Browser**
```
Node: v12.9.0, npm: v6.10.2
OS: Windows 10
Browser: Chrome
```
**Angular, Nebular**
```
"@nebular/auth": "5.0.0",
"@nebular/eva-icons": "5.0.0",
"@nebular/security": "5.0.0",
"@nebular/theme": "5.0.0",
```
Guida per i contributori
Apri la guida per i contributori
Valutazione
Questa issue non è ancora stata valutata.