回答

1

令牌只是持有索赔,它只是用来验证到资源。如果其中一项索赔持有用户信息,您可以创建一个身份并向其分配索赔。

public void ValidateBearerToken(OwinContext context) 
{ 
    try 
    { 
     var tokenHandler = new JwtSecurityTokenHandler(); 
     byte[] securityKey = GetBytes("some key"); //this should come from a config file 

     SecurityToken securityToken; 

     var validationParameters = new TokenValidationParameters() 
     { 
      ValidAudience = "http://localhost:2000", 
      IssuerSigningToken = new BinarySecretSecurityToken(securityKey), 
      ValidIssuer = "Self" 
     }; 

     var auth = context.Request.Headers["Authorization"]; 

     if (!string.IsNullOrWhiteSpace(auth) && auth.Contains("Bearer")) 
     { 
      var token = auth.Split(' ')[1]; 

      var principal = tokenHandler.ValidateToken(token, validationParameters, out securityToken); 

      context.Request.User = principal; 
     } 
    } 
    catch (Exception ex) 
    { 
     var message = ex.Message; 
    } 
} 
+0

您可以在此扩展吗?我如何从字符串(原始令牌)去提取信息。 – Aziz

+0

这将验证您的令牌并设置声明原则。然后,您只需向pricinple.Claims列表添加声明即可。 –

+0

我正在使用SimpleAuthorizationServerProvider:OAuthAuthorizationServerProvider而不是Jwt安全性令牌 – Aziz

1

首先,您需要创建一些基于令牌的声明,然后创建ClaimsIdentity并使用它来授权用户。

public ActionResoult Login(string token) 
{ 
    if(_tokenManager.IsValid(token))   
    { 
     // optionally you have own user manager which returns roles and user name from token 
     // no matter how you store users and roles 
     var user=_myUserManager.GetUserRoles(token); 

     // user is valid, going to authenticate user for my App 
     var ident = new ClaimsIdentity(
      new[] 
      { 
       // adding following 2 claim just for supporting default antiforgery provider 
       new Claim(ClaimTypes.NameIdentifier, token), 
       new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"), 

       // an optional claim you could omit this 
       new Claim(ClaimTypes.Name, user.Username), 

       // populate assigned user's role form your DB 
       // and add each one as a claim 
       new Claim(ClaimTypes.Role, user.Roles[0]), 
       new Claim(ClaimTypes.Role, user.Roles[1]), 
       // and so on 
      }, 
      DefaultAuthenticationTypes.ApplicationCookie); 

     // Identity is sign in user based on claim don't matter 
     // how you generated it    
     HttpContext.GetOwinContext().Authentication.SignIn(
      new AuthenticationProperties { IsPersistent = false }, ident); 

     // auth is succeed, just from a token 
     return RedirectToAction("MyAction"); 
    } 
    // invalid user   
    ModelState.AddModelError("", "We could not authorize you :("); 
    return View(); 
} 

现在你可以使用Authorize过滤器,以及:

[Authorize] 
public ActionResult Foo() 
{ 
} 

// since we injected user roles to Identity we could do this as well 
[Authorize(Roles="admin")] 
public ActionResult Foo() 
{ 
    // since we injected our authentication mechanism to Identity pipeline 
    // we have access current user principal by calling also 
    // HttpContext.User 
} 

而且我鼓励你有看Token Based Authentication Sample从我的github回购是一个非常简单的工作示例。

+0

没有_myUserManager.GetUserRoles(token); ...方法。我正在使用公共类SimpleAuthorizationServerProvider:OAuthAuthorizationServerProvider - 这有帮助吗? – Aziz

+0

'_myUserManager'就是一个例子。展示如何使用自己的类来生成声明并基于用户登录。在这个例子中,我使用'_myUserManager'来提取当前用户角色,你可以实现你自己的类。用户名和角色只是简单字符串。如果您没有用户名或角色,可选。如果你看看我的github回购,你可以看到我只用一个字符串来授权用户。 –

+0

我没有当前的用户上下文。我需要从字符串令牌转到用户。我需要知道_myUserManager.GetUserRoles(token)里面的locic; – Aziz