2

我正在尝试通过 ember-cli-simple-auth 使用身份验证来配置基本的 ember-cli 应用程序,并希望拥有一个专用的“访客”登录页面和不同的“管理员”登录页面(授权给不同的serverTokenEnpoint)。

我的“访客”页面正在工作,即如果用户尝试浏览受保护的路由(页面),那么他们将被重定向到默认的/login路由并可以登录。

我想不通的是如何让用户浏览到/admin/xyz路由,然后他们被重定向(使用到/admin/login反过来将验证到默认的不同serverTokenEnpoint

谁能指出我实现上述目标的正确方向?

谢谢。

受保护的“来宾”路由文件示例如下所示:

文件:/app/routes/protected.js

import Ember from 'ember';

import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin);

环境配置包含:

文件:/app/config/environment.js

ENV['simple-auth'] = {
    authorizer: 'simple-auth-authorizer:oauth2-bearer',
    store: 'simple-auth-session-store:local-storage',
    crossOriginWhitelist: ['http://www.domain.com/token',
                         'http://www.domain.com'
   ]
};

我什至尝试覆盖/app/routes/admin.js文件中的默认authenticationRoute,如下所示,但没有成功:

import Ember from 'ember';

import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin,{
    authenticationRoute: 'admin.login'
});

因此,为了按照 Marco 的建议简化流程,我现在有:

注意:目前这不起作用..@marcoow你有什么想法我哪里出错了吗?

这是使用带有以下 firebug 输出的 ember-cli:

AuthenticatorBase A (unknown mixin)  ***<- IS this expected????***
CustomAuthenticator B (unknown mixin)
DEBUG: -------------------------------
DEBUG: Ember                       : 1.7.0
DEBUG: Ember Data                  : 1.0.0-beta.9
DEBUG: Handlebars                  : 1.3.0
DEBUG: jQuery                      : 1.11.1
DEBUG: Ember Simple Auth           : 0.6.4
DEBUG: Ember Simple Auth OAuth 2.0 : 0.6.4
DEBUG: -------------------------------

如果我将手动覆盖代码放回查看先前的答案,它将起作用,但由于我想对不同的 URL 使用相同的 oauth2 身份验证,我喜欢能够使用自定义身份验证器覆盖TokenEndpoint的想法。

文件:app/initializers/simple-auth-admin.js

import AuthenticatorBase from 'simple-auth-oauth2/authenticators/oauth2';
var CustomAuthenticator = AuthenticatorBase.extend({
    serverTokenEndpoint:            AppchatENV['simple-auth-admin'].serverTokenEndpoint,
    serverTokenRevokationEndpoint:  AppchatENV['simple-auth-admin'].serverRevokationTokenEndpoint,
    refreshAccessTokens:            AppchatENV['simple-auth-admin'].refreshAccessTokens
});
console.log("AuthenticatorBase A ",AuthenticatorBase);
console.log("CustomAuthenticator B ",CustomAuthenticator);

export default {
    name:   'simple-auth-admin',
    before: 'simple-auth',
    initialize: function(container) {
        container.register('simple-auth-authenticator:admin', CustomAuthenticator);
    }
};

但是上面显示了“AuthenticatorBase A (unknown mixin)”的错误

然后在 文件中:app/controllers/admin/login.js

import Ember from 'ember';
import LoginControllerMixin from 'simple-auth/mixins/login-controller-mixin';
export default Ember.Controller.extend(LoginControllerMixin, {
    authenticator: 'simple-auth-authenticator:admin'
}

对于配置...

文件:config/environment.js

ENV['simple-auth-admin'] = {
    serverTokenEndpoint: "http://www.domain.com/admintoken",
    serverTokenRevokationEndpoint: "http://www.domain.com/admintoken/revoke",
    refreshAccessTokens: true
  };

编辑:

所以通过设置:在文件中: app/initializers/simple-auth-admin.js

import AuthenticatorBase from 'simple-auth-oauth2/authenticators/oauth2';
var CustomAuthenticator = AuthenticatorBase.extend({
    serverTokenEndpoint:            MyappENV['simple-auth-admin'].serverTokenEndpoint,
    serverTokenRevokationEndpoint:  MyappENV['simple-auth-admin'].serverRevokationTokenEndpoint,
    refreshAccessTokens:            MyappENV['simple-auth-admin'].refreshAccessTokens
});

console.log("AuthenticatorBase.serverTokenEndpoint =",AuthenticatorBase.serverTokenEndpoint);
console.log("CustomAuthenticator.serverTokenEndpoint =",CustomAuthenticator.serverTokenEndpoint);
console.log("MyappENV['simple-auth-admin'].serverTokenEndpoint =  ",MyappENV['simple-auth-admin'].serverTokenEndpoint);

export default {
    name:   'simple-auth-admin',
    before: 'simple-auth',
    initialize: function(container) {
        container.register('simple-auth-authenticator:admin', CustomAuthenticator);
        console.log("[at container.register] CustomAuthenticator.serverTokenEndpoint =  ",CustomAuthenticator.create().get('serverTokenEndpoint'));

    }
};

我得到以下输出:

AuthenticatorBase.serverTokenEndpoint = undefined
CustomAuthenticator.serverTokenEndpoint = undefined
MyappENV['simple-auth-admin'].serverTokenEndpoint =  http://www.domain.com/oauth2/admintoken
[at container.register] CustomAuthenticator.serverTokenEndpoint = http://www.domain.com/oauth2/admintoken

我是否误解了 AuthenticatorBase.extend () 在做什么?我认为它可以让你覆盖一些变量或函数?

编辑2:

文件:app/controllers/admin/login.js

import Ember from 'ember';
var $ = Ember.$;
import LoginControllerMixin from 'simple-auth/mixins/login-controller-mixin';
export default Ember.Controller.extend(LoginControllerMixin, {
    authenticator: 'simple-auth-authenticator:admin',
    init: function(){
        console.log('INIT LOGIN CONTROLLER', this.get('session'));
        this._super();
    },
    actions: {
        authenticate: function() { // (data)
            console.log("LoginController clicked");
            $('#nameBtn').ladda().ladda('start');
            console.log(this.get('session'));

            console.log('this.authenticator = ', this.authenticator);
            var _this = this;
            this._super().then(null, function(data) {
                console.log('LOGIN GOT BACK: ', data);
                $('#nameBtn').ladda().ladda('stop');
                    if(data.error !== undefined && data.error !== "") {
                    _this.set('data', {error: data.error});
                }
            });
        }
    }
});

这会导致一个 ajax 到www.domain.com/token而不是预期的www.domain.com/admintoken

4

3 回答 3

1

好的,经过大量的循环编码和反复试验,并在以下方面提供了很多帮助:

https://github.com/simplabs/ember-simple-auth/blob/master/examples/6-custom-server.html

这就是我实现我想要的方式的方式......

1)在环境文件中将 enpoints 设置为变量(simple-auth-admin 是我为我的管理员身份验证器选择的名称)

文件: /app/config/environment.js

ENV['simple-auth-admin'] = {
    serverTokenEndpoint: "http://www.domain.com/admintoken",
    serverTokenRevokationEndpoint: "http://www.domain.com/admintoken/revoke",
    refreshAccessTokens: true
};

2)在初始化程序中创建实际的身份验证器作为覆盖注意:在这种情况下,实际上并未使用 CustomAuthorizer 并确保将 AppNameENV 替换为您的应用程序名称,因此如果您的应用程序被称为bob它将是BobENV

文件:/app/initializers/simple-auth-admin.js

import Ember from 'ember';
import AuthenticatorBase from 'simple-auth/authenticators/base';
import AuthorizerBase from 'simple-auth/authorizers/base';

var CustomAuthorizer = AuthorizerBase.extend({
authorize: function(jqXHR, requestOptions) {
    if (this.get('session.isAuthenticated') && !Ember.isEmpty(this.get('session.token'))) {
        jqXHR.setRequestHeader('Authorization', 'Token: ' + this.get('session.token'));
    }
}
});

var CustomAuthenticator = AuthenticatorBase.extend({
tokenEndpoint: window.AppNameENV['simple-auth-admin'].serverTokenEndpoint,
tokenRevokationEndpoint: window.AppNameENV['simple-auth-admin'].serverRevokationTokenEndpoint,
refreshAccessTokens: window.AppNameENV['simple-auth-admin'].refreshAccessTokens,
init: function(){
    console.log("CUSOTMM AUTH INIT ",window.AppNameENV['simple-auth-admin'].serverTokenEndpoint);
    this._super();
},
restore: function(data) {
    console.log('AdminAuth - restore');
    return new Ember.RSVP.Promise(function(resolve, reject) {
        if (!Ember.isEmpty(data.token)) {
            resolve(data);
        } else {
            reject();
        }
    });
},
authenticate: function(credentials) {
    console.log('AdminAuth - authenticate',credentials);
    var _this = this;
    return new Ember.RSVP.Promise(function(resolve, reject) {
        Ember.$.ajax({
            url: _this.tokenEndpoint,
            type: 'POST',
            data: JSON.stringify({ grant_type: 'password', username: credentials.identification, password: credentials.password, session: { identification: credentials.identification, password: credentials.password } }),
                    contentType: 'application/json'
                }).then(function(response) {
                    Ember.run(function() {
                        resolve({ token: response.access_token });
                    });
                }, function(xhr, status, error) {
                    var response = JSON.parse(xhr.responseText);
                    Ember.run(function() {
                        reject(response.error);
                    });
                });
        });
    },
    invalidate: function() {
        console.log('AdminAuth - invalidate');
        var _this = this;
        return new Ember.RSVP.Promise(function(resolve) {
            Ember.$.ajax({ url: _this.tokenEndpoint, type: 'DELETE' }).always(function() {
            resolve();
            })
        });
    }
});

export default {
    name:   'simple-auth-admin',
    before: 'simple-auth',
    initialize: function(container) {
        console.log("OVERRIDES : ", window.AppNameENV['simple-auth-admin']);
        container.register('simple-auth-authenticator:admin', CustomAuthenticator);
        container.register('simple-auth-authorizer:admin', CustomAuthorizer);
    }
};

3)我为任何受保护的页面设置了一个重定向到 admin/login 的路由(这个例子是/admin/dashboard

文件:/app/routes/admin/dashboard.js

import Ember from 'ember';
import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';

export default Ember.Route.extend(AuthenticatedRouteMixin,{
    authenticationRoute: 'admin.login',
    actions: {
        authenticateSession: function() {
            this.transitionTo(this.authenticationRoute);
        }
    }
});

4)然后配置管理控制器使用新的自定义身份验证器

文件:/app/controllers/admin/login.js

import Ember from 'ember';
var $ = Ember.$;
import LoginControllerMixin from 'simple-auth/mixins/login-controller-mixin';
//import Session from 'simple-auth/session';

export default Ember.Controller.extend(LoginControllerMixin, {
    authenticator: 'simple-auth-authenticator:admin',
});

当我真正想做的只是将 /admin/login 点的身份验证指向不同的服务器端点时,所有这些似乎都有些繁重。Marco,有没有办法只覆盖这些变量并因此扩展simple-auth-oauth2授权者?

于 2014-09-05T12:20:15.370 回答
1

您定义的路线当然是必要的。

由于您的管理区域的授权人和身份验证器似乎也是自定义的,因此这些当然也是必要的。如果您在管理区域也使用了普通的 OAuth 2.0,您可以删除授权者并将验证者更改为

import AuthenticatorBase from 'simple-auth-oauth2/authenticators/oauth2';

var CustomAuthenticator = AuthenticatorBase.extend({
  serverTokenEndpoint:           'http://www.domain.com/admintoken',
  serverTokenRevokationEndpoint: 'http://www.domain.com/admintoken/revoke'
});
于 2014-09-05T13:58:50.253 回答
0

每次 Ember Simple Auth 强制执行身份验证(通常是当用户访问经过身份验证的路由而会话未经过身份验证时),它都会调用ApplicationRouteMixin's authenticateSessionaction。您拥有的最佳选择是覆盖它并以某种方式决定是从那里转换到管理员还是访客登录页面。如果你在一个/admin路由中有你的管理页面命名空间,你也可以覆盖authenticateSessionon theAdminRoute并从那里转换到管理登录页面,而ApplicationRoute转换到访客登录页面的默认实现。

对于身份验证器,最好使用默认的 OAuth 2.0 身份验证器serverTokenEndpoint来对来宾进行身份验证,并从另一个身份验证器扩展另一个身份验证器,该身份验证器针对不同的serverTokenEndpoint.

于 2014-09-05T06:51:54.643 回答