by sunil ravulapalli
/2. September 2016 06:18
/aspnet-core
/Comments (0)
In the configuration folder create a class called
MyUser
public class MyUser
{
public string UserName { get; set; }
public string Password { get; set; }
}
Also, create a class called
MyUserManager
using System.Collections.Generic;
using System.Security.Claims;
using System.Linq;
using System.Threading.Tasks;
namespace IdTest.Configuration
{
public class MyUserManager
{
public Task<MyUser> FindByNameAsync(string username)
{
//This is where you would do a database call in real world scenario
//var context = new ApplicationContext();
//var user = context.MyUsers.SingleOrDefaultAsync(x => x.Username == username)
var user = GetUsers().SingleOrDefault(x => x.UserName == username);
return Task.FromResult(user);
}
public Task<bool> CheckPasswordAsync(MyUser user, string password)
{
//This is where you call a hashing method to verify password
//var isPasswordMatch = MyPasswordHasher.VerifyHashedPassword(user.PasswordHash, password);
if (user.Password == password)
return Task.FromResult(true);
return Task.FromResult(false);
}
private List<MyUser> GetUsers()
{
var users = new List<MyUser>();
users.Add(new MyUser { UserName = "alice", Password = "Bunny11!" });
users.Add(new MyUser { UserName = "bob", Password = "Bunny11!" });
users.Add(new MyUser { UserName = "eve", Password = "Bunny11!" });
return users;
}
public Task<List<Claim>> GetClaimsAsync(MyUser user)
{
//Database call to get calims if needed
var calims = new List<Claim>();
calims.Add(new Claim("accountnumber", "12345"));
return Task.FromResult(calims);
}
}
}
Next, add a class called
ResourceOwnerPasswordValidator
using IdentityServer4.Validation;
using System.Threading.Tasks;
namespace IdTest.Configuration
{
public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
private MyUserManager _myUserManager { get; set; }
public ResourceOwnerPasswordValidator()
{
_myUserManager = new MyUserManager();
}
public async Task<CustomGrantValidationResult> ValidateAsync(string userName, string password, ValidatedTokenRequest request)
{
var user = await _myUserManager.FindByNameAsync(userName);
if (user != null && await _myUserManager.CheckPasswordAsync(user, password))
{
return new CustomGrantValidationResult(user.UserName, "password");
}
return new CustomGrantValidationResult("Invalid username or password");
}
}
}
Next, add a class called
ProfileService
using IdentityServer4.Services;
using System;
using System.Linq;
using System.Threading.Tasks;
using IdentityServer4.Models;
using System.Security.Claims;
using IdentityModel;
namespace IdTest.Configuration
{
public class ProfileService : IProfileService
{
MyUserManager _myUserManager;
public ProfileService()
{
_myUserManager = new MyUserManager();
}
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var sub = context.Subject.FindFirst("sub")?.Value;
if (sub != null)
{
var user = await _myUserManager.FindByNameAsync(sub);
var cp = await getClaims(user);
var claims = cp.Claims;
if (context.AllClaimsRequested == false ||
(context.RequestedClaimTypes != null && context.RequestedClaimTypes.Any()))
{
claims = claims.Where(x => context.RequestedClaimTypes.Contains(x.Type)).ToArray().AsEnumerable();
}
context.IssuedClaims = claims;
}
}
public Task IsActiveAsync(IsActiveContext context)
{
return Task.FromResult(0);
}
private async Task<ClaimsPrincipal> getClaims(MyUser user)
{
if (user == null)
{
throw new ArgumentNullException(nameof(user));
}
var id = new ClaimsIdentity();
id.AddClaim(new Claim(JwtClaimTypes.PreferredUserName, user.UserName));
id.AddClaims(await _myUserManager.GetClaimsAsync(user));
return new ClaimsPrincipal(id);
}
}
}
Finally, make the following changes to the
Startup.cs file in the
ConfigureServices method
var builder = services.AddIdentityServer()
.SetSigningCredential(cert)
.AddInMemoryClients(Clients.Get())
.AddInMemoryScopes(Scopes.Get());
builder.Services.AddTransient<IResourceOwnerPasswordValidator, ResourceOwnerPasswordValidator>();
builder.Services.AddTransient<IProfileService, ProfileService>();