Asked by:
Custom User Service for Thinktecture Identity Server V3

Question
-
User1741474265 posted
I am trying to create a custom user service to authenticate a user against multiple user stores. As per my understanding I have to create a new service implementing interface IUserService.
In my login page users will enter username , password and they will select a organization name which is displayed as a dropdown. This organization name will decide which user store to use. Now, should I write different UserServices for each organization or is there way that I can do with one something like passing an extra parameter to AuthenticateLocalAsync(string username, string password, SignInMessage message)?
If I develop three services how to register them to work based on the organization selected?
Thursday, January 22, 2015 2:37 PM
All replies
-
User1779161005 posted
That scenario is not supported. You would need to implement either a partial login or a custom view with a custom user service.
Thursday, January 22, 2015 4:19 PM -
User1741474265 posted
Thank you Allen. I have created custom view service and added a new field for the domain. Also created a custom user service that implements IUserService. How will the AuthenticateLocalAsync will get the "domain" value from the model. How can I wire this up?
Friday, January 23, 2015 3:20 PM -
User1779161005 posted
It won't -- this is why I suggested that you might need to do a custom view. The other approach is you can make the use put the domain in the username field, but that's a bit of a hack. So, in short, this is not supported.
Friday, January 23, 2015 4:44 PM -
User1741474265 posted
are there any references on how to create a custom view? Ordo you suggest a better way to implement this? Thank you
Friday, January 23, 2015 5:19 PM -
User1779161005 posted
Check the docs: http://identityserver.github.io/Documentation/
Friday, January 23, 2015 5:30 PM -
User1741474265 posted
Allen, first of all many thanks for your quick response and sorry to keep coming back at you. Either I am too dumb or I am missing something very simple. Can you please clarify few things?
1. I initially assumed Custom View and Custom View Service are same. Looks like I am wrong. So by Custom View you mean normal html page with in "assets" folder of the hosting application? If yes, once I create this how can send my extra argument to User Service? Or do I need to call a corresponding user service (assuming each or has different services) based on the "domain" selected in the custom view?
2. Is there a way to achieve this using Dependency Injection like below. Is there a way to inject the "domain" value after the login view is submitted?
factory.Register(new Registration<IDomain, Org1Domain>("ORG1")); factory.Register(new Registration<IDomain, Org2Domain>("ORG2")); factory.UserService = new Registration<IUserService>(resolver => new LocalRegistrationUserService(resolver.Resolve<IDomain>(domain)));
Friday, January 23, 2015 6:21 PM -
User1779161005 posted
Well, as I mentioned before -- your scenario is not something supported. You might be able to get it to work, but I've not tried myself and I'm not certain you can (and I wrote much of the code). We just didn't design to allow for that.
Friday, January 23, 2015 9:02 PM -
User-461692724 posted
Hi Brock,
Does the latest version of IdentityServer3 (2.5.0) already contains this featuare? I need to create the same scenario of rajarameshvarma1 and pass a parameter from the login page to user service.
I'm looking foward to rear from you.
Thanks you!
Best regards
Monday, April 18, 2016 12:56 PM -
User-229120143 posted
In your custom login page put your dropdown or something else like this:
<input type="text" name="extra" id="extra" />
in your userservice...
public class UserService : UserServiceBase
{
private readonly IUserRepository userRepository;
IOwinContext ctx;
public UserService(IUserRepository userRepository, OwinEnvironmentService env)
{
this.userRepository = userRepository;
ctx = new OwinContext(env.Environment);
}public override async Task AuthenticateLocalAsync(LocalAuthenticationContext context)
{var form = await ctx.Request.ReadFormAsync();var extra = form["extra"];
after that put your logic in action to authenticate in a data store you want.
Monday, June 6, 2016 12:25 AM