c# - 从 Web API 中的 Controller 返回由 OAuthAuthorizatioServer 生成的 JWT token

标签 c# asp.net asp.net-identity .net-4.5

在@Taiseer Joudeh 之后,我能够创建简单的 Web API POC。当我将 JWT token 添加到 header 时,我能够创建新帐户,然后登录并调用安全 Web API。

我想修改负责创建账户的方法。
现在我正在返回带有新用户对象的创建 (201) 代码,但我想返回访问 token 。

我找到了 similar question但它需要创建 HttpClient 并向 OAuthAuthorizatioServer TokenEndpointPath 发出请求。

Second question我发现需要生成返回给前端的临时 token ,但随后前端必须向服务器发出额外请求以获取“真实” token 。

我想做的是在创建用户帐户时返回登录响应(access_token、token_type 和 expires_in)。 我希望在创建用户帐户时对用户进行身份验证。

我只使用 Web API 和 JWT,没有任何 cookie。

编辑:我的临时解决方案:
创建用户后我这样做:

var validTime = new TimeSpan(0, 0, 0, 10);
var identity = await UserManager.CreateIdentityAsync(user, "JWT");
var jwtFormat = new CustomJwtFormat(ApplicationConfiguration.Issuer);
var authenticationProperties = new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow, ExpiresUtc = DateTimeOffset.UtcNow.Add(validTime) };
var authenticationTicket = new AuthenticationTicket(identity, authenticationProperties);
var token = jwtFormat.Protect(authenticationTicket);

var response = new
{
    access_token = token,
    token_type = "bearer",
    expires_in = validTime.TotalSeconds.ToInt()
};

return Ok(response);

CustomJwtFormat 来自 this awesome article .

最佳答案

下面是一些类似于我在我的应用程序中所做的代码,它使用的是 Asp.Net Core 1.0。如果您不使用 Core 1.0,您的登录和用户注册将有所不同。

public async Task<string> CreateUser(string username, string password)
    {
        string jwt = String.Empty;

        if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
        {
            Response.StatusCode = (int)HttpStatusCode.BadRequest;
        }

        var user = await _userManager.FindByNameAsync(username);
        if (user == null) // user doesn't exist, create user
        {
            var newUser = await _userManager.CreateAsync(new ApplicationUser() { UserName = username }, password); 
            if (newUser.Succeeded) //user was successfully created, sign in user
            {
                user = await _userManager.FindByNameAsync(username);
                var signInResult = await _signInManager.PasswordSignInAsync(user, password, false, true);
                if (signInResult.Succeeded) //user signed in, create a JWT
                {
                    var tokenHandler = new JwtSecurityTokenHandler();
                    List<Claim> userClaims = new List<Claim>();

                    //add any claims to the userClaims collection that you want to be part of the JWT
                    //...

                    ClaimsIdentity identity = new ClaimsIdentity(new GenericIdentity(user.UserName, "TokenAuth"), userClaims);
                    DateTime expires = DateTime.Now.AddMinutes(30); //or whatever

                    var securityToken = tokenHandler.CreateToken(
                        issuer: _tokenOptions.Issuer,  //_tokenAuthOptions is a class that holds the issuer, audience, and RSA security key
                        audience: _tokenOptions.Audience,
                        subject: identity,
                        notBefore: DateTime.Now,
                        expires: expires,
                        signingCredentials: _tokenOptions.SigningCredentials
                        );

                    jwt = tokenHandler.WriteToken(securityToken);
                    Response.StatusCode = (int)HttpStatusCode.Created;
                    await _signInManager.SignOutAsync(); //sign the user out, which deletes the cookie that gets added if you are using Identity.  It's not needed as security is based on the JWT
                }
            }
            //handle other cases...
        }
    }

基本上,用户会被创建并自动登录。然后我构建了一个 JWT(添加你想要的任何声明)并将其返回到响应正文中。在客户端(MVC 和 Angular JS),我从响应主体中获取 JWT 并将其存储。然后在每个后续请求的 Authorization header 中将其传回服务器。所有服务器操作的授权策略都基于 JWT 提供的一组声明。没有 cookie,服务器上没有状态。

编辑:我想您甚至不需要在此过程中调用 signIn 方法,因为您只需创建用户、创建 JWT 并返回 JWT。当用户根据 future 的请求登录时,您将使用登录、创建 token 、注销方法。

关于c# - 从 Web API 中的 Controller 返回由 OAuthAuthorizatioServer 生成的 JWT token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36864330/

相关文章:

c# - 尝试使用 WebMatrix 从 sql server ce 数据库中动态删除一行时出错

c# - 按货币值(value)排序列表

c# - Asp.Net (c#) - 读取 Excel 工作表

c# - 是否可以计算回发中的按钮点击次数

c# - MVC5 从登录到 Web 应用程序的用户那里获取 UserID

c# - 如何将图像设置为图表轴或沿图表轴设置?

c# - Xamarin.Forms 目标框架 (Kitkat) 问题

c# - 来自 Windows 窗体应用程序的 ASP.NET 身份验证

c# - ASP.NET Identity 2.0 Roles.IsUserInRole 给出 {"Invalid object name ' dbo.aspnet_SchemaVersions'."} 异常

asp.net-mvc - 失败的 claim 给出 500 而不是 403