I am stumped by this behavior. Basically, when a refresh of a token is requested, WebAPI goes through the logic of removing the old refresh_token from the data, and I don't see any errors in the debugger. However, the API returns a HTTP 400 with "invalid_grant" as the error.
Startup.cs
// OAuth Server configuration
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = false,
TokenEndpointPath = new PathString("/oauth2/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(1),
AccessTokenFormat = new AccessTokenJwtFormat(issuer),
RefreshTokenProvider = new SimpleRefreshTokenProvider(),
RefreshTokenFormat = new RefreshTokenJwtFormat(issuer),
Provider = new CustomOAuthProvider()
};
// OAuth 2.0 Bearer Access Token Generation
app.UseOAuthAuthorizationServer(OAuthServerOptions);
SimpleRefreshTokenProvider.cs
public class SimpleRefreshTokenProvider : IAuthenticationTokenProvider
{
public async Task CreateAsync(AuthenticationTokenCreateContext context)
{
var clientid = context.Ticket.Properties.Dictionary["as:client_id"];
if (string.IsNullOrEmpty(clientid))
{
return;
}
var refreshTokenId = Guid.NewGuid().ToString("n");
var refreshTokenLifeTime = context.OwinContext.Get<string>("as:clientRefreshTokenLifeTime");
var _repo = ClientDbProvider.GetInstance();
var token = new RefreshToken()
{
Id = ClientHelper.GetHash(refreshTokenId),
ClientId = clientid,
Subject = context.Ticket.Identity.Name,
IssuedUtc = DateTime.UtcNow,
ExpiresUtc = DateTime.UtcNow.AddMinutes(Convert.ToDouble(refreshTokenLifeTime))
};
context.Ticket.Properties.IssuedUtc = new DateTimeOffset(token.IssuedUtc);
context.Ticket.Properties.ExpiresUtc = new DateTimeOffset(token.ExpiresUtc);
context.Ticket.Properties.Dictionary.Add("refreshTokenId", refreshTokenId);
context.Ticket.Identity.AddClaim(new Claim(ClaimTypes.Role, "refreshToken"));
token.ProtectedTicket = context.SerializeTicket();
var result = await _repo.AddRefreshToken(token);
if (result)
{
context.SetToken(token.ProtectedTicket);
}
return;
}
public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
var allowedOrigin = context.OwinContext.Get<string>("as:clientAllowedOrigin");
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });
var _repo = ClientDbProvider.GetInstance();
string hashedTokenId = ClientHelper.GetHash(context.Token);
var refreshToken = await _repo.FindRefreshToken(hashedTokenId);
if (refreshToken != null)
{
//Get protectedTicket from refreshToken class
context.DeserializeTicket(refreshToken.ProtectedTicket);
var result = await _repo.RemoveRefreshToken(hashedTokenId);
}
}
public void Create(AuthenticationTokenCreateContext context)
{
throw new NotImplementedException();
}
public void Receive(AuthenticationTokenReceiveContext context)
{
throw new NotImplementedException();
}
}
RefreshTokenJwtFormat.cs
public class RefreshTokenJwtFormat : ISecureDataFormat<AuthenticationTicket>
{
private const string AudiencePropertyKey = "audience";
private readonly string _issuer = string.Empty;
public RefreshTokenJwtFormat(string issuer)
{
_issuer = issuer;
audStore = new AudiencesStore();
}
public string Protect(AuthenticationTicket data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
string audienceId = data.Properties.Dictionary.ContainsKey(AudiencePropertyKey) ? data.Properties.Dictionary[AudiencePropertyKey] : null;
if (string.IsNullOrWhiteSpace(audienceId)) throw new InvalidOperationException("AuthenticationTicket.Properties does not include audience");
var audience = GetAudience(audienceId);
string symmetricKeyAsBase64 = audience.Base64Secret;
var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64);
var signingCredentials = new SigningCredentials(
new InMemorySymmetricSecurityKey(keyByteArray),
SecurityAlgorithms.HmacSha256Signature,
SecurityAlgorithms.Sha256Digest);
var issued = data.Properties.IssuedUtc;
var expires = data.Properties.ExpiresUtc;
var payload = new JwtPayload(_issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime);
if (data.Properties.Dictionary.ContainsKey("refreshTokenId"))
{
payload.Add("refreshTokenId", data.Properties.Dictionary["refreshTokenId"]);
}
var header = new JwtHeader(signingCredentials);
var token = new JwtSecurityToken(header, payload);
var handler = new JwtSecurityTokenHandler();
var jwt = handler.WriteToken(token);
return jwt;
}
public AuthenticationTicket Unprotect(string protectedText)
{
var handler = new JwtSecurityTokenHandler();
SecurityToken securityToken = handler.ReadToken(protectedText);
var audienceId = ((JwtSecurityToken)securityToken).Claims.First(x => x.Type == "aud").Value;
var audience = GetAudience(audienceId);
string symmetricKeyAsBase64 = audience.Base64Secret;
var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64);
var securityKey = new InMemorySymmetricSecurityKey(keyByteArray);
var validationParameters = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = securityKey,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
ValidateAudience = true,
ValidAudience = audienceId,
ValidateIssuer = true,
ValidIssuer = _issuer
};
SecurityToken validatedToken;
ClaimsPrincipal principal = null;
try
{
principal = handler.ValidateToken(protectedText, validationParameters, out validatedToken);
}
catch(Exception ex)
{
return null;
}
return new AuthenticationTicket(principal.Identities.First(), new AuthenticationProperties());
}
private Models.Audience GetAudience(string audienceId)
{
var findAudTask = Task.Run(() => audStore.FindAudienceAsync(audienceId));
findAudTask.Wait();
var audience = findAudTask.Result;
return audience;
}
private AudiencesStore audStore;
}
First you need
implement GrantRefreshToken(OAuthGrantRefreshTokenContext context) in your CustomOAuthProvider
something like
public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
{
// Change auth ticket for refresh token requests
var newIdentity = new ClaimsIdentity(context.Ticket.Identity);
//newIdentity.AddClaim(new Claim("newClaim", "newValue"));
var newTicket = new AuthenticationTicket(newIdentity, context.Ticket.Properties);
context.Validated(newTicket);
return Task.FromResult<object>(null);
}
Second you need to change your method Unprotect in RefreshTokenJwtFormat.
replace
return new AuthenticationTicket(principal.Identities.First(), new AuthenticationProperties());
with
return new AuthenticationTicket(principal.Identities.First(), new AuthenticationProperties
{
IssuedUtc = validatedToken.ValidFrom,
ExpiresUtc = validatedToken.ValidTo
});
i have similar (working) code. I'm not a specialist on this but i compared my code a bit and noticed:
in SimpleRefreshToken.cs:
in receiveAsync, my code ends with:
context.SetTicket(context.Ticket);
return Task.FromResult<object>(null);
Which sets the ticket and return a value.
The same for createAsync, my code ends with:
return Task.FromResult<object>(null);
Allthough, no idea if this will help
Related
I have the following code in my Startup.cs
var openIdOptions = new OpenIdConnectAuthenticationOptions
{
ClientId = openIdConfiguration.ClientId,
Authority = openIdConfiguration.Authority,
RedirectUri = openIdConfiguration.RedirectUri,
ResponseType = openIdConfiguration.CodeFlowEnabled ? "code" : OpenIdConnectResponseTypes.IdToken,
TokenValidationParameters = tokenValidationParameters,
Scope = string.IsNullOrEmpty(openIdConfiguration.Scope) ? OpenIdConnectScopes.OpenIdProfile : openIdConfiguration.Scope,
PostLogoutRedirectUri = openIdConfiguration.PostLogoutRedirectUri,
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthorizationCodeReceived = this.AuthorizationCodeReceived,
MessageReceived = this.MessageReceived,
SecurityTokenValidated = this.SecurityTokenValidated,
SecurityTokenReceived = this.SecurityTokenReceived,
AuthenticationFailed = this.AuthenticationFailed,
RedirectToIdentityProvider = this.RedirectToIdentityProvider
},
SignInAsAuthenticationType = "Cookies",
CookieManager = new SameSiteCookieManager(new SystemWebCookieManager())
};
....
app.UseOpenIdConnectAuthentication(openIdOptions);
I would like to generate a token from a separate TokenService.cs, with a different configuration which will be consumed by another application.
public class TokenService
{
public async Task<string> GenerateToken()
{
var openIdOptions = new OpenIdConnectAuthenticationOptions
{
//similar OIDC config
}
**// How to generate a token ?**
return token;
}
}
How to go about generating a new token when needed from my TokenService class ?
I'm trying to create an authorize with jwt bearer, but I cant do it on my application, when I do with postman it happening what I want, but on my app don't...
Service.ts (Angular 8)
getAll(): Observable<...[]> {
return this.httpClient.get<...[]>(environment.url + "api",
{ headers: {'Authorization' : 'Bearer ' + token });
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
...
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
var symetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtKey"]));
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateIssuerSigningKey = true,
IssuerSigningKey = symetricSecurityKey
};
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
AuthController.cs
[HttpPost]
[Route("login")]
public async Task<AccountModel> Login([FromBody] AccountModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser();
var signInResultado = new Microsoft.AspNetCore.Identity.SignInResult();
Task.Run(async () =>
{
user = await _userManager.FindByEmailAsync(model.Email);
}).Wait();
Task.Run(async () =>
{
await _userManager.CheckPasswordAsync(user, model.Password);
}).Wait();
Task.Run(async () =>
{
signInResultado = await _signInManager.PasswordSignInAsync(
user.UserName,
model.Password,
isPersistent: false,
lockoutOnFailure: false);
}).Wait();
if (signInResultado.Succeeded)
{
var appUser = _userManager.Users.FirstOrDefault(u => u.Id == user.Id);
var claims = await GetValidClaims(appUser);
var accountModel = new AccountModel(user, _roleManager);
accountModel.Token = GenerateJwtToken(appUser, claims);
return accountModel;
}
}
return model;
}
private string GenerateJwtToken(ApplicationUser user, List<Claim> claims)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_configuration["JwtKey"]);
var tokens = new JwtSecurityToken(
claims: claims,
expires: DateTime.UtcNow.AddDays(1),
signingCredentials: new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
);
return new JwtSecurityTokenHandler().WriteToken(tokens);
}
private async Task<List<Claim>> GetValidClaims(ApplicationUser user)
{
IdentityOptions _options = new IdentityOptions();
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
new Claim(_options.ClaimsIdentity.UserIdClaimType, user.Id.ToString()),
new Claim(_options.ClaimsIdentity.UserNameClaimType, user.UserName)
};
var userClaims = await _userManager.GetClaimsAsync(user);
var userRoles = await _userManager.GetRolesAsync(user);
claims.AddRange(userClaims);
foreach (var userRole in userRoles)
{
claims.Add(new Claim(ClaimTypes.Role, userRole));
var role = await _roleManager.FindByNameAsync(userRole);
if (role != null)
{
var roleClaims = await _roleManager.GetClaimsAsync(role);
foreach (Claim roleClaim in roleClaims)
{
claims.Add(roleClaim);
}
}
}
return claims;
}
Any method with Role = Admin
[HttpGet]
[Authorize(Roles = "Admin")]
public ActionResult<IEnumerable<RoleModel>> Get()
Postman - Login (Create Token)
Postman - Get any method with Role = Admin
When I did on my application, it redirected to Identity/Account/Login
I'm doing user-controlled using JWT token.
No problem logging in, but how to log out?
Comparison of the database
my opinion,
do you have better method suggestions
Token controller
I validate the user in UyelikOnaylama class
public class TokenController : ApiController
{
[HttpPost]
public async Task<HttpResponseMessage> Post(TokenRequestDto dto)
{
UyelikOnaylama uyelikOnaylama = new UyelikOnaylama();
var sonuc = await uyelikOnaylama.AsekronMethod(dto);
Random random = new Random();
if (sonuc==1)
{
var claims = new[]
{
new Claim(ClaimTypes.Name, dto.UserName),
new Claim(ClaimTypes.Role, random.ToString()+"asd"),
new Claim("scope", random.ToString()+"tasd"),
new Claim("scope", "**")
};
var token = new JwtSecurityToken(
issuer: "localhost",
audience: "localhost",
claims: claims,
expires: DateTime.UtcNow.AddMonths(30),
signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes("!^'+sda1905SDASDQdqqdD'^+!34123")), SecurityAlgorithms.HmacSha256)
);
return Request.CreateResponse(HttpStatusCode.OK, new JwtSecurityTokenHandler().WriteToken(token));
}
else
{
return Request.CreateResponse(HttpStatusCode.Unauthorized, "Hatalı kullanıcı adı ya da parola");
}
}
}
I'm checking with a startup class
public class Startup
{
public void Configuration(IAppBuilder app)
{
string secretKey = "!^'+sda1905SDASDQdqqdD'^+!34123";
var opt = new JwtBearerAuthenticationOptions();
var prov = new SymmetricKeyIssuerSecurityKeyProvider[1];
prov[0] = new SymmetricKeyIssuerSecurityKeyProvider("localhost", Encoding.UTF8.GetBytes(secretKey));
opt.IssuerSecurityKeyProviders = prov;
opt.AllowedAudiences = new String[1] { "localhost" };
app.UseJwtBearerAuthentication(opt);
}
}
Correct me if I am wrong, but you get an AccessToken from your JWT Service? With this Token you get the desired rights for accessing data on the WebApi (or whatever you do with it). If your User logs out, the AccessToken is still available.
If this is your problem, simply remove the token from the List holding all of them. Also you can reduce the time, when the Token expires
Solution
Add this 3 classes into your project
public static class JwtSecurityKey
{
public static SymmetricSecurityKey Create(string secret)
{
return new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret));
}
}
public sealed class JwtToken
{
private JwtSecurityToken Token;
internal JwtToken(JwtSecurityToken token)
{
this.Token = token;
}
public DateTime ValidTo => Token.ValidTo;
public string Value => new JwtSecurityTokenHandler().WriteToken(this.Token);
}
public class JwtTokenBuilder
{
private SecurityKey SecurityKey = null;
private string Subject = "";
private string Issuer = "";
private string Audience = "";
private Dictionary<string, string> Claims = new Dictionary<string, string>();
private int ExpiryInMinutes = 5;
public JwtTokenBuilder AddSecurityKey(SecurityKey securityKey)
{
this.SecurityKey = securityKey;
return this;
}
public JwtTokenBuilder AddSubject(string subject)
{
this.Subject = subject;
return this;
}
public JwtTokenBuilder AddIssuer(string issuer)
{
this.Issuer = issuer;
return this;
}
public JwtTokenBuilder AddAudience(string audience)
{
this.Audience = audience;
return this;
}
public JwtTokenBuilder AddClaim(string type, string value)
{
this.Claims.Add(type, value);
return this;
}
public JwtTokenBuilder AddClaims(Dictionary<string, string> claims)
{
this.Claims.Union(claims);
return this;
}
public JwtTokenBuilder AddExpiry(int expiryInMinutes)
{
this.ExpiryInMinutes = expiryInMinutes;
return this;
}
public JwtToken Build()
{
EnsureArguments();
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, this.Subject),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
}
.Union(this.Claims.Select(item => new Claim(item.Key, item.Value)));
var token = new JwtSecurityToken(
issuer: this.Issuer,
audience: this.Audience,
claims: claims,
expires: DateTime.UtcNow.AddMinutes(ExpiryInMinutes),
signingCredentials: new SigningCredentials(
this.SecurityKey,
SecurityAlgorithms.HmacSha256));
return new JwtToken(token);
}
#region Privates
private void EnsureArguments()
{
if (this.SecurityKey == null)
throw new ArgumentNullException("Security Key");
if (string.IsNullOrEmpty(this.Subject))
throw new ArgumentNullException("Subject");
if (string.IsNullOrEmpty(this.Issuer))
throw new ArgumentNullException("Issuer");
if (string.IsNullOrEmpty(this.Audience))
throw new ArgumentNullException("Audience");
}
#endregion
}
And in your Startup class, call this method:
private void ConfigureTokenServices(IServiceCollection services)
{
// Add Token Authentication
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters =
new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "Custom.Security.Bearer",
ValidAudience = "Custom.Security.Bearer",
IssuerSigningKey = JwtSecurityKey.Create("Yout securitykey which must be a very long string to work")
};
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
Debug.WriteLine("OnAuthenticationFailed: " + context.Exception.Message);
return Task.CompletedTask;
},
OnTokenValidated = context =>
{
Debug.WriteLine("OnTokenValidated: " + context.SecurityToken);
return Task.CompletedTask;
}
};
});
services.AddAuthorization(options =>
{
options.AddPolicy("Guest",
policy => policy.RequireClaim("Role", "Add here your roles"));
});
}
And add this line
app.UseAuthentication();
to
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
With this you can then filter inside your Controller, which is the sense of JWT:
[Produces("application/json")]
[Route("YourRoute")]
[Authorize("Role")]
public class MyController
{
or you can do this directly on a method.
[Authorize("Role")]
[HttpGet, Route("YourRoute")]
public IActionResult HttpGet()
{
Tell me if I understood your issue correct and if there are any problems implementing this
I did create custom AuthorizeAttribute that should handle Jwt Bearer token and then create ClaimsIdentity. But when I send request again, anyway I can't see authorized user and must create ClaimsIdentity again and add user to CurrentPricipal again. What I'm doing wrong?
public class JwtAuthorizeAttribute : AuthorizeAttribute
{
private readonly string role;
public JwtAuthorizeAttribute()
{
}
public JwtAuthorizeAttribute(string role)
{
this.role = role;
}
protected override bool IsAuthorized(HttpActionContext actionContext)
{
var jwtToken = new JwtToken();
var ctx = actionContext.Request.GetOwinContext();
if (ctx.Authentication.User.Identity.IsAuthenticated) return true;
if (actionContext.Request.Headers.Contains("Authorization"))
{
var token = actionContext.Request.Headers.Authorization.Parameter;
try
{
IJsonSerializer serializer = new JsonNetSerializer();
IDateTimeProvider provider = new UtcDateTimeProvider();
IJwtValidator validator = new JwtValidator(serializer, provider);
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);
var json = decoder.Decode(token, SiteGlobal.Secret, verify: true);
jwtToken = JsonConvert.DeserializeObject<JwtToken>(json);
if (jwtToken.aud != SiteGlobal.Audience || jwtToken.iss != SiteGlobal.Issuer || role != jwtToken.role)
{
return false;
}
}
catch (TokenExpiredException)
{
return false;
}
catch (SignatureVerificationException)
{
return false;
}
}
else
{
return false;
}
var identity = new ClaimsIdentity("JWT");
identity.AddClaim(new Claim(ClaimTypes.Name, jwtToken.unique_name));
identity.AddClaim(new Claim(ClaimTypes.Role, jwtToken.role));
ctx.Authentication.SignIn(new AuthenticationProperties { IsPersistent = true }, identity);
Thread.CurrentPrincipal = new ClaimsPrincipal(identity);
HttpContext.Current.User = new ClaimsPrincipal(identity);
return true;
}
}
Signin is used to create a cookie. Do you have a cookie Auth middleware to handle the signin?
I have mocked abstract class to test concrete method of a class as following.
var mock = new Mock<BaseTestController>();
mock.CallBase = true;
var ta = mock.Object;
ta.ControllerContext = new HttpControllerContext { Request = new HttpRequestMessage() };
var owinMock = new Mock<IOwinContext>();
owinMock.Setup(o => o.Authentication.User).Returns(new ClaimsPrincipal());
owinMock.Setup(o => o.Request).Returns(new Mock<OwinRequest>().Object);
owinMock.Setup(o => o.Response).Returns(new Mock<OwinResponse>().Object);
owinMock.Setup(o => o.Environment).Returns(new Dictionary<string, object> { { "key1", 123 } });
var traceMock = new Mock<TextWriter>();
owinMock.Setup(o => o.TraceOutput).Returns(traceMock.Object);
ta.Request.SetOwinContext(owinMock.Object);
var result = await ta.ActivateDeactive("test#user.com", true);
Problem:
My abstract class use Entity Framework 6 and Asp.Net Identity UserManager and RoleManager as following
public TestUserManager UserService
{
get
{
return _userService ?? Request.GetOwinContext().GetUserManager<TestUserManager>();
}
private set
{
_userService = value;
}
}
public TestRoleManager RoleService
{
get
{
return _roleService ?? Request.GetOwinContext().Get<TestRoleManager>();
}
private set
{
_roleService = value;
}
}
How i can mock TestUserManager and TestRoleManager in my above mocking code?
I tried the following way but couldn't get the way to hook it up with controllerContext.
var userStore = new Mock<IUserStore<TestUser>>();
var userManager = new TestUserManager(userStore.Object);
Answer to question asked below by Aleksey L.
This is how TestUserManager derives UserManaer and implement.
public class TestUserManager : UserManager<TestUser>
{
public TestUserManager(IUserStore<TestUser> store)
: base(store)
{
}
public static TestUserManager Create(IdentityFactoryOptions<TestUserManager> options, IOwinContext context)
{
TestUserManager manager = new TestUserManager(new UserStore<TestUser>(context.Get<AuthContext>()));
setValidationRules(manager);
IDataProtectionProvider dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider == null)
dataProtectionProvider = new DpapiDataProtectionProvider();
manager.UserTokenProvider = new DataProtectorTokenProvider<TestUser>(dataProtectionProvider.Create("ASP.NET Identity")) { TokenLifespan = TimeSpan.FromDays(expiryTime) };
return manager;
}
public static TestUserManager CreateLocal(AuthContext context)
{
TestUserManager manager = new TestUserManager(new UserStore<TestUser>(context));
setValidationRules(manager);
IDataProtectionProvider dataProtectionProvider = new DpapiDataProtectionProvider();
manager.UserTokenProvider = new DataProtectorTokenProvider<TestUser>(dataProtectionProvider.Create("ASP.NET Identity"));
return manager;
}
private static void setValidationRules(ApplicationUserManager manager)
{
manager.UserValidator = new UserValidator<TestUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
manager.PasswordValidator = new ApplicationPasswordValidator
{
RequiredLength = 30,
MaximumCharacters = 30,
RequireNonLetterOrDigit = false,
RequireDigit = true,
RequireLowercase = false,
RequireUppercase = false
};
}
}
Controller Code
public async Task<IHttpActionResult> ActivateDeactive(string studentId, bool active)
{
IdentityResult result;
_accountService = new AccountMgtService(UserService, RoleService);
result = await _accountService.ActiveDeactiveUser(userId, active);
}
Not sure why you're implementing TestUserManager and not just mocking it. Lat's say we have following code in controller:
var owinContext = Request.GetOwinContext();
var userManager = owinContext.GetUserManager<ApplicationUserManager>();
var applicationUser = userManager.FindById("testId");
You can inject mock user store this way:
var owinMock = new Mock<IOwinContext>();
var userStoreMock = new Mock<IUserStore<ApplicationUser>>();
userStoreMock.Setup(s => s.FindByIdAsync("testId")).ReturnsAsync(new ApplicationUser
{
Id = "testId",
Email = "test#email.com"
});
var applicationUserManager = new ApplicationUserManager(userStoreMock.Object);
owinMock.Setup(o => o.Get<ApplicationUserManager>(It.IsAny<string>())).Returns(applicationUserManager);
ta.Request.SetOwinContext(owinMock.Object);