我在我的asp核心网络api中使用IdentityServer4进行用户身份验证和授权.我在android应用程序中使用此api.我的用户使用用户名和密码注册和登录没有问题.这是我的访问令牌我来自连接/令牌端点
I'm using IdentityServer4 for user authentication and authorization in my asp core web api.I use this api in android application.My users Signup and Login with username and password with no problem .And here is my access token that I got from connect/token endpoint
{ "alg": "RS512", "typ": "at+jwt" } { "nbf": 1600324303, "exp": 1631860303, "iss": "myIdentityServerApi", "aud": [ "IdentityServerApi", "MyAPI1" ], "client_id": "MyApp1", "sub": "521d198c-3657-488e-997e-3e50d756b353", "auth_time": 1600324302, "idp": "local", "role": "Admin", "name": "myusername", "scope": [ "openid", "IdentityServerApi", "MyAPI1" ], "amr": [ "pwd" ] }现在,在新的android应用程序中,我希望用户使用电话号码和短信激活功能进行注册和登录. 当用户发送ActivationCode时,我应该向他发送访问令牌.但是,如何在没有用户名和密码的情况下从令牌端点获取令牌?
Now in my new android application I want users signup and login with phone number and sms activation. When User send the ActivationCode I should send him access token.But how can I get token from token endpoint without username and password?
在下面,我想手动生成令牌,但是生成的令牌不起作用.
In below I wanted to generate token manually.but generated token don't work.
[HttpPost("Activate")] [AllowAnonymous] public async Task<IActionResult> Activate([FromBody] SignUpPhoneModel model) { if (string.IsNullOrWhiteSpace(model.PhoneNumber)) { return BadRequest("Phone Number is Empty"); } PhoneValidation pv = new PhoneValidation(); IdentityUser CurrentUser = await db.Users.Where(e => e.PhoneNumber == model.PhoneNumber).FirstAsync(); if (!await UserManager.VerifyChangePhoneNumberTokenAsync(CurrentUser, model.ActivationCode, model.PhoneNumber)) { return BadRequest("Activation Code is not correct"); } else { //Here user is activated and should get token But How? CurrentUser.PhoneNumberConfirmed = true; List<string> UserRoles = (await UserManager.GetRolesAsync(CurrentUser)).ToList(); var tokenHandler = new JwtSecurityTokenHandler(); RSACryptoServiceProvider rsap = new RSACryptoServiceProvider(KeyContainerNameForSigning); SecurityKey sk = new RsaSecurityKey(rsap.Engine); List<Claim> UserClaims = new List<Claim>() { new Claim(JwtRegisteredClaimNames.Sub, CurrentUser.Id), }; foreach (var r in UserRoles) { UserClaims.Add(new Claim(JwtClaimTypes.Role, r)); } var tokenDescriptor = new SecurityTokenDescriptor { Issuer= "myidentityserverapi", Audience = "IdentityServerApi,MyAPI", Subject = new ClaimsIdentity(UserClaims), Expires = DateTime.UtcNow.AddDays(365), SigningCredentials = new SigningCredentials(sk, SecurityAlgorithms.RsaSha512), }; var token = tokenHandler.CreateToken(tokenDescriptor); TokenModel tm = new TokenModel() { access_token = tokenHandler.WriteToken(token) }; return Ok(tm); } }当我在应用程序中从上面(动作方法)接收令牌时,如下所示,但是它不起作用,例如User.Identity.IsAuthenticated为false.任何人都知道如何在没有用户名的情况下生成令牌,例如connect/token端点和密码?
When I recieve token from above(actionvation method) in my application is like below,But It don't work for example User.Identity.IsAuthenticated is false.Does any one know How can I generate token like connect/token endpoint without username and password?
"alg": "RS256", "typ": "JWT" } { "unique_name": "13f2e130-e2e6-48c7-b3ac-40f8dde8087b", "role": "Member", "nbf": 1600323833, "exp": 1718259833, "iat": 1600323833 }我选择了正确的方法吗?还是我应该使用另一种方式,例如不同的流程或授予类型?
Did I choose the right method? Or I should use another way for example different flow or grant types?
推荐答案我终于创建了这样的访问令牌:
I finally create access token like this:
[HttpPost("Activate")] [AllowAnonymous] public async Task<IActionResult> Activate([FromBody] SignUpPhoneModel model, [FromServices] ITokenService TS, [FromServices] IUserClaimsPrincipalFactory<JooyaIdentityUser> principalFactory, [FromServices] IdentityServerOptions options) { JooyaIdentityUser CurrentUser = await db.Users.Where(e => e.PhoneNumber == model.PhoneNumber).FirstOrDefaultAsync(); if (!await UserManager.VerifyChangePhoneNumberTokenAsync(CurrentUser, model.ActivationCode, model.PhoneNumber)) { return BadRequest("Activation Code in not correct"); } CurrentUser.PhoneNumberConfirmed = true; await db.SaveChangesAsync(); await UserManager.UpdateSecurityStampAsync(CurrentUser); var Request = new TokenCreationRequest(); var IdentityPricipal = await principalFactory.CreateAsync(CurrentUser); var IdentityUser = new IdentityServerUser(CurrentUser.Id.ToString()); IdentityUser.AdditionalClaims = IdentityPricipal.Claims.ToArray(); IdentityUser.DisplayName = CurrentUser.UserName; IdentityUser.AuthenticationTime = System.DateTime.UtcNow; IdentityUser.IdentityProvider = IdentityServerConstants.LocalIdentityProvider; Request.Subject = IdentityUser.CreatePrincipal(); Request.IncludeAllIdentityClaims = true; Request.ValidatedRequest = new ValidatedRequest(); Request.ValidatedRequest.Subject = Request.Subject; Request.ValidatedRequest.SetClient(SeedConfig.GetClients().Where(e => e.ClientId == model.ClientId).First()); List<ApiResource> Apis = new List<ApiResource>(); Apis.Add(SeedConfig.GetApis().Where(e => e.Name == "IdentityServerApi").First()); Apis.Add(SeedConfig.GetApis().Where(e => e.Name == model.ApiName).First()); Request.Resources = new Resources(SeedConfig.GetIdentityResources(), Apis); Request.ValidatedRequest.Options = options; Request.ValidatedRequest.ClientClaims = IdentityUser.AdditionalClaims; var Token = await TS.CreateAccessTokenAsync(Request); Token.Issuer = HttpContext.Request.Scheme + "://" + HttpContext.Request.Host.Value; Token.Lifetime = 32000000; var TokenValue = await TS.CreateSecurityTokenAsync(Token); TokenModel tm = new TokenModel() { access_token = TokenValue }; return Ok(tm); }更多推荐
如何在Identityserver4中从没有用户名和密码的令牌终结点获取令牌?
发布评论