【问题标题】:Configure Identity Server 4 With Ionic 2使用 Ionic 2 配置 Identity Server 4
【发布时间】:2017-12-19 03:49:16
【问题描述】:

我正在尝试将 Identity Server 配置为与 Ionic 2 一起使用。我对如何配置重定向 URL 有点困惑。当我在浏览器中进行测试时。

我正在更新和集成 OIDC Cordova 组件。 旧组件 git hub 在这里: https://github.com/markphillips100/oidc-cordova-demo

我创建了一个 typescript 提供程序并在我的 app.module.ts 中注册了它

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import { Component } from '@angular/core';
import * as Oidc from "oidc-client";
import { Events } from 'ionic-angular';
import { environment } from "../rules/environments/environment";

export class UserInfo {
    user: Oidc.User = null;
    isAuthenticated: boolean = false;
}

@Injectable()
export class OidcClientProvider   {

    USERINFO_CHANGED_EVENT_NAME: string = ""
    userManager: Oidc.UserManager;
    settings: Oidc.UserManagerSettings;
    userInfo: UserInfo = new UserInfo();
    constructor(public events:Events) {

        this.settings = {
            //authority: "https://localhost:6666",
            authority: environment.identityServerUrl,
            client_id: environment.clientAuthorityId,
            //This doesn't work
            post_logout_redirect_uri: "http://localhost/oidc",
            redirect_uri: "http://localhost/oidc",
            response_type: "id_token token",
            scope: "openid profile",

            automaticSilentRenew: true,
            filterProtocolClaims: true,
            loadUserInfo: true,
            //popupNavigator: new Oidc.CordovaPopupNavigator(),
            //iframeNavigator: new Oidc.CordovaIFrameNavigator(),
        }

        this.initialize();
    }

    userInfoChanged(callback: Function) {
        this.events.subscribe(this.USERINFO_CHANGED_EVENT_NAME, callback);
    }

    signinPopup(args?): Promise<Oidc.User> {
        return this.userManager.signinPopup(args);
    }

    signoutPopup(args?) {
        return this.userManager.signoutPopup(args);
    }

    protected initialize() {

        if (this.settings == null) {
            throw Error('OidcClientProvider required UserMangerSettings for initialization')
        }

        this.userManager = new Oidc.UserManager(this.settings);
        this.registerEvents();
    }

    protected notifyUserInfoChangedEvent() {
        this.events.publish(this.USERINFO_CHANGED_EVENT_NAME);
    }

    protected clearUser() {
        this.userInfo.user = null;
        this.userInfo.isAuthenticated = false;
        this.notifyUserInfoChangedEvent();
    }

    protected addUser(user: Oidc.User) {
        this.userInfo.user = user;
        this.userInfo.isAuthenticated = true;
        this.notifyUserInfoChangedEvent();
    }

    protected registerEvents() {
        this.userManager.events.addUserLoaded(u => {
            this.addUser(u);
        });

        this.userManager.events.addUserUnloaded(() => {
            this.clearUser();
        });

        this.userManager.events.addAccessTokenExpired(() => {
            this.clearUser();
        });

        this.userManager.events.addSilentRenewError(() => {
            this.clearUser();
        });
    }
}

我正在尝试了解如何配置重定向 URL,以便可以在浏览器中正常进行身份验证。通常你会配置一个重定向 url 在登录后获取令牌和声明。

this.settings = {
        authority: environment.identityServerUrl,
        client_id: environment.clientAuthorityId,
        post_logout_redirect_uri: "http://localhost:8100/oidc",
        redirect_uri: "http://localhost:8100/oidc",
        response_type: "id_token token",
        scope: "openid profile AstootApi",

        automaticSilentRenew: true,
        filterProtocolClaims: true,
        loadUserInfo: true,
        //popupNavigator: new Oidc.CordovaPopupNavigator(),
        //iframeNavigator: new Oidc.CordovaIFrameNavigator(),
    }

Ionic 2 不使用 url 进行路由,假设我有一个组件 AuthenticationPage 处理存储身份验证令牌。 如何配置重定向 url 使其导航到身份验证页面,以便我可以在浏览器中进行测试?

【问题讨论】:

  • 你是用inappbrowser插件访问idp的吗?
  • OIDC 提供商会为您处理这个问题,尽管我还没有在本机上测试它,因为我已更改为目标 PWA。如果这些信息中的任何一个被证明是有用的,请记得点赞。如果您有任何其他问题,请给我发表评论,我会尽力帮助您
  • 我已经完成了一个简单的实现,它不适用于本机,因为它没有连接到 inappbrowser。适用于网页但不是本机。在这个阶段,如果你想使用自定义 idp,离子似乎不太适合目的
  • @Aeseir 在我的问题中看到两行注释掉的代码,这两行代码应该设置 oidc 以使用 idp 的弹出导航器。但是,如果您使用 Angular 4,则可以使用更好的 OIDC 管理器。
  • 顺便说一句,我将研究 ResourceOwner 流作为替代方案并实现我自己的前端。这是不推荐的方式,但可以启用安静的登录和注销。保持联系以获取更新(我会得到一个 github repo)

标签: javascript angular cordova typescript ionic2


【解决方案1】:

TL;DR

我必须做一些事情才能使它正常工作。
起初我没有意识到,但我的重定向网址必须与我的客户存储在身份服务器中的内容相匹配。

new Client
{
    ClientId = "myApp",
    ClientName = "app client",
    AccessTokenType = AccessTokenType.Jwt,
    RedirectUris = { "http://localhost:8166/" },
    PostLogoutRedirectUris = { "http://localhost:8166/" },
    AllowedCorsOrigins = { "http://localhost:8166" },
    //...
}

所以 Typescript 中的 OIDC 客户端也需要更新。

this.settings = {
    authority: environment.identityServerUrl,
    client_id: environment.clientAuthorityId,
    post_logout_redirect_uri: "http://localhost:8166/",
    redirect_uri: "http://localhost:8166/",
    response_type: "id_token token",
}

此外,由于我不想在 Ionic 中设置路由,因此我需要找到一种与 Ionic 通信的 url(出于浏览器测试目的,正常通信将通过 cordova 完成)。

所以我将重定向 url 指定为 ionic 托管我的应用程序的 url,并在构造函数中的 app.Component.ts 上添加了代码以尝试获取我的身份验证令牌。

constructor(
  public platform: Platform,
  public menu: MenuController,
  public oidcClient: OidcClientProvider
)
{
  //Hack: since Ionic only has 1 default address, attempt to verify if this is a call back before calling 
   this.authManager.verifyLoginCallback().then((isSuccessful) => {
     if (!isSuccessful) {
        this.authManager.IsLoggedIn().then((isLoggedIn) => {
          if (isLoggedIn) {
              return;
          }

          this.nav.setRoot(LoginComponent)
        });
     }
  });
}

编辑验证登录回调应该只是 oidc 客户端回调,它将从获取参数中读取令牌

verifyLoginCallback(): Promise<boolean> {
    return this.oidcClient.userManager.signinPopupCallback()
        .then(user => {
            return this.loginSuccess(user).
                then(() => true,
                    () => false);
    }, err => { console.log(err); return false; });
} 

注意 Login 组件只是一个表示登录登录页面的模态,它只是使用一个登录按钮来初始化弹出窗口。您可以将其与任何用户驱动的事件挂钩以触发登录,但如果您想在不触发弹出窗口阻止程序的情况下支持 Web,则必须使用用户驱动的事件

<ion-footer no-shadow>
  <ion-toolbar no-shadow position="bottom">
    <button ion-button block (click)="login()">Login</button>
  </ion-toolbar>
</ion-footer>

login(): Promise<any> {
    return this.oidcClient.signinPopup().then((user) => {
        this.events.publish(environment.events.loginSuccess);
    }).catch((e) => { console.log(e); });
}

我确信有更好的重定向到不同的路线,这只是一个快速而肮脏的黑客

【讨论】:

  • 您不会碰巧有一个可以共享的存储库来展示您的应用设置吗?作为现在涉足此领域的人,弄清楚身份验证是我最大的问题。
  • @Aeseir 我没有可共享的仓库,你有什么问题?几乎所有的代码都可以让它工作
  • 我是 ionic 新手,所以我正在收集有关关键主题的信息,我需要拥有适当的经过身份验证的应用程序
  • @Aeseir 为什么要使用令牌服务器而不仅仅是使用 jwt 进行身份验证
  • 与其说是令牌的类型,不如说它是如何工作的。所以我试图弄清楚 IdentityServer4 设置需要如何进行移动应用程序身份验证以及我需要使用的令牌类型。我读到 PKCE 是我们应该使用的类型。无论给出什么访问令牌,我都将使用它作为不记名令牌从 api 服务器获取数据。
猜你喜欢
  • 2019-04-26
  • 2019-09-20
  • 2019-04-11
  • 1970-01-01
  • 1970-01-01
  • 2021-01-17
  • 1970-01-01
  • 2018-12-16
  • 1970-01-01
相关资源
最近更新 更多