fix login oauth cookie problem (#3508)

* fix login don't check the cookie in oauth2

* fix test

* check boolean storage
This commit is contained in:
Eugenio Romano
2018-06-20 12:08:35 +01:00
committed by GitHub
parent 061a2e5567
commit ebbf4c30a0
6 changed files with 46 additions and 19 deletions

View File

@@ -27,6 +27,8 @@ Authenticates to Alfresco Content Services and Alfresco Process Services.
- [Customizing validation rules](#customizing-validation-rules) - [Customizing validation rules](#customizing-validation-rules)
- [Call an external identity provider to fetch the auth token](#call-an-external-identity-provider-to-fetch-the-auth-token) - [Call an external identity provider to fetch the auth token](#call-an-external-identity-provider-to-fetch-the-auth-token)
- [Controlling form submit execution behaviour](#controlling-form-submit-execution-behaviour) - [Controlling form submit execution behaviour](#controlling-form-submit-execution-behaviour)
- [SSO login](#sso-login)
- [Implicit Flow](#implicit-flow)
- [See Also](#see-also) - [See Also](#see-also)
@@ -50,7 +52,7 @@ Authenticates to Alfresco Content Services and Alfresco Process Services.
| fieldsValidation | `any` | | Custom validation rules for the login form. | | fieldsValidation | `any` | | Custom validation rules for the login form. |
| logoImageUrl | `string` | "./assets/images/alfresco-logo.svg" | Path to a custom logo image. | | logoImageUrl | `string` | "./assets/images/alfresco-logo.svg" | Path to a custom logo image. |
| needHelpLink | `string` | "" | Sets the URL of the NEED HELP link in the footer. | | needHelpLink | `string` | "" | Sets the URL of the NEED HELP link in the footer. |
| providers | `string` | | Possible valid values are ECM, BPM or ALL. By default, this component will log in only to ECM. If you want to log in in both systems then use ALL. | | providers | `string` | | **Deprecated:** 3.0.0 |
| registerLink | `string` | "" | Sets the URL of the REGISTER link in the footer. | | registerLink | `string` | "" | Sets the URL of the REGISTER link in the footer. |
| showLoginActions | `boolean` | true | Should the extra actions (`Need Help`, `Register`, etc) be shown? | | showLoginActions | `boolean` | true | Should the extra actions (`Need Help`, `Register`, etc) be shown? |
| showRememberMe | `boolean` | true | Should the `Remember me` checkbox be shown? When selected, this option will remember the logged-in user after the browser is closed to avoid logging in repeatedly. | | showRememberMe | `boolean` | true | Should the `Remember me` checkbox be shown? When selected, this option will remember the logged-in user after the browser is closed to avoid logging in repeatedly. |
@@ -275,7 +277,7 @@ export class MyCustomLogin {
### Implicit Flow ### Implicit Flow
If the 'app.config.json' or you used the host-setting component to use the SSO Oauth the login component will show only a button to login: If the 'app.config.json' or you used the host-setting component to use the SSO Oauth the [login component](../core/login.component.md) will show only a button to login:
```JSON ```JSON
"authType" :"OAUTH", "authType" :"OAUTH",

View File

@@ -25,6 +25,7 @@ import { AuthenticationService } from '../../services/authentication.service';
import { LogService } from '../../services/log.service'; import { LogService } from '../../services/log.service';
import { TranslationService } from '../../services/translation.service'; import { TranslationService } from '../../services/translation.service';
import { UserPreferencesService } from '../../services/user-preferences.service'; import { UserPreferencesService } from '../../services/user-preferences.service';
import { SettingsService } from '../../services/settings.service';
import { LoginErrorEvent } from '../models/login-error.event'; import { LoginErrorEvent } from '../models/login-error.event';
import { LoginSubmitEvent } from '../models/login-submit.event'; import { LoginSubmitEvent } from '../models/login-submit.event';
@@ -86,9 +87,8 @@ export class LoginComponent implements OnInit {
@Input() @Input()
copyrightText: string = '\u00A9 2016 Alfresco Software, Inc. All Rights Reserved.'; copyrightText: string = '\u00A9 2016 Alfresco Software, Inc. All Rights Reserved.';
/** Possible valid values are ECM, BPM or ALL. /** @deprecated 3.0.0 Possible valid values are ECM, BPM or ALL.
* deprecated in 2.4.0 use the providers property in the the app.config.json * deprecated in 3.0.0 use the providers property in the the app.config.json
* @deprecated 2.4.0
*/ */
@Input() @Input()
providers: string; providers: string;
@@ -97,7 +97,7 @@ export class LoginComponent implements OnInit {
@Input() @Input()
fieldsValidation: any; fieldsValidation: any;
/** Prevents the CSRF Token from being submitted. Only valid for Alfresco Process Services. */ /** @depreated 3.0.0 Prevents the CSRF Token from being submitted. Only valid for Alfresco Process Services. */
@Input() @Input()
disableCsrf: boolean; disableCsrf: boolean;
@@ -147,7 +147,8 @@ export class LoginComponent implements OnInit {
private elementRef: ElementRef, private elementRef: ElementRef,
private router: Router, private router: Router,
private appConfig: AppConfigService, private appConfig: AppConfigService,
private userPreferences: UserPreferencesService private userPreferences: UserPreferencesService,
private settingsService: SettingsService
) { ) {
this.initFormError(); this.initFormError();
this.initFormFieldsMessages(); this.initFormFieldsMessages();
@@ -176,9 +177,8 @@ export class LoginComponent implements OnInit {
* @param event * @param event
*/ */
onSubmit(values: any) { onSubmit(values: any) {
if (this.disableCsrf !== null && this.disableCsrf !== undefined) { this.settingsService.setProviders(this.providers);
this.appConfig.get<boolean>(AppConfigValues.DISABLECSRF); this.settingsService.csrfDisabled = this.disableCsrf;
}
this.disableError(); this.disableError();
const args = new LoginSubmitEvent({ const args = new LoginSubmitEvent({

View File

@@ -104,7 +104,9 @@ export class AlfrescoApiService {
return this.getInstance().core.groupsApi; return this.getInstance().core.groupsApi;
} }
constructor(protected appConfig: AppConfigService, protected storage: StorageService) {} constructor(protected appConfig: AppConfigService,
protected storage: StorageService) {
}
async load() { async load() {
await this.appConfig.load().then(() => { await this.appConfig.load().then(() => {
@@ -124,13 +126,13 @@ export class AlfrescoApiService {
} }
const config = { const config = {
provider: this.appConfig.get<string>(AppConfigValues.PROVIDERS), provider: this.getProvider(),
hostEcm: this.appConfig.get<string>(AppConfigValues.ECMHOST), hostEcm: this.appConfig.get<string>(AppConfigValues.ECMHOST),
hostBpm: this.appConfig.get<string>(AppConfigValues.BPMHOST), hostBpm: this.appConfig.get<string>(AppConfigValues.BPMHOST),
authType: this.appConfig.get<string>(AppConfigValues.AUTHTYPE, 'BASIC'), authType: this.appConfig.get<string>(AppConfigValues.AUTHTYPE, 'BASIC'),
contextRootBpm: this.appConfig.get<string>(AppConfigValues.CONTEXTROOTBPM), contextRootBpm: this.appConfig.get<string>(AppConfigValues.CONTEXTROOTBPM),
contextRoot: this.appConfig.get<string>(AppConfigValues.CONTEXTROOTECM), contextRoot: this.appConfig.get<string>(AppConfigValues.CONTEXTROOTECM),
disableCsrf: this.storage.getItem('DISABLE_CSRF') === 'true', disableCsrf: this.getDisableCSRF(),
oauth2: oauth oauth2: oauth
}; };
@@ -140,4 +142,18 @@ export class AlfrescoApiService {
this.alfrescoApi = <AlfrescoApi> new alfrescoApi(config); this.alfrescoApi = <AlfrescoApi> new alfrescoApi(config);
} }
} }
// @deprecated 3.0.0 get only from app config
private getDisableCSRF(): boolean {
if (this.storage.getItem(AppConfigValues.DISABLECSRF) === 'true') {
return true;
} else {
return this.appConfig.get<boolean>(AppConfigValues.DISABLECSRF);
}
}
// @deprecated 3.0.0 get only from app config
private getProvider() {
return this.storage.getItem(AppConfigValues.PROVIDERS) || this.appConfig.get<string>(AppConfigValues.PROVIDERS);
}
} }

View File

@@ -128,6 +128,7 @@ describe('AuthenticationService', () => {
it('should require remember me set for ECM check', () => { it('should require remember me set for ECM check', () => {
spyOn(cookie, 'isEnabled').and.returnValue(true); spyOn(cookie, 'isEnabled').and.returnValue(true);
spyOn(authService, 'isRememberMeSet').and.returnValue(false); spyOn(authService, 'isRememberMeSet').and.returnValue(false);
spyOn(authService, 'isOauth').and.returnValue(false);
spyOn(apiService, 'getInstance').and.callThrough(); spyOn(apiService, 'getInstance').and.callThrough();
expect(authService.isEcmLoggedIn()).toBeFalsy(); expect(authService.isEcmLoggedIn()).toBeFalsy();
@@ -137,6 +138,7 @@ describe('AuthenticationService', () => {
it('should not require cookie service enabled for ECM check', () => { it('should not require cookie service enabled for ECM check', () => {
spyOn(cookie, 'isEnabled').and.returnValue(false); spyOn(cookie, 'isEnabled').and.returnValue(false);
spyOn(authService, 'isRememberMeSet').and.returnValue(false); spyOn(authService, 'isRememberMeSet').and.returnValue(false);
spyOn(authService, 'isOauth').and.returnValue(false);
spyOn(apiService, 'getInstance').and.callThrough(); spyOn(apiService, 'getInstance').and.callThrough();
expect(authService.isEcmLoggedIn()).toBeFalsy(); expect(authService.isEcmLoggedIn()).toBeFalsy();
@@ -230,6 +232,7 @@ describe('AuthenticationService', () => {
it('should require remember me set for BPM check', () => { it('should require remember me set for BPM check', () => {
spyOn(cookie, 'isEnabled').and.returnValue(true); spyOn(cookie, 'isEnabled').and.returnValue(true);
spyOn(authService, 'isRememberMeSet').and.returnValue(false); spyOn(authService, 'isRememberMeSet').and.returnValue(false);
spyOn(authService, 'isOauth').and.returnValue(false);
spyOn(apiService, 'getInstance').and.callThrough(); spyOn(apiService, 'getInstance').and.callThrough();
expect(authService.isBpmLoggedIn()).toBeFalsy(); expect(authService.isBpmLoggedIn()).toBeFalsy();

View File

@@ -164,7 +164,7 @@ export class AuthenticationService {
* @returns True if logged in, false otherwise * @returns True if logged in, false otherwise
*/ */
isEcmLoggedIn(): boolean { isEcmLoggedIn(): boolean {
if (this.cookie.isEnabled() && !this.isRememberMeSet()) { if (!this.isOauth() && this.cookie.isEnabled() && !this.isRememberMeSet()) {
return false; return false;
} }
return this.alfrescoApi.getInstance().isEcmLoggedIn(); return this.alfrescoApi.getInstance().isEcmLoggedIn();
@@ -175,7 +175,7 @@ export class AuthenticationService {
* @returns True if logged in, false otherwise * @returns True if logged in, false otherwise
*/ */
isBpmLoggedIn(): boolean { isBpmLoggedIn(): boolean {
if (this.cookie.isEnabled() && !this.isRememberMeSet()) { if (!this.isOauth() && this.cookie.isEnabled() && !this.isRememberMeSet()) {
return false; return false;
} }
return this.alfrescoApi.getInstance().isBpmLoggedIn(); return this.alfrescoApi.getInstance().isBpmLoggedIn();

View File

@@ -18,12 +18,14 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { AppConfigService, AppConfigValues } from '../app-config/app-config.service'; import { AppConfigService, AppConfigValues } from '../app-config/app-config.service';
import { LogService } from './log.service'; import { LogService } from './log.service';
import { StorageService } from './storage.service';
@Injectable() @Injectable()
export class SettingsService { export class SettingsService {
constructor(private appConfig: AppConfigService, constructor(private appConfig: AppConfigService,
private logService: LogService) { private logService: LogService,
private storage: StorageService) {
} }
/** @deprecated in 1.6.0 */ /** @deprecated in 1.6.0 */
@@ -35,6 +37,9 @@ export class SettingsService {
/** @deprecated in 1.7.0 */ /** @deprecated in 1.7.0 */
public set csrfDisabled(csrfDisabled: boolean) { public set csrfDisabled(csrfDisabled: boolean) {
this.logService.log(`SettingsService.csrfDisabled is deprecated. Use UserPreferencesService.disableCSRF instead.`); this.logService.log(`SettingsService.csrfDisabled is deprecated. Use UserPreferencesService.disableCSRF instead.`);
if (csrfDisabled !== null && csrfDisabled !== undefined) {
this.storage.setItem(AppConfigValues.DISABLECSRF, csrfDisabled.toString());
}
} }
/** @deprecated in 1.6.0 */ /** @deprecated in 1.6.0 */
@@ -62,11 +67,12 @@ export class SettingsService {
/** @deprecated in 1.7.0 */ /** @deprecated in 1.7.0 */
public getProviders(): string { public getProviders(): string {
this.logService.log(`SettingsService.getProviders is deprecated. Use UserPreferencesService.authType instead.`); this.logService.log(`SettingsService.getProviders is deprecated. Use UserPreferencesService.authType instead.`);
return this.appConfig.get<string>(AppConfigValues.PROVIDERS); return this.storage.getItem(AppConfigValues.PROVIDERS) || this.appConfig.get<string>(AppConfigValues.PROVIDERS);
} }
/** @deprecated in 1.7.0 */ /** @deprecated in 1.7.0 */
public setProviders(providers: string) { public setProviders(providers: string) {
this.logService.log(`SettingsService.aetProviders is deprecated. Use the app-config.json`); this.logService.log(`SettingsService.aetProviders is deprecated. Use the app-config.json`);
this.storage.setItem(AppConfigValues.PROVIDERS, providers);
} }
} }