ASP.NET身份2.0身份验证对我们自己的承载服务器

问题描述:

所有,ASP.NET身份2.0身份验证对我们自己的承载服务器

我有一个安全的服务器,其唯一目的是从一个端点提供承载令牌:http://example.com/token

请求示例:

POST http://example.com/token HTTP/1.1 
User-Agent: Fiddler 
Content-Type: x-www-form-urlencoded 
Host: example.com 
Content-Length: 73 

grant_type=password&[email protected]&password=examplePassword 

实施例响应:

HTTP/1.1 200 OK 
Cache-Control: no-cache 
Pragma: no-cache 
Content-Type: application/json;charset=UTF-8 
Expires: -1 
Server: Microsoft-IIS/10.0 
X-Powered-By: ASP.NET 
Date: Tue, 16 Aug 2016 12:04:39 GMT 
{ 
    "access_token": "xxxx", 
    "token_type": "bearer", 
    "expires_in": 17999, 
    "refresh_token": "xxxx", 
    ".issued": "Tue, 16 Aug 2016 12:04:38 GMT", 
    ".expires": "Tue, 16 Aug 2016 17:04:38 GMT" 
} 

我们甲肝e使用此端点进行身份验证的角度应用程序,并且这样做很好。

我们正在努力实现但没有成功是创建使用相同的服务器进行身份验证的MVC应用程序,我们希望的代码坐在身份2.0如果可能的顶部。

在我们AccountController(例如项目),我们有我们的Login(LoginModel model)方法,可处理登录和看起来像这样(同示例项目模板):

var result = await _signInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false); 

我们有自己的IUserStore,的UserManager,SignInManager的FPGA实现。

我认为首要的

public Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout) on `SignInManager<,>` and make a web call across to the security server. 

PasswordSignInAsync调用默认实现UserManager.FindByNameAsync但是这将意味着我不得不暴露我的安全服务器上的查找方法来确认用户名存在这确实不听起来不错。

我必须失去了一些东西,我知道这不会是这个复杂的,我们的MVC应用程序需要使用Cookie身份验证,但也保持空头令牌后续调用我们的其他资源服务器。

(我很欣赏这里的技术的问题我可能会被混淆,因此)。

这也在OWIN上运行。

+0

你想要一个新的MVC应用程序使用一个现有的认证服务器的令牌?如果是这样,你希望获得什么优势? –

+0

您的MVC应用程序不需要有一个登录控制器。无论如何,没有人会接受用户名和密码。您的MVC应用程序应该对您的SecurityServer进行身份验证并获取AccessToken,并且您应该在MVC上解密此令牌。如果服务器共享一些属性,这将是可能的。阅读这篇文章的一些更多的信息: http://bitoftech.net/2014/09/24/decouple-owin-authorization-server-resource-server-oauth-2-0-web-api/ – Xavero

+0

不知道我是否让你的问题正确 - *我们试图取得的成功没有太多的成功是创建一个MVC应用程序,它使用相同的服务器进行身份验证* - 是否有可能通过HttpClient从您的AccountController登录操作使用用户名打到安全服务器令牌端点和密码,如果请求被认证,它会自动设置响应cookie中的令牌? – Developer

在这种情况下,我不认为你应该在你的MVC应用程序使用Identity 2.0。您应该创建一个AuthenticationClient打电话给你的验证服务器,你也可以使用这个库来建立这样一个客户端https://www.nuget.org/packages/Thinktecture.IdentityModel.Client/

public class AuthenticationClient { 
    public ClaimsIdentity GetClaimsIdentity(string username, string password) { 
     //Call your authentication server to get your token and also claims associated with your identity. 
     //You can look at an example code how to do it: https://github.com/IdentityServer/IdentityServer3.Samples/blob/master/source/Clients/ConsoleResourceOwnerClient/Program.cs 
     //and create a ClaimsIdentity object out of those information 

     var identity = GetIdentity(); 

     //The key point here is to add AccessToken and RefreshToken as custom claims to your identity so you retrieve these tokens back on subsequent requests. 
     identity.AddClaim(new Claim("access_token", accessToken)); 
     identity.AddClaim(new Claim("refresh_token", refreshToken)); 
    } 
} 

这将满足您的要求:

使用cookie认证也维持熊用于随后调用其他资源服务器的令牌。

LoginAccountController方法应该是这样的:

public ActionResult Login(LoginModel model) 
{ 
    var identity = authenticationClient.GetClaimsIdentity(model.UserName, model.Password); 

    if (identity == null) { 
     return new HttpUnauthorizedResult(); 
    } 
    //Sign in the user 
    var ctx = Request.GetOwinContext(); 
    var authenticationManager = ctx.Authentication; 
    authenticationManager.SignIn(identity); 

    return new HttpStatusCodeResult(HttpStatusCode.OK); 
} 

我假设你已经注册该中间件使用Cookie的身份验证:

public void ConfigureAuth(IAppBuilder app) 
{ 
    app.UseCookieAuthentication(new CookieAuthenticationOptions 
    { 
     AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
     LoginPath = new PathString("/Account/Login") 
    }); 
} 

现在对于所有后续请求,您可以取回访问令牌以从您的ClaimsIdentity调用资源服务器:

User.Identity.Claims.FirstOrDefault(x => x.Type == "access_token");