Внешняя аутентификация с Azure Active Directory B2C - PullRequest
0 голосов
/ 21 мая 2018

В настоящее время мы изучаем использование AspNetBoilerPlate (.NETCore и Agular), и одной из самых больших частей, которые нам нужно использовать, является Azure Active Directory B2C.После нескольких попыток перенаправить страницу входа в экземпляр Azure B2C, мне не повезло.Моя цель, поэтому не нужно много переопределять, если какой-либо из базового кода ABP для достижения этой цели.Кроме того, у меня есть то, что рекомендовано в документации, но безуспешно.

https://aspnetboilerplate.com/Pages/Documents/Zero/User-Management?searchKey=authentication#external-authentication

Извините, вот фрагменты кода, которые я удалил с некоторыми подробностями:

В рамках проекта Portal.Web.Core - Аутентификация. Я создал новый класс, унаследованный от ExternalAuthProviderApiBase, и просто жестко запрограммировал некоторые значения для пользователя.Мне все еще нужно выяснить, как получить их из Azure AD B2C.

public class AzureActiveDirectoryB2CAuthProvider : ExternalAuthProviderApiBase
{
    public const string Name = "AzureB2C";

    public AzureActiveDirectoryB2CAuthProvider()
    {
    }

    public override Task<ExternalAuthUserInfo> GetUserInfo(string accessCode)
    {
        ExternalAuthUserInfo user = new ExternalAuthUserInfo();
        user.EmailAddress = "admin@aol.com";
        user.Name = "Administrator";
        user.Provider = this.ProviderInfo.Name;
        user.ProviderKey = "12345";
        user.Surname = "Cool Dude";

        return Task.FromResult(user);
    }
}

В Portal.Web.Host -> Startup.cs я регистрирую ExternalAuthProvider в методе Configure сразу после приложения.UserAuthentication

var externalAuthConfiguration = app.ApplicationServices.GetRequiredService<ExternalAuthConfiguration>();
externalAuthConfiguration.Providers.Add(
    new ExternalLoginProviderInfo(
        AzureActiveDirectoryB2CAuthProvider.Name, string.Empty, string.Empty,
        typeof(AzureActiveDirectoryB2CAuthProvider)
    )
);

Теперь на стороне Angular2 я добавил ссылку на библиотеку MSAL.js, созданную Microsoft, чтобы помочь обработать аутентификацию.

Внутри auth-route-guard.Файл ts Я изменил метод canActivate, чтобы вызывать службу входа в систему, которая будет пытаться определить, прошел ли пользователь аутентификацию, и, если нет, перенаправить его на страницу входа Microsoft.

if (!this._sessionService.user) {
    //this._router.navigate(['/account/login']);
    this._loginService.updateUser();
    return false;
}

Ниже вы увидите код изизмененный файл login.service.ts минус сведения о Azure AD B2C.

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { TokenAuthServiceProxy, AuthenticateModel, AuthenticateResultModel, ExternalLoginProviderInfoModel, ExternalAuthenticateModel, ExternalAuthenticateResultModel } fro`enter code here`m '@shared/service-proxies/service-proxies';
import { UrlHelper } from '@shared/helpers/UrlHelper';
import { AppConsts } from '@shared/AppConsts';

import { MessageService } from '@abp/message/message.service';
import { LogService } from '@abp/log/log.service';
import { TokenService } from '@abp/auth/token.service';
import { UtilsService } from '@abp/utils/utils.service';

declare var Msal: any;

@Injectable()
export class LoginService {
    static readonly twoFactorRememberClientTokenName = 'TwoFactorRememberClientToken';
    private clientApplication: any;

    authenticateModel: AuthenticateModel;
    authenticateResult: AuthenticateResultModel;

    externalAuthenticateModel: ExternalAuthenticateModel;
    externalAuthenticateResult: ExternalAuthenticateResultModel;

    rememberMe: boolean;

    B2CTodoAccessTokenKey = "msal.idtoken";

    tenantConfig = {
        tenant: "",
        clientID: '',
        signUpSignInPolicy: "",
        b2cScopes: ["openid"]
    };

    // Configure the authority for Azure AD B2C
    authority = "https://login.microsoftonline.com/tfp/" + this.tenantConfig.tenant + "/" + this.tenantConfig.signUpSignInPolicy;

    /*
     * B2C SignIn SignUp Policy Configuration
     */
    //clientApplication = new Msal.UserAgentApplication(
    //    this.tenantConfig.clientID, this.authority,
    //    function (errorDesc: any, token: any, error: any, tokenType: any) {
    //        // Called after loginRedirect or acquireTokenPopup
    //    }
    //);

    constructor(
        private _tokenAuthService: TokenAuthServiceProxy,
        private _router: Router,
        private _utilsService: UtilsService,
        private _messageService: MessageService,
        private _tokenService: TokenService,
        private _logService: LogService,
    ) {
        this.clear();
        this.clientApplication =
            new Msal.UserAgentApplication(
                this.tenantConfig.clientID,
                this.authority,
                this.authCallback);
    }

    authenticate(finallyCallback?: () => void): void {
        finallyCallback = finallyCallback || (() => { });
        var model = new ExternalAuthenticateModel;
        model.authProvider = "AzureB2C";
        model.providerAccessCode = this.getAccessToken();
        model.providerKey = "12345";

        this._tokenAuthService
            .externalAuthenticate(model)
            .finally(finallyCallback)
            .subscribe((result: ExternalAuthenticateResultModel) => {
                this.processExternalAuthenticateResult(result);
        });
    }

    private processAuthenticateResult(authenticateResult: AuthenticateResultModel) {
        this.authenticateResult = authenticateResult;

        if (authenticateResult.accessToken) {
            //Successfully logged in
            this.login(authenticateResult.accessToken, authenticateResult.encryptedAccessToken, authenticateResult.expireInSeconds, this.rememberMe);

        } else {
            //Unexpected result!
            this._logService.warn('Unexpected authenticateResult!');
            this._router.navigate(['account/login']);
        }
    }

    private processExternalAuthenticateResult(externalAuthenticateResult: ExternalAuthenticateResultModel) {
        this.externalAuthenticateResult = externalAuthenticateResult;
        alert(externalAuthenticateResult.accessToken);
        if (externalAuthenticateResult.accessToken) {
            //Successfully logged in
            this.login(externalAuthenticateResult.accessToken, externalAuthenticateResult.encryptedAccessToken, externalAuthenticateResult.expireInSeconds, this.rememberMe);
        } else {
            //Unexpected result!

            this._logService.warn('Unexpected externalAuthenticateResult!');
        }
    }

    private login(accessToken: string, encryptedAccessToken: string, expireInSeconds: number, rememberMe?: boolean): void {
        var tokenExpireDate = rememberMe ? (new Date(new Date().getTime() + 1000 * expireInSeconds)) : undefined;

        this._tokenService.setToken(
            accessToken,
            tokenExpireDate
        );

        this._utilsService.setCookieValue(
            AppConsts.authorization.encrptedAuthTokenName,
            encryptedAccessToken,
            tokenExpireDate,
            abp.appPath
        );

        var initialUrl = UrlHelper.initialUrl;
        if (initialUrl.indexOf('/login') > 0) {
            initialUrl = AppConsts.appBaseUrl;
        }

        location.href = initialUrl;
    }

    private clear(): void {
        this.authenticateModel = new AuthenticateModel();
        this.authenticateModel.rememberClient = false;
        this.authenticateResult = null;
        this.rememberMe = false;
    }

    public AzureB2Clogin(): void {
        this.isOnline();
        this.clientApplication.loginRedirect(this.tenantConfig.b2cScopes);
    }

    saveAccessTokenToCache(accessToken: string): void {
        sessionStorage.setItem(this.B2CTodoAccessTokenKey, accessToken);
    };

    public isOnline(): boolean {
        return this.clientApplication.getUser() != null;
    };

    public getAccessToken(): string {
        alert('AccessToken: ' + sessionStorage.getItem(this.B2CTodoAccessTokenKey));
        return sessionStorage.getItem(this.B2CTodoAccessTokenKey);
    }

    public updateUser(): void {
        if (this.isOnline()) {
            this.authenticate();
        }
        else {
            this.AzureB2Clogin();
        }
    }

    public getAuthenticationToken(): Promise<string> {
        return this.clientApplication.acquireTokenSilent(this.tenantConfig.b2cScopes)
            .then(token => {
                alert("Got silent access token: " + token);
                return token;
            }).catch(error => {
                alert("Could not silently retrieve token from storage." + error);
                return this.clientApplication.acquireTokenPopup(this.tenantConfig.b2cScopes)
                    .then(token => {
                        alert("Got popup access token: "+ token);
                        return token;
                    }).catch(error => {
                        alert("Could not retrieve token from popup." + error);
                        this.clientApplication.acquireTokenRedirect(this.tenantConfig.b2cScopes);
                        return Promise.resolve("");
                    });
            });
    }

    private authCallback(errorDesc: any, token: any, error: any, tokenType: any) {
        if (token) {
            alert("Id token: " + token);
        }
        else {
            alert(error + ":" + errorDesc);
        }

        this.getAuthenticationToken();
    }
}

Наконец, к index.html добавлены следующие ссылки на сценарии ->

<script src="https://secure.aadcdn.microsoftonline-p.com/lib/0.1.3/js/msal.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.3.4/bluebird.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/2.0.3/fetch.min.js"></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...