微服务安全 [英] Micro service security

查看:348
本文介绍了微服务安全的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去的几天我一直在玩微服务模式,一切都进展顺利,但安全性似乎难不倒我。

Over the last few days I've been playing with the micro service pattern and all is going well but security seems to baffle me.

<击>
所以如果我可以问一个问题:
如何处理对个人服务的用户身份验证?目前,我传递给网关API 这反过来连接到服务的请求。

So If I may ask a question: How do I handle user authentication on an individual service? At the moment I pass a request to the Gateway API which in turns connects to the service.

问编辑请参考下面

铭记各个服务不应该知道对方。在网关是聚合本身。

Bearing in mind that the individual services should not know about each other. The Gateway is the aggregator as such.

当前架构

一个小代码模拟了请求:

A little code to simulate the request:

前端 - 客户端应用

public class EntityRepository<T>
{
    private IGateway _gateway = null;
    public EntityRepository(IGateway gateway)
    {
        this._gateway = gateway;
    }
    public IEnumerable<T> FindAll()
    {
        return this._gateway.Get(typeof(T)).Content.ReadAsAsync<IEnumerable<T>>().Result;
    }
    public T FindById(int id)
    {
        return this._gateway.Get(typeof(T)).Content.ReadAsAsync<T>().Result;
    }
    public void Add(T obj)
    {
        this._gateway.Post(typeof(T), obj);
    }
    public void Update(T obj)
    {
        this._gateway.Post(typeof(T), obj);
    }
    public void Save(T obj)
    {
        this._gateway.Post(typeof(T), obj);
    }
}


   //Logic lives elsewhere
   public HttpResponseMessage Get(Type type)
   {
      return Connect().GetAsync(Path(type)).Result;
   }
   public HttpResponseMessage Post(Type type, dynamic obj)
   {
      return Connect().PostAsync(Path(type), obj);
   }
    private string Path(Type type)
    {
        var className = type.Name;
        return "api/service/" + Application.Key + "/" + className;
    }
    private HttpClient Connect()
    {
        var client = new HttpClient();
        client.BaseAddress = new Uri("X");

        // Add an Accept header for JSON format.
         client.DefaultRequestHeaders.Accept.Add(
         new MediaTypeWithQualityHeaderValue("application/json"));

        return client;
    }



我使用泛型,以确定它需要火,一旦它击中的网关。
因此,如果键入类别将火在类别服务并进而呼吁:

I use generics to determine where it needs to fire once it hit's the gateway. So if the Type is Category it will fire the Category service thus calling:

public IEnumerable<dynamic> FindAll(string appKey, string cls)
{
    var response = ConnectTo.Service(appKey, cls);
    return (appKey == Application.Key) ? (response.IsSuccessStatusCode) ? response.Content.ReadAsAsync<IEnumerable<dynamic>>().Result : null : null;
}



网关不包含物理文件/文件类型的类的。

The Gateway does not contain the physical files/Class's of the types.

一些代码后,我希望有人可以给我一些示范或处理与当前架构的安全性/用户认证的最佳方法。

After a little code, I was hoping someone could give me a little demonstration or the best approach to handle security/user authentication with the current architecture.

案例情景1
用户点击在Web应用程序和日志,在这一点上用户加密的电子邮件和密码发送到网关API ,然后传递到用户服务并决定用户是否经过验证 - 一切都很好,但现在我想获取所有信息从消息服务用户已收到。我无法在网关真说,如果用户通过验证,获取信息,因为不解决呼叫问题的消息服务之外网关API

Case Scenario 1 User hits the web app and logs in, at that point the users encrypted email and password is sent to the Gateway API which is then passed to the User Service and decides whether the user is authenticated - all well and good but now I want to fetch all Messages from the Message Service that the user has received. I cannot really say in the Gateway if the user is authenticated, fetch the messages because that does not solve the issue of calling the Message Service outside of the Gateway API

我也可以不加验证每一个人服务,因为这需要谈话的用户都各自服务。服务和击败模式的目的

I also cannot add authentication to each individual service because that would require all respective services talking to the User Service and that defeats the purpose of the pattern.

修正:
只允许网关调用服务。请求外部网关应阻止的服务。

Fixes: Only allow the Gateway to call the Services. Requests to services outside of the Gateway should be blocked.

我知道安全性是一个广泛的话题,但在当前背景下,我希望有人能告诉我最好的行动方针来解决问题。

I know security is a broad topic but within the current context, I'm hoping someone could direct me with the best course of action to resolve the issue.

目前我已经全部关闭应用程序,它在硬编码一个的Guid 如果应用程序是平等反过来获取数据。

Currently I have Hardcoded a Guid in all off the applications, which in turn fetches data if the app is equal.

推荐答案

修改

Edit

这个答案是对网关< - >科技的服务,沟通。用户当然应该正确验证当与网关应用会谈

结束编辑

end edit

首先,微服务不应从互联网可到达的。它们应该只从网关(可群集)进行访问。

First of all, the micro services should not be reachable from internet. They should only be accessible from the gateway (which can be clustered).

其次,你需要能够识别当前用户。你可以通过在用户ID 作为HTTP头做。创建的WebAPI过滤器,它采用了头,并从它创建一个自定义的的IPrincipal

Second, you do need to be able to identify the current user. You can do it by passing the UserId as a HTTP header. Create a WebApi filter which takes that header and creates a custom IPrincipal from it.

最后,你需要一些方法来确保该请求来自网关或另一个微服务。一个简单的方法是在一个令牌使用HMAC认证。

Finally you need some way to make sure that the request comes from the gateway or another micro service. An easy way to do that is to use HMAC authentication on a token.

存储在的web.config 为每个服务和网关的关键。然后,只需发送与每个请求令牌(你可以使用的WebAPI认证过滤器认证)

Store the key in the web.config for each service and the gateway. Then just send a token with each request (which you can authenticate using a WebApi authentication filter)

要生成一个散列,使用 HMACSHA256 在.NET类:

To generate a hash, use the HMACSHA256 class in .NET:

private static string CreateToken(string message, string secret)
{
    secret = secret ?? "";
    var keyByte = Encoding.ASCII.GetBytes(secret);
    var messageBytes = Encoding.ASCII.GetBytes(message);
    using (var hasher = new HMACSHA256(keyByte))
    {
        var hashmessage = hasher.ComputeHash(messageBytes);
        return Convert.ToBase64String(hashmessage);
    }
}



因此,在你的 MicroServiceClient 你会做这样的事情:

var hash = CreateToken(userId.ToString(), mySharedSecret);
var myHttpRequest = HttpRequest.Create("yourUrl");
myHttpRequest.AddHeader("UserId", userId);
myHttpRequest.AddHeader("UserIdToken", hash);
//send request..

和在微服务,你创建了一个过滤器:

And in the micro service you create a filter like:

public class TokenAuthenticationFilterAttribute : Attribute, IAuthenticationFilter
{
    protected string SharedSecret
    {
        get { return ConfigurationManager.AppSettings["SharedSecret"]; }
    }

    public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
    {
        await Task.Run(() =>
        {
            var userId = context.Request.Headers.GetValues("UserId").FirstOrDefault();
            if (userId == null)
            {
                context.ErrorResult = new StatusCodeResult(HttpStatusCode.Forbidden, context.Request);
                return;
            }

            var userIdToken = context.Request.Headers.GetValues("UserIdToken").FirstOrDefault();
            if (userIdToken == null)
            {
                context.ErrorResult = new StatusCodeResult(HttpStatusCode.Forbidden, context.Request);
                return;
            }

            var token = CreateToken(userId, SharedSecret);
            if (token != userIdToken)
            {
                context.ErrorResult = new StatusCodeResult(HttpStatusCode.Forbidden, context.Request);
                return;
            }


            var principal = new GenericPrincipal(new GenericIdentity(userId, "CustomIdentification"),
                new[] {"ServiceRole"});
            context.Principal = principal;
        });
    }

    public async Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
    {
    }

    public bool AllowMultiple
    {
        get { return false; }
    }

    private static string CreateToken(string message, string secret)
    {
        secret = secret ?? "";
        var keyByte = Encoding.ASCII.GetBytes(secret);
        var messageBytes = Encoding.ASCII.GetBytes(message);
        using (var hasher = new HMACSHA256(keyByte))
        {
            var hashmessage = hasher.ComputeHash(messageBytes);
            return Convert.ToBase64String(hashmessage);
        }
    }
}

这篇关于微服务安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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