IdentityServer4 and ResourceOwnerPasswordValidator Dynamic ConnectionString - authentication

So, IResourceOwnerPasswordValidator is supposed to replace IUserService.
In the old version IdentityServer3 I could do the following:
factory.UserService = new Registration<IUserService>(typeof(MyIdentityUserService));
factory.Register(new Registration<IUserRepository>(userRepository));
which passes a custom userRepository object with the proper connection string.
Now in IdentityServer4 I need to Connect to the proper Portal database in order for ID4 to authenticate the user against the correct portal database.
If I could pass a parameter to the constructor of the ResourceOwnerPasswordValidator class like below , then this would be fine but this is not possible with ASP.NET CORE.
public ResourceOwnerPasswordValidator(string MyConnString)
{
_connstring = MyConnString;
}
This can't work because the ConfigurationService registers this class without the ability to pass values. This makes sense since this registration process begins before the pipeline is built. How do I dynamically pass a connection string to the ResourceOwnerPasswordValidator class? I am trying to authenticate against the portal making the call. In ID3 I could do this by using the acr_value.
I am trying to get ID4 to authenticate as a MultiTenant Authentication Server.

You could inject a service or a DTO into a ResourceOwnerPasswordValidator constructor:
public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
public ResourceOwnerPasswordValidator(IAuthRepository repository)
{
}
}
Hence it is possible to pass a service which returns your connection string.
By default, validator's implementation is registered as Transient which means it will not be a singleton until it is resolved in a singleton (which is not a IdSrv4 case I guess).
If you need a Scoped connection string (i.e. per web request), register a scoped DTO with a factory method: services.AddScoped<T>(() => ) or use AsyncLocal<T>. Check this thread to get more details:
How to Per-Request caching in ASP.net core

Related

access ResourceInfo in Quarkus / Vertx HttpAuthenticationMechanism

In Quarkus (resteasy reactive), is there a way to get hold of the "ResourceInfo" in an HTTP Authentication Mechanism?
What I'm trying to do is read an annotation that is defined on the resource class or method, in order to choose an authentication mechanism based on it.
Injecting the ResourceInfo directly in the mechanism class does not work (and also, it is application scoped and not request scoped, so not sure it could work). I also couldn't find the info I need in the RoutingContext parameter.
I have also tried adding a ContainerRequestFilter, in which injecting the ResourceInfo with #Context works well, but I think perhaps the filters are called after the httpAuthenticationMechanism.authenticate(), because it's not called in my test when the endpoint requires authentication.
Is there another way to do this?
----> To clarify with code what I would like to do:
have different JAX-RS resources with a custom #Authorization annotations with different "api names" like this:
#Path("/jwttest")
#ApplicationScoped
#Authorization("jwttest")
public class JWTTestController {
...
}
#Path("/oidctest")
#ApplicationScoped
#Authorization("myoidc")
public class OIDCTestController {
...
}
and then different configs like this:
myframework.auth.jwttest.type=jwt
myframework.auth.jwttest.issuer=123
myframework.auth.jwttest.audience=456
myframework.auth.myoidc.type=oidc
myframework.auth.myoidc.auth-server-url=myurl
And in the HttpAuthenticationMechanism, find the value of #Authorization, and based on it, call another provider like suggested in https://quarkus.io/guides/security-customization#dealing-with-more-than-one-httpauthenticationmechanism with the right api name so that it can load the config.

Authentication for Apache Ignite 2.5

I would like to implement authentication for all the nodes of the cluster (client and server should provide username and password to join the cluster). I tried to use the latest version, which the documentation claims to provide authentication, but it doesn't implement it for all the nodes; it's just for the new thin java client.
First question: is my understanding correct, or am I missing something?
I also tried to implement the authentication of all the nodes using the GridSecurityProcessor interface, as part of a custom plugin (by following this guide http://smartkey.co.uk/development/securing-an-apache-ignite-cluster/ and other discussions on the public mailing list).
I got the plugin to be recognized by the server node, but I can't wire my implementation of the SecurityCredentialsProvider to Ignite; it seems Ignite doesn't use it. The question is similar to this one: http://apache-ignite-users.70518.x6.nabble.com/Custom-SecurityCredentialsProvider-and-SecurityCredentials-td16360.html.
As a consequence, when GridSecurityProcessor.authenticateNode(ClusterNode node, SecurityCredentials cred) is called, cred is null.
Second question: How to hook SecurityCredentialsProvider and SecurityCredentials to Ignite, so that it will call the authorizeNode method from my plugin, with these credentials?
I managed to implement authentication with using the plugin system recommended by the documentation. I followed these steps:
Created a class extending the TcpDiscoverySpi and implements DiscoverySpiNodeAuthenticator. In it I pass the SecurityCredentials object as a constructor parameter.
`
public CustomTcpDiscoverySpi(final SecurityCredentials securityCredentials) {
this.securityCredentials = securityCredentials;
this.setAuthenticator(this);
}
In this class, I override the setNodeAttributes from TcpDiscoverySpi to add the securityCredentials object like this:
`
#Override
public void setNodeAttributes(final Map<String, Object> attrs, final IgniteProductVersion ver) {
attrs.put(IgniteNodeAttributes.ATTR_SECURITY_CREDENTIALS, this.securityCredentials);
super.setNodeAttributes(attrs, ver);
}
I also implement the authenticateNode method where I check the SecurityCredentials object of this class with the one received as a parameter on the authenticateNode method. This method returns an implementation of SecurityContext if authentication succeeded or null if not; so you need to implement it as you like. For example to give full access with no authorization, just return true for all the ****operationAllowed methods and return null in subject() method.
In IgniteConfiguration, use this class as discoverySpi: cfg.setDiscoverySpi(customTcpDiscoverySpi);

Using RIA Domain Services how to refresh client generated code after making changes to EF

I am working on a N-tier Silverlight 4.0 solution using WCV RIA services, Domain Services and Entity Framework.
I have created the Entity Framework model and Domain Services in my DAL project.
Having clicked the 'Enable Client Code Generation' whilst creating the Domain Service everything works fine. The generated code is created in the client application as I can see the .g.cs file.
I decided to add a stored procedure to the EF model by adding a function and creating a complex type.
Then I proceeded to add this code to my Domain Service (MyDomainService.cs) class as shown below:
public IQueryable GetJournalItemList()
{
return this.ObjectContext.ExecuteFunction("GetJournalList", null).AsQueryable();
}
The problem I'm facing now is that when I build my solution I cannot see the new code in the client generated code class (.g.cs) in Silverlight client application. The proxy has no reference to the new GetJournalItemList which references the newly added stored procedure.
So here's my question: how to force a refresh of the client generated code so changes to the Domain Service class can be shown?
Thank You
You must return a strongly typed result. i.e.
public IQueryable<JournalItemList> GetJournalItemList()
{
return this.ObjectContext
.ExecuteFunction("GetJournalList", null).AsQueryable();
}
In addition, if this has not already been done, JournalItemList must have a key defined. You can do this using a Metadatatype attribute through a custom partial class. When you generate the Domain Service, a .metadata.cs file would have been created. There should be examples you can use.
[MetadataType(JournalItemList.Metadata)]
public partial class JournalItemList
{
public class Metadata
{
// Assuming that JournalItemList.JournalItemId exists
[Key]
public int JournalItemId { get; set; }
}
}

Windows authentication and Asp.Net Web API

I have an Intranet application with Windows authentication based on MVC4.
When I need the WindowsIdentity for authorization purpose in a Controller I just use
HttpContext.User.Identity
Now I wanted to use the new Asp.Net WebAPI for some Ajax calls.
Is there a way to get the WindowsIdenty object in the same easy way as in an MVC Controller?
Please don't reference the HttpContext from a controller.
You can access the Controllers User property which is way of accessing the Identity through without a dirrect reference to HttpContext.
public class MyController : ApiController
{
public string Get()
{
var indenty = this.User.Identity;
}
}
Why
The controllers User property provides a level of abstraction which allows for easier mocking and thus unit testing. This abstraction also allows for greater portability e.g. if this was WebApi Self Host you wouldn't even have access to HttpContext.
To read more about how to unit test and mock the User property read here. For more information re: portability read here.

Silverlight 4 - authentiation / authorization against custom wcf service

I have a wcf service in front of an AzMan store that passes roles and operations to clients using the following interface:
[OperationContract]
bool AuthenticateUser(string password, string appName);
[OperationContract]
string[] GetRoles(string storelocation, string appName);
[OperationContract]
string[] GetOperations(string storeLocation, string appName, string selectedRole);
Clients connect to this service using windows authentication (but users must send their password through to reaffirm their identity). Ultimately the service delivers an array of operations that each client can perform based on their selected role.
I've opened a new Silverlight Business Application and tried to understand how authentication/authorization works in this template, as well as scoured the web to find examples to how to hook my webservice to the login box already created in the template, but I am completely at a loss as how to do this!
Can anyone offer any advice?
The Business application template has an AuthenticationService, that is based on the User object and the AuthenticationBase class. AuthenticationBase has virtual methods that you can override to use your own security mechanisms.
For example, there is a Login method, based on a username and a password. This method returns a IUser that has a name and roles.
After looking at your interface, I'd create a sub-interface of IUser to include the list of allowed operations and change the generated User class to implement this sub-interface. And I'd override the Login and related methods in AuthenticationService to use your existing Azman-based code.