![](/img/trans.png)
[英]How to implement claims-based authentication using Identity 2.0 in Asp.net MVC
[英]ASP.NET MVC+API and WCF with claims-based authorization and authentication against a custom DB and active directory
我們正在開發兩個(新的)ASP.NET 應用程序,它們使用 MVC/Razor 視圖作為模板引擎來處理 I18N/L10N(當前文化存儲在每個請求的 cookie 中並從中檢索;文本從資源)。
這兩個應用程序通過托管在與 MVC 應用程序相同的 ASP.NET 應用程序中的單獨 WebApis 使用相同的 WCF 服務。 API 和由基於 Web 的應用程序 (HTML/JS) 訪問。
應用程序A當前使用表單身份驗證(WCF 服務根據我們的應用程序數據庫驗證用戶憑據),應用程序B使用 Windows 身份驗證。
TL;DR 摘要:我們需要了解 WCF 服務中有關 Web 用戶的信息。
我們需要:
到目前為止,我對此的想法和印象是:
到目前為止,我有:
app.UseCookieAuthentication
和app.UseIdentityServerBearerTokenAuthentication
來設置身份驗證,但我不太確定這到底意味着什么,所以我現在不太滿意。TokenClient.RequestResourceOwnerPasswordAsync(username, password, scopes)
從 IdentityServer 請求一個(訪問?)令牌,嘗試通過訪問用戶信息來構建ClaimsIdentity
? 端點並通過Request.GetOwinContext().Authentication.SignIn(id);
設置 cookie Request.GetOwinContext().Authentication.SignIn(id);
.我沒有的:
UseIdentityServerBearerTokenAuthentication
、 UseOpenIdConnectAuthentication
等)實際上做了什么,應該如何以及何時使用它們以及具有什么安全隱患。wS2007FederationHttpBinding
作用和用途,或者我必須在Startup.cs
配置的內容以及需要在web.config
或其他地方配置的內容基本上,我已經閱讀了太多關於 WCF、WIF 等的信息,以至於我不清楚當前的信息是什么、最佳實踐是什么以及我如何實施符合我們所有要求的東西。 IdentityServer 中的示例並沒有真正幫助我,因為對我來說,它們沒有解釋任何內容。
對此的任何幫助將不勝感激,即使您只是幫助我更好地理解術語和技術。
PS:我們正在運行 .NET 4.6
更新:我設法從 IdentityServer 檢索令牌並查詢 userinfo 端點以獲取聲明。 結果我使用了ClaimTypes.Email
等而不是Constants.ClaimTypes.Email
- 同樣只有身份范圍會在 userinfo 端點上產生聲明,我在我的資源范圍內指定了它們。
我的下一步是試圖弄清楚UseIdentityServerBearerTokenAuthentication
如何阻止我訪問任何東西,以及如果我刪除任何必需的范圍,為什么它不會......
更新: (2015-12-01) 我目前正在嘗試以某種方式透明地將令牌傳輸到 WCF 服務,並根據令牌提供當前委托人(或聲明委托人)。 我還沒有明確的方法來實現這一目標。
MVC 和 WebApi 的東西現在似乎工作正常:
MVC 應用程序使用 OWIN cookie 中間件進行保護 - 在使用表單身份驗證的登錄時,我使用TokenClient
和資源所有者密碼憑據流。 然后我查詢userinfo
(通過UserInfoClient
)和introspection
(通過IntrospectionClient
)端點來構建聲明,創建一個ClaimsIdentity
並將其保存在 cookie 中。 我還將訪問令牌保存為聲明。
var id = new ClaimsIdentity(listOfClaims, "Cookies");
this.Request.GetOwinContext().Authentication.SignIn(id);
陷阱:內省端點需要作為范圍而不是客戶端進行身份驗證 - 這在示例中有點誤導,其中客戶端和范圍具有相同的名稱
為了驗證每個請求上的令牌,我將CookieAuthenticationOptions
的Provider
配置為一個new CookieAuthenticationProvider()
,我在OnValidateIdentity
期間查詢 IdentityServer 的內省端點:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
LoginPath = new PathString("/User/Login"),
LogoutPath = new PathString("/User/Logoff"),
// setup more options etc..
Provider = new CookieAuthenticationProvider()
{
OnValidateIdentity = async context =>
{
// validate etc. - and if it fails call: context.RejectIdentity();
}
}
}
通過擴展用於設置Register(HttpConfiguration config)
的Register(HttpConfiguration config)
, Register(HttpConfiguration config)
與 cookie 身份驗證分離:
// prevent use of owin cookie auth
config.SuppressDefaultHostAuthentication();
// need bearer token auth
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
此外,我已經在 owin 啟動中設置了IdentityServerBearerTokenAuthentication
(基本上,這是我對 WebApi 所做的唯一事情,因為我有幾個通往多個 API 的路由,並且無法通過 Ninject 設置具有依賴項注入的多個地圖......)。
app.Map(
"/api",
inner =>
{
inner.UseIdentityServerBearerTokenAuthentication(identityServerBearerTokenAuthenticationOptions);
});
當然,僅憑這一點就意味着 angular 應用程序將無法獲取任何數據 - 因此在單頁應用程序視圖中,我將令牌作為常量注入到配置中,並通過配置$httpProvider
設置默認標頭:
看法:
<script type="text/javascript">
angular.module("myApp").constant("authorizationHeader", "Bearer @Model");
</script>
應用程序:
myApp.config(["$httpProvider", "authorizationHeader", function ($httpProvider, authorizationHeader) {
$httpProvider.defaults.headers.common["Authorization"] = authorizationHeader;
}]);
...所以我現在唯一的問題幾乎是如何將令牌傳輸到 WCF 服務以及如何從該服務上的令牌設置聲明標識(無需明確地這樣做 - 即我不想要一個單獨的我的合同上的參數)
PS:我只能在app.config
配置 WCF 服務,因為我們使用的是自托管 WCF 服務和 Ninject ...
2015-12-10更新成功!
我將參考令牌傳輸到 WCF 服務,類似於 Dominick Baier 建議的做法: http : //leastprivilege.com/2015/07/02/give-your-wcf-security-architecture-a-makeover-with-identityserver3/
本質上這歸結為:
Claim
在新ClaimsIdentity
SecurityTokenDescriptor
Saml2SecurityTokenHandler
包裝GenericXmlSecurityToken
this.ChannelFactory.CreateChannelWithIssuedToken(xmlToken);
創建頻道this.ChannelFactory.CreateChannelWithIssuedToken(xmlToken);
(提示:緩存ChannelFactory
而不是Channel
) 這意味着我必須將綁定更改為ws2007FederationHttpBinding
,將所有 url 更改為使用https
和44300
到44399
范圍內的端口在本地主機上進行開發(因為 Windows 已經為這些端口預配置了證書和訪問控制列表 - 對於部署,您必須添加您的證書並允許 WCF 主機用戶在那里托管 HTTP/SSL 服務)。 如果任何元數據端點可見,那么它們也必須使用 HTTPS( binding="mexHttpsBinding"
和<serviceMetadata httpGetEnabled="false" />
)
為了使用該綁定,安全性必須是TransportWithMessageCredentials
。
在 WCF 端,我刪除了所有SecurityTokenHandler
並添加了我自己的,它解開引用令牌並使用來自 IdentityServer 的introspection
端點來構建身份(與來自 IdentityServer 的示例非常相似)。
這可以在代碼或 app.config 中完成( ServiceCommunication
是我保存所有這些東西的程序集):
<configSections>
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</configSections>
<system.identityModel>
<identityConfiguration name="identity">
<securityTokenHandlers>
<clear />
<add type="ServiceCommunication.Authentication.IdentityServerWrappedReferenceTokenHandler, ServiceCommunication" />
</securityTokenHandlers>
<claimsAuthorizationManager type="ServiceCommunication.Authorization.ClaimsAuthorizationManager, ServiceCommunication"/>
</identityConfiguration>
對於授權,我定義了自己的ClaimsAuthorizationManager
,它處理覆蓋的CheckAccess
方法中的所有內容。 注意:每個 WCF 合約方法也會調用該方法。
授權可以在經由任何明碼ClaimsPrincipalPermissionAttribute
或通過顯式ClaimsPrincipalPermission
。 甚至不必是 WCF。 在 .NET 4.5 中開箱即用
我在 WCF 服務和 MVC/API 控制器操作中盡可能深入地使用ClaimsPrincipalPermissionAttribute
。
現在我已經對所有用戶進行了身份驗證,防止訪問未經身份驗證的用戶(重定向到登錄)並保證只有授權用戶才能訪問特定方法。 :)
所以我終於解決了這一切:
app.UseCookieAuthentication
和我自己的CookieAuthenticationProvider
來驗證 MVC 中的引用令牌並像以前的表單身份驗證一樣處理登錄app.UseIdentityServerBearerTokenAuthentication
(每個 http 請求必須設置一個標頭Authorize
和值Bearer your-token-here
,大多數 JS 框架允許你全局設置)。 身份驗證針對 IdentityServer,我已經配置了 ClientId 和 ClientSecret(實際上是 ScopeId 和 ScopeSecret),以便它使用自省端點。 當心:您只會獲得該特定范圍的聲明,而不會獲得其他范圍的聲明。IdentityModel
客戶端進行身份驗證和驗證(並從用戶信息和自省端點獲取聲明)Ws2007FederationHttpBinding
和TransportWithMessageCredentials
安全性包裝的引用或 jwt 令牌SecurityTokenHandler
解開該令牌並驗證它(並設置身份/主體)ClaimsAuthorizationManager
通過ClaimsPrincipalPermission
( Attribute
) 進行授權OAuth2 和 OpenID Connect 等新的 Internet 安全協議不能很好地與 WCF SOAP 服務配合使用。
使用 OAuth2 和 OpenID Connect 協議時,授權服務器會發出 JWT 令牌。 但是,當您使用WS2007FederationHttpBinding
時,您的 SOAP WCF 服務需要信封標頭中的 SAML 令牌。 IndentityServer 不發布 SAML 令牌。
雖然可以使用來自 JWT 令牌的聲明來發布和簽署您自己的 SAML 令牌,但將 WCF SOAP 服務替換為基於 REST 的服務可能更容易,該服務在Authorization
標頭中需要 JWT 令牌。
我不確定您為什么要使用資源所有者密碼憑據流。 您可能需要考慮將 IdentityServer 與現有數據庫一起使用,並改用身份驗證代碼流。
PS IdentityServer和Katana (Microsoft 的 OWIN 實現)都是開源的,因此您可以弄清楚所有這些代碼實際上在做什么。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.