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

本文关键字:服务器 身份验证 自己的 我们自己 Identity NET 0针 我们 ASP | 更新日期: 2023-09-27 18:02:40

全部,

我有一个安全服务器,其唯一目的是从单个端点提供承载令牌: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&username=example@example.com&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"
}

我们有一个角度应用程序,它使用这个端点进行身份验证,而且做得很好。

我们试图实现的是创建一个使用同一服务器进行身份验证的MVC应用程序,但没有取得多大成功,如果可能的话,我们希望代码位于Identity 2.0之上。

在我们的AccountController(示例项目(中,我们有一个Login(LoginModel model)方法,它处理登录,看起来像这样(与示例项目模板相同(:

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

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

我考虑过推翻

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身份验证,但也需要维护bear令牌,以便后续调用我们的其他资源服务器。

(我很感激我可能在这里混淆了技术,因此提出了这个问题(。

这也在OWIN上运行。

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

在这种情况下,我认为您不应该在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身份验证,但也要维护bear令牌,以便后续调用我们的其他资源服务器。

AccountController上的Login方法应该是这样的:

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");
相关文章: