The Web API v2用户认证模板提供了流行的应用用户认证场景,如.使用本地帐号的用户名密码认账 (包括创建用户、设置和修改密码)以及使用第三方的认证方式,如facebook,google等等– 在本地中包含了外部帐号的连接 所有的这些均通过使用一个OAuth2认证服务进行.
To make all that happen the template combines quite a bit of new stuff together: OWIN, Katana authentication middleware, ASP.NET identity, OAuth2 and a bunch of new authentication related attributes…and I must admit figuring out exactly what’s going on was a bit of a challenge. Two quotes constantly came to mind while digging through the source code and writing down my notes. One was: complexity is the natural enemy of security – and the other one was: shit’s hard. So enjoy.
为了实现这些,模板集合了一些技术:OWIN、Katana认证中间件、ASP.NET 标识、OAuth2以及一些新的与认证相关的特性…,必须指出这是一个挑战.
In this post I want to focus on the general setup of the Katana authentication middleware, the following posts will deal with the local account features and the external authentication.
In Katana, every authentication middleware “registers” itself with the system. For that it needs a “name” – or technically speaking an AuthenticationType. Using that name, some code like a framework can call into the authentication component. This is done using theIAuthenticationManager interface which hangs off the Authentication property on theOwinContext. It features methods like SignIn, SignOut, AuthenticateAsync or Challenge. Each of these methods require an AuthenticationType as a hint which middleware will do the actual work.
在Katana中,每个认证中间件将自己注册到系统中,因此它需要一个名字,或从技术上称之为一个认证类型。使用这个名字,代码会想一个框架一样可以调用认证组件。使用IAuthenticationManager 接口在OwinContext中处理认证的属性,方法如:SignIn,SignOut,AuthenticateAsync 或Challenge。每个方法需要哦一个认证类型作为指示其如何具体工作。
One built-in mechanism that uses the authentication manager is the newHostAuthenticationFilter in Web API v2 – will come to that later. Let’s first have a look which authentication middleware gets actually wired up (see also Startup.Auth.cs).
一个内建的机制使用认证管理器,在Web API V2中是newHostAuthenticationFilter。我们首先看认证中间件是如何连接的(参照Startup.Auth.cs)。
For the implicit flow and the interaction with Google and friends, “browser tech” is needed (think web views in native apps, or the browser itself for JS) – this is where cookies come in:
在隐式流程和与Google和朋友互动时,需要前端技术的支持(考虑本地App的Web页面或者浏览器的JS),即就是使用Cookie。
app.UseCookieAuthentication(new CookieAuthenticationOptions());
This call adds supports for classic cookie based authentication. The authentication type is simply called Cookies or in code the middleware is referenced usingCookieAuthenticationDefaults.AuthenticationType.
这个调用将增加对基于经典Cookie认证的支持。认证类型简单的被称之为Cookies或这在中间件中使用usingCookieAuthenticationDefaults.AuthenticationType.
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
The second cookie middleware registers itself as ExternalCookie (or DefaultAuthenticationTypes.ExternalCookie). This cookie is used to temporarily store information about a user logging in with a third party login provider
这个Cookie中间件将其自身作为一个ExternalCookie(或DefaultAuthenticationTypes.ExternalCookie)注册到系统中。这个Cookie被用在为使用第三方登录提供方的临时存储用户登录信息。
Further there is one authentication middleware registered for every external login provider you want to support (authentication types: Google, Facebook, Twitter and Microsoft):
你需要为想支持的每个外部登录提供方注册一个认证中间件(认证类型:Google、Facebook、Twitter以及微软):
app.UseFacebookAuthentication(appId: “178…455″,appSecret: “f43…f”);
app.UseGoogleAuthentication();
OK – next up is all the plumbing to support token-based authentication – we need a token producer and consumer. This is all hidden behind the following line of code:
好了,接下来是对基于令牌认证的支持,我们需要一个令牌生产者和消费者。这些都会被隐藏在下面代码的中执行:
app.UseOAuthBearerTokens(OAuthOptions);
This extension method actually registers three middlewares behind the covers:
这个扩展方法实际上注册了三个中间件:
- OAuth2 authorization server to deal with resource owner flow and implicit flow token requests. Application specific logic is encapsulated in theApplicationOAuthProviderclass which we’ll have a closer look in the next post.
OAuth2认证服务器来处理资源所有者流程以及隐式令牌获取流程。应用程序指定包装ApplicationOAuthProviderclass 的逻辑,在下篇中我们会详细的探讨。
- Token-based authentication for local accounts using an authentication type of Bearer(or OAuthDefault.AuthenticationType). This middleware only accepts claims where the issuer has been set to LOCAL AUTHORITY.
为本地帐号进行基于令牌的认证使用一种认证类型为Bearer的认证(或OAuthDefault.AuthenticationType)。这个中间件只接受发行人被设置为本地权限的claims(声明)
- Token-based authentication for external accounts (resulting from an authentication handshake with an external login provider). It uses an authentication type ofExternalBearer (or DefaultAuthenticationTypes.ExternalBearer) and only accepts claims where the issuer is not LOCAL AUTHORITY (important technical detail – keep that in the back of your mind).
对外部账户进行的基于令牌的认证(结果来自一个与外部登录提供者的认证握手)。他使用认证类型为ofExternalBearer (或DefaultAuthenticationTypes.ExternalBearer)并只接受发行人不是本地认证的声明(重要的技术细节)
With that setup you can now control which authentication type is required to access which parts of the API surface – let me give you some examples:
有了这些步骤,现在你便可以控制需要的认证类型来访问API,例如
In general Web API requires token-based authentication using local accounts (Bearer). This is why you find the following two lines of code in WebApiConfig.cs:
一般WebApi需要使用本地帐号(Bearer)基于令牌的认证。这是为什么需要在WebApiConfig.cs 文件中找到下面两行代码:
config.SuppressDefaultHostAuthentication();
config.Filters.Add(
new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
Let’s say you’d want to also accept tokens resulting from external authentication – but require an authenticated principal, the following would work (e.g. on a controller or action):
你也可以从外部认证获取令牌,但是需要一个认证原则,下面的代码便可以工作(如一个控制器或动作)
[Authorize]
[HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
If you want to override the global setting and only accept an application cookie if present (a technique used in the account controller – more on that in the next post) – you could do this:
如果你想覆盖全局配置并只允许一个应用程序的Cookie,你可以这样做:
[OverrideAuthentication]
[HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)]
[AllowAnonymous]