SPA - 火力地堡和.Net的WebAPI 2认证 [英] SPA - Firebase and .Net WebApi 2 authentication

查看:192
本文介绍了SPA - 火力地堡和.Net的WebAPI 2认证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写AngularJs(该框架是无关紧要的在这一点上)应用程序在IIS托管和它的组成中的index.html再加上一堆客户资产的单页的应用。

I'm having a Single Page Application written in AngularJs (The framework is irrelevant at this point) The application is hosted in IIS and it's compose of index.html plus a bunch of client assets.

在后台我的WebAPI 2,还主持在IIS作为一个单独的应用程序。

On backend I have WebApi 2, hosted also in IIS as a separate application.

有关我用火力地堡(简单的登录)与几个社会netoworks客户端认证功能,如Facebook,Twitter或谷歌。

For authentication on client I'm using Firebase (simple login) with several social netoworks enabled, like Facebook, Twitter or Google.

到目前为止好。我喜欢它是多么容易使例如用火力Twitter的认证。

So far so good. I like how easy it is to enable twitter authentication for example with firebase.

在使用社交网络我从火力点,在firebaseAuthToken和供应商的accessToken回登录。

On login with social network i get back from firebase, the firebaseAuthToken and provider accesstoken.

现在我想用firebaseAuthToken或提供者的访问令牌与我的WebAPI进行身份验证。

Now I want to use firebaseAuthToken or provider access token to authenticate with my WebApi.

现在的问题是:什么是在给定的条件用的WebAPI验证的最好方法

有没有只用火力来存储我的数据,摆脱网页API,因为我已经制定复杂的业务逻辑在服务器上的一个选项。

There is not an option to use only firebase to store my data and get rid of web api since I have in place complex business logic on server.

一个愚蠢的想法,我到目前为止,是对社会提供访问令牌传递给服务器,验证对供应商的令牌,然后使用发出安全令牌Owin -Katana。

One silly idea that i have so far, is to pass the social provider access token to the server, validate the token against provider and then issue a security token using Owin -Katana.

我不使用从卡塔纳社会提供支持建造由于缺少文档,复杂性和单页的应用程序整合不好。我发现SPA太具体的MVC在Visual Studio模板。但是,这是我:)

I'm not using build in social providers support from katana due to lack of documentation, complexity and bad integration with single page apps. I found the visual studio template for SPA too mvc specific. But that's me :)

推荐答案

按照如下步骤看似很长,但它实际上是很容易。我创造了我演示项目,在短短一个小时左右。

tl;dr - Demo Project on GitHub

The steps below may seem long, but it's actually really easy. I created my demo project in just an hour or so.

我同意你关于使用自己和武士刀。我经历过这个过程之前,它是不是一个真正的伟大的经验。使用火力地堡是一个更容易赫克。

I agree with you about using Own and Katana. I've been through that process before and it wasn't really a great experience. Using Firebase was a heck of a lot easier.

这可以全部用JWTs做!

This can all be done with JWTs!

当您完成火力地堡和任何社会提供商进行认证,你会得到一个JSON网络令牌(JWT) - firebaseAuthToken

When you authenticate through Firebase and whatever social provider, you get back a JSON Web Token (JWT) - firebaseAuthToken.

方式JWTs工作,我们有一个秘密令牌和一个客户端令牌。客户端令牌是firebaseAuthToken我们在登录后领取。在火力地堡仪表板为我们生成的秘密令牌。

The way JWTs work is that we have a secret token and a client token. The client token is the firebaseAuthToken we receive after logging in. The secret token is generated for us in the Firebase Dashboard.

我们需要存储此密钥在Web.config所以它更容易稍后访问。

We need to store this secret key in the Web.config so it's easier to access later.

<add key="FirebaseSecret" value="<Firebase-Secret-Token-Goes-Here" />

创建一个行为过滤器,从认证头检查JWT

我们可以验证请求是通过将客户端令牌的Authorization头有效。在服务器上,我们可以存储我们的密钥我们从火力地堡仪表盘得到。当请求是由网络API检查,我们可以去使用JWT库(提供的NuGet )code中的智威汤逊。如果解码成功,那么我们可以检查令牌来确保它没有过期。

Create an Action Filter to check the JWT from the Authorization Header

We can verify the request is valid by passing the client token in the Authorization header. On the server we can store our secret key that we get from our Firebase Dashboard. When the request is checked by Web API we can decode the JWT using a JWT Library (available from NuGet). If the decoding is successful then we can check to token to make sure it isn't expired.

public class DecodeJWT: ActionFilterAttribute 
{

    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext) 
    {
        string firebaseAuthToken = string.Empty;
        if (actionContext.Request.Headers.Authorization != null) {
            firebaseAuthToken = actionContext.Request.Headers.Authorization.Scheme;
        } else {
            throw new HttpException((int) HttpStatusCode.Unauthorized, "Unauthorized");
        }

        string secretKey = WebConfigurationManager.AppSettings["FirebaseSecret"];
        try {
            string jsonPayload = JWT.JsonWebToken.Decode(firebaseAuthToken, secretKey);
            DecodedToken decodedToken = JsonConvert.DeserializeObject < DecodedToken > (jsonPayload);
            // TODO: Check expiry of decoded token
        } catch (JWT.SignatureVerificationException jwtEx) {
            throw new HttpException((int) HttpStatusCode.Unauthorized, "Unauthorized");
        } catch (Exception ex) {
            throw new HttpException((int) HttpStatusCode.Unauthorized, "Unauthorized");
        }

        base.OnActionExecuting(actionContext);
    }

}

创建$ httpInterceptor添加firebaseAuthToken到标题为每个请求

在客户端,诀窍是,令牌每一次传递。为方便起见,我们需要创建一个 $ httpInterceptor 与角上 firebaseAuthToken 检查>的sessionStorage 。

Create a $httpInterceptor add the firebaseAuthToken to the header for every request

On the client, the trick is that the token has to be passed every time. To make this easier we need to create a $httpInterceptor with Angular that checks for a firebaseAuthToken on sessionStorage.

.factory('authInterceptor', function ($rootScope, $q, $window) {
    return {
        request: function (config) {
            config.headers = config.headers || {};
            if ($window.sessionStorage.firebaseAuthToken) {
                config.headers.Authorization = $window.sessionStorage.firebaseAuthToken;
            }
            return config;
        },
        response: function (response) {
            if (response.status === 401) {
                // TODO: User is not authed
            }
            return response || $q.when(response);
        }
    };
})

设置firebaseAuthToken到的sessionStorage在成功登录

每当我们用户登录可以将该值设置为的sessionStorage

$rootScope.$on('$firebaseSimpleLogin:login',
    function (e, user) {

        // add a cookie for the auth token
        if (user) {
            $window.sessionStorage.firebaseAuthToken = user.firebaseAuthToken;
        }

        cb(e, user);
    });

全球注册德codeJWT过滤器

WebApiConfig.cs 注册方法,我们可以设置德codeJWT过滤器适用于所有我们ApiControllers的。

Register the DecodeJWT filter globally

Inside of the WebApiConfig.cs Register method we can set the DecodeJWT filter to apply for all of our ApiControllers.

config.Filters.Add(new DecodeJWT());

现在,每当我们做一个ApiController它会拒绝它,除非有一个有效的智威汤逊的请求。所以经过用户登录我们的数据保存到ApiController,如果它已经不存在了。

Now whenever we make a request to an ApiController it will reject it unless there is a valid JWT. So after a user logs in we can save their data to a ApiController if it already doesn't exist.

// globally uses DecodeJWT
public class UsersController: ApiController 
{
    // POST api/users
    public void Post([FromBody] FbUser user) // See GitHub for this Model
    {
        // Save user if we do not already have it
    }
}

这篇关于SPA - 火力地堡和.Net的WebAPI 2认证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆