【问题标题】:Retrieving tokens from OAuth2 authorize endpoint in angularjs从OAuth2中检索令牌授权angularjs中的端点
【发布时间】:2015-11-03 23:30:40
【问题描述】:

我正在尝试将 IdentityServer 与 Angularjs 应用程序一起使用。 Angularjs 前端旨在在未经身份验证的用户尝试导航到应用程序的根 url 时调用授权端点。 app.config 有一个 resolve 属性,它会生成一个 routeChangeError。此事件触发重定向到 OAuth2 授权端点(在我的例子中是 IdentityServer,在 Asp.Net MVC 上运行)。

baseballApp.config(['$routeProvider', '$locationProvider', '$httpProvider', function($routeProvider, $locationProvider, $httpProvider) {
    $routeProvider.when('/players', {
        resolve: {
            auth: function ($q, $rootScope) {                    
                var deferred = $q.defer();
                if ($rootScope.token) {
                    deferred.resolve();
                } else {
                    deferred.reject();
                }                    
                return deferred.promise;
            }
    },
    templateUrl: '/FrontEnd/Templates/PlayerList.html',
    controller: 'PlayerListController'        
});
$routeProvider.otherwise({ redirectTo: '/players' });

var spinnerFunction = function (data, headersGetter) {
    if (data) {
        $('#spinner').show();
        return data;
    }
};

$httpProvider.defaults.transformRequest.push(spinnerFunction);
$httpProvider.interceptors.push('authInterceptor');}]).run(['$rootScope', '$location', 'authenticationService', function ($rootScope, $location, authenticationService) {
//authenticationService.getBearerToken().then(function(data) {
//    $rootScope.token = data;
//});

debugger;

var generateRandomString = function() {
    return (Math.random().toString(16) + "000000000").substr(2, 8);
}

var nonce = generateRandomString();
var state = generateRandomString();
$rootScope.$on('$routeChangeError', function () {
   window.location = 'https://localhost:44301/identity/connect/authorize?client_id=baseballStats&redirect_uri=https%3a%2f%2flocalhost%3a44300%2f&response_type=id_token+token&scope=openid+profile+roles+baseballStatsApi&nonce=' + nonce + '&state=' + state;
});}]);

如您所见,如果我没有令牌,我会重定向到授权端点。但是,我不清楚在授权端点上登录后如何检索令牌。

我已经指定了一个返回 url,在登录后它会重定向到应用程序,但是我将如何设置我的角度代码来检索应该在授权端点上生成并发送回应用程序的令牌?

我见过很多人使用不记名令牌身份验证进行 Angular 的示例,但我还没有看到任何人将 OAuth2 服务器的授权端点与 Angular 一起使用。在 MVC 中,有许多内置的回调来检索令牌。我正在寻找一些关于如何以角度实现这一点的想法。

你能告诉我我做错了什么吗?

编辑

我还尝试在重定向 uri 中传递哈希导航标记,但从 IdentityServer 获得“错误未知客户端”。请看下面的代码

  $rootScope.$on('$routeChangeError', function () {
   var returnUrl = encodeURIComponent('https://localhost:44300/#/players');
   window.location = 'https://localhost:44301/identity/connect/authorize?client_id=baseballStats&redirect_uri=' + returnUrl + '&response_type=id_token+token&scope=openid+profile+roles+baseballStatsApi&nonce=' + nonce + '&state=' + state;
});

有人知道为什么吗?

【问题讨论】:

    标签: javascript asp.net-mvc angularjs oauth-2.0 owin


    【解决方案1】:

    我想您正在为您的 spa js 应用程序使用隐式流量授权?

    在这种情况下,身份服务器会在您登录后将访问令牌发送回您的水疗应用程序的回调 url。使用该回调页面,您可以捕获令牌,以便在授权标头中将其作为不记名令牌传递给您的资源服务器。

    观看 Brock Allen 的这段视频,解释得很好: https://vimeo.com/131636653

    顺便说一句,您应该使用 Brock 自己编写的 oidc-token-manager。它非常易于使用,它抽象了与身份服务器的所有通信。它也可以在凉亭上买到,所以你可以从那里拿到它。

    最后,我想向您指出我最近一直在开发的我自己的 spa angular 应用程序:https://github.com/GeertHuls/SecuredApi

    它实际上使用令牌管理器来获取访问令牌,自动刷新它们并在整个 Angular 应用程序中公开它们。

    希望这会对您有所启发,以便将其与 angular 集成。

    【讨论】:

    • 感谢您的回复。这看起来很有希望。一旦有机会查看您提供的所有材料,我会尽快回复您。
    • 好的,如果您有其他问题,请告诉我。
    • 再次感谢您提供此信息。你的 github repo 很有帮助。只有一个问题:我尝试为授权端点指定 redirect_uri 以包含哈希 #/players/ (如您的 #/cb)(请参阅上面的编辑)。当我重定向到 IdentityServer 时,我得到一个“错误未知客户端”。知道为什么吗?
    • 那是因为身份服务器配置不正确。检查客户端配置:github.com/GeertHuls/SecuredApi/blob/master/SecuredApi/…。重定向 url 必须与 js tokenmanager 中配置的 url 匹配。即使正斜杠太多或太少都会导致“客户端未知”错误。
    • 这里是客户端回调 url 配置:github.com/GeertHuls/SecuredApi/blob/master/SecuredApi/…
    【解决方案2】:

    我通过创建一个自定义 ActionResult 来回避这个问题,当用户已经通过 .NET Auth cookie 登录时,它会返回一个带有令牌的 JSON 响应,它有点 hacky,看起来像这样;

        [AllowAnonymous]
        public ActionResult GetToken()
        {
            if (!User.Identity.IsAuthenticated)
            {
                Response.StatusCode = 403;
                return Json(new {message = "Forbidden - user not logged in."}, JsonRequestBehavior.AllowGet);
            }
    
            var claims = new ClaimsPrincipal(User).Claims.ToArray();
            var identity = new ClaimsIdentity(claims, "Bearer");
            AuthenticationManager.SignIn(identity);
            var ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
            var token = Startup.OAuthOptions.AccessTokenFormat.Protect(ticket);
            return Json(new { token }, JsonRequestBehavior.AllowGet);
        }
    

    【讨论】:

      猜你喜欢
      • 2018-09-19
      • 1970-01-01
      • 2016-10-16
      • 1970-01-01
      • 2016-10-13
      • 2014-02-07
      • 1970-01-01
      • 2015-09-17
      • 1970-01-01
      相关资源
      最近更新 更多