Implementing Authentication in IgniteDB - security

I just configured authentication in IgniteDB ( a specific server, not a localhost )
https://apacheignite.readme.io/docs/advanced-security
However I encountered some issue while trying to connect. Where should I provide the credential?
TcpDiscoverySpi spi = new TcpDiscoverySpi();
TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();
String ipList = appConfig.getIgniteIPAddressList();
List<String> addressList= Arrays.asList(ipList.split(";"));
ipFinder.setAddresses(addressList);
spi.setIpFinder(ipFinder);
IgniteConfiguration cfg = new IgniteConfiguration();
cfg.setIgniteInstanceName("IgnitePod");
cfg.setClientMode(true);
cfg.setDiscoverySpi(spi);
Ignite ignite = Ignition.start(cfg);
Anybody has idea on implementing it?

https://apacheignite.readme.io/docs/advanced-security
Describes how to configure the authentication via username and password for THIN connections only (JDBC, ODBC).
You can create users using SQL commands like next:
https://apacheignite-sql.readme.io/docs/create-user
You can provide credentials to thin client connection string using its properties:
https://apacheignite-sql.readme.io/docs/connection-string-and-dsn#section-supported-arguments
https://apacheignite-sql.readme.io/docs/jdbc-driver#section-additional-connection-string-examples
Please also check that you have Ignite persistence configured.

As Andrei notes, Ignite only authenticates thin clients by default, and even then only when persistence is enabled. If you need to have thick-clients authenticate also, you can do this using a plugin. Third-party, commercial solutions also exist.

Apache Ignite does not provide these kinds of security capabilities with its open-source version. One can either implement it on your own or use commercial Gridgain distribution.
Here are the steps to implement a custom security plugin.
One would need to implement GridSecurityProcessor which would be used to authenticate the joining node.
In GridSecurityProcessor, you would have to implement authenticateNode() api as follows
public SecurityContext authenticateNode(ClusterNode node, SecurityCredentials cred) throws IgniteCheckedException {
SecurityCredentials userSecurityCredentials;
if (securityPluginConfiguration != null) {
if ((userSecurityCredentials = securityPluginConfiguration.getSecurityCredentials()) != null) {
return userSecurityCredentials.equals(cred) ? new SecurityContextImpl() : null;
}
if (cred == null && userSecurityCredentials == null) {
return new SecurityContextImpl();
}
}
if (cred == null)
return new SecurityContextImpl();
return null;
}
Also, you would need to extend TcpDiscoverySpi to pass the user credentials during initLocalNode() as follows
#Override
protected void initLocalNode(int srvPort, boolean addExtAddrAttr) {
try {
super.initLocalNode(srvPort, addExtAddrAttr);
this.setSecurityCredentials();
} catch (Exception e) {
e.printStackTrace();
}
}
private void setSecurityCredentials() {
if (securityCredentials != null) {
Map<String,Object> attributes = new HashMap<>(locNode.getAttributes());
attributes.put(IgniteNodeAttributes.ATTR_SECURITY_CREDENTIALS, securityCredentials);
this.locNode.setAttributes(attributes);
}
}
You can follow the link given below to get detailed steps that can be followed to write a custom security plugin and its usage.
https://www.bugdbug.com/post/how-to-secure-apache-ignite-cluster

Was able to solve my own problem by creating my own CustomTCPDiscoveryAPI.
First, create this class :
import org.apache.ignite.IgniteException;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.internal.IgniteNodeAttributes;
import org.apache.ignite.internal.processors.security.SecurityContext;
import org.apache.ignite.lang.IgniteProductVersion;
import org.apache.ignite.plugin.security.SecurityCredentials;
import org.apache.ignite.spi.discovery.DiscoverySpiNodeAuthenticator;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import java.util.Map;
public class CustomTcpDiscoverySpi extends TcpDiscoverySpi implements DiscoverySpiNodeAuthenticator {
SecurityCredentials securityCredentials;
public CustomTcpDiscoverySpi(final SecurityCredentials securityCredentials) {
this.securityCredentials = securityCredentials;
this.setAuthenticator(this);
}
#Override
public SecurityContext authenticateNode(ClusterNode clusterNode, SecurityCredentials securityCredentials) throws IgniteException {
return null;
}
#Override
public boolean isGlobalNodeAuthentication() {
return true;
}
#Override
public void setNodeAttributes(final Map<String, Object> attrs, final IgniteProductVersion ver) {
attrs.put(IgniteNodeAttributes.ATTR_SECURITY_CREDENTIALS, this.securityCredentials);
super.setNodeAttributes(attrs, ver);
}
}
And then, use it like below :
SecurityCredentials cred = new SecurityCredentials();
cred.setLogin(appConfig.getIgniteUser());
cred.setPassword(appConfig.getIgnitePassword());
CustomTcpDiscoverySpi spi = new CustomTcpDiscoverySpi(cred);
//TcpDiscoverySpi spi = new TcpDiscoverySpi(); - > removed to use the CustomTCPDiscovery
TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();
String ipList = appConfig.getIgniteIPAddressList();
List<String> addressList= Arrays.asList(ipList.split(";"));
ipFinder.setAddresses(addressList);
spi.setIpFinder(ipFinder);
IgniteConfiguration cfg = new IgniteConfiguration();
cfg.setIgniteInstanceName("IgnitePod");
cfg.setClientMode(true);
cfg.setAuthenticationEnabled(true);
// Ignite persistence configuration.
DataStorageConfiguration storageCfg = new DataStorageConfiguration();
// Enabling the persistence.
storageCfg.getDefaultDataRegionConfiguration().setPersistenceEnabled(true);
// Applying settings.
// tests
cfg.setDataStorageConfiguration(storageCfg);
cfg.setDiscoverySpi(spi);
Ignite ignite = Ignition.start(cfg);
Hope this helps other people who stuck with the same problem.

The only option for peer-authenticating server nodes which is available in vanilla Apache Ignite is SSL+certificates.

Related

Injecting custom datastax.session into Spring-Data Cassandra

Is it possible to use a custom datastax session for Spring-Data?
Hi, I know Spring-Data for Cassandra uses datastax session internally. However I have a custom datastax session object (given by another service) that I would like Spring-Data to use instead of the one prewired. Assuming the versions of both datastax sessions are the same, is this possible?
Yes, it's possible.
Depending on your setup, there are a couple of approaches. Let me explain the two most common scenarios:
Direct usage of Template API
Session yourSession = …;
CqlTemplate cqlTemplate = new CqlTemplate(yourSession);
CassandraTemplate cassandraTemplate = new CassandraTemplate(yourSession);
Exposing the Session as #Bean
This one might require a bit more setup as configuration support expects usage of CassandraSessionFactoryBean and CassandraClusterFactoryBean.
Take a look at AbstractCassandraConfiguration to see what supporting beans (CassandraConverter, CassandraMappingContext) are configured to configure Spring Data's Cassandra support.
#Configuration
class MyCassandraConfig {
private final Session mySession;
public MyCassandraConfig(Session mySession) {
this.mySession = mySession;
}
#Bean
public CassandraConverter cassandraConverter() {
MappingCassandraConverter mappingCassandraConverter = new MappingCassandraConverter(cassandraMapping());
mappingCassandraConverter.setCustomConversions(customConversions());
return mappingCassandraConverter;
}
#Bean
public CassandraMappingContext cassandraMapping() {
Cluster cluster = mySession.getCluster();
String keyspace = mySession.getLoggedKeyspace();
CassandraMappingContext mappingContext = new CassandraMappingContext(
new SimpleUserTypeResolver(cluster, keyspace), new SimpleTupleTypeFactory(cluster));
CustomConversions customConversions = customConversions();
mappingContext.setCustomConversions(customConversions);
mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder());
return mappingContext;
}
#Bean
public CustomConversions customConversions() {
return new CassandraCustomConversions(Collections.emptyList());
}
#Bean
public CassandraTemplate cassandraTemplate() {
return new CassandraTemplate(mySession, cassandraConverter());
}
}

Connecting to CRM Online through CRM 365 Plugin

I need to connect and retrieve records in CRM Online through CRM 365 plugin. I have tried simplified connection using xrm.tooling.dll but unfortunately it says Could not load file or assembly 'microsoft.xrm.tooling.connectorand when i used ClientCredential the error says Metadata contain refereces that cannot be resolved.
Strangely, i tried both method with console applcation and it's work prefectly. Just wanna knows what i miss in this case ? Do i need special requirement when i want to connect to CRM through plugin ? Please anybody share your knowledge.
EDIT
This just a sample code to get account name from CRM Online and display it using InvalidPluginExecutionException:
IOrganizationService _service;
public void Execute(IServiceProvider serviceprovider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceprovider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory servicefactory = (IOrganizationServiceFactory)serviceprovider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = servicefactory.CreateOrganizationService(context.UserId);
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
Entity ent = (Entity)context.InputParameters["Target"];
if (ent.LogicalName != "opportunity")
return;
string connstring = #"Url=https://office.crm5.dynamics.com; Username=username#office.onmicrosoft.com; Password=crmoffice; authtype=Office365";
CrmServiceClient conn = new Microsoft.Xrm.Tooling.Connector.CrmServiceClient(connstring);
service = (IOrganizationService)conn.OrganizationWebProxyClient != null ? (IOrganizationService)conn.OrganizationWebProxyClient :
(IOrganizationService)conn.OrganizationServiceProxy;
try
{
Guid fabercastel = new Guid("efd566dc-10ff-e511-80df-c4346bdcddc1");
Entity _account = new Entity("account");
_account = service.Retrieve(_account.LogicalName, fabercastel, new ColumnSet("name"));
string x = _account["name"].ToString();
throw new InvalidPluginExecutionException("Result of Query : " + x);
}
catch (Exception ex)
{
throw new InvalidPluginExecutionException(ex.Message);
}
You should be able to connect to another CRM instance without using any assemblies that are outside Online Sandbox (so other than Microsoft.Xrm.Sdk and related). Simply use the sample from SDK from "SDK\SampleCode\CS\GeneralProgramming\Authentication\AuthenticateWithNoHelp\AuthenticateWithNoHelp.cs". Simplified version for connecting to Office365 looks like that:
class AuthenticateWithNoHelp
{
private String _discoveryServiceAddress = "https://disco.crm.dynamics.com/XRMServices/2011/Discovery.svc";
private String _organizationUniqueName = "orgname";
private String _userName = "admin#orgname.onmicrosoft.com";
private String _password = "password";
private String _domain = "domain";
public void Run()
{
IServiceManagement<IDiscoveryService> serviceManagement =
ServiceConfigurationFactory.CreateManagement<IDiscoveryService>(
new Uri(_discoveryServiceAddress));
AuthenticationProviderType endpointType = serviceManagement.AuthenticationType;
AuthenticationCredentials authCredentials = GetCredentials(serviceManagement, endpointType);
String organizationUri = String.Empty;
using (DiscoveryServiceProxy discoveryProxy =
GetProxy<IDiscoveryService, DiscoveryServiceProxy>(serviceManagement, authCredentials))
{
if (discoveryProxy != null)
{
OrganizationDetailCollection orgs = DiscoverOrganizations(discoveryProxy);
organizationUri = FindOrganization(_organizationUniqueName,
orgs.ToArray()).Endpoints[EndpointType.OrganizationService];
}
}
if (!String.IsNullOrWhiteSpace(organizationUri))
{
IServiceManagement<IOrganizationService> orgServiceManagement =
ServiceConfigurationFactory.CreateManagement<IOrganizationService>(
new Uri(organizationUri));
AuthenticationCredentials credentials = GetCredentials(orgServiceManagement, endpointType);
using (OrganizationServiceProxy organizationProxy =
GetProxy<IOrganizationService, OrganizationServiceProxy>(orgServiceManagement, credentials))
{
organizationProxy.EnableProxyTypes();
Guid userid = ((WhoAmIResponse)organizationProxy.Execute(
new WhoAmIRequest())).UserId;
}
}
}
private AuthenticationCredentials GetCredentials<TService>(IServiceManagement<TService> service, AuthenticationProviderType endpointType)
{
AuthenticationCredentials authCredentials = new AuthenticationCredentials();
authCredentials.ClientCredentials.UserName.UserName = _userName;
authCredentials.ClientCredentials.UserName.Password = _password;
return authCredentials;
}
public OrganizationDetailCollection DiscoverOrganizations(
IDiscoveryService service)
{
if (service == null) throw new ArgumentNullException("service");
RetrieveOrganizationsRequest orgRequest = new RetrieveOrganizationsRequest();
RetrieveOrganizationsResponse orgResponse =
(RetrieveOrganizationsResponse)service.Execute(orgRequest);
return orgResponse.Details;
}
public OrganizationDetail FindOrganization(string orgUniqueName,
OrganizationDetail[] orgDetails)
{
if (String.IsNullOrWhiteSpace(orgUniqueName))
throw new ArgumentNullException("orgUniqueName");
if (orgDetails == null)
throw new ArgumentNullException("orgDetails");
OrganizationDetail orgDetail = null;
foreach (OrganizationDetail detail in orgDetails)
{
if (String.Compare(detail.UrlName, orgUniqueName,
StringComparison.InvariantCultureIgnoreCase) == 0)
{
orgDetail = detail;
break;
}
}
return orgDetail;
}
private TProxy GetProxy<TService, TProxy>(
IServiceManagement<TService> serviceManagement,
AuthenticationCredentials authCredentials)
where TService : class
where TProxy : ServiceProxy<TService>
{
Type classType = typeof(TProxy);
if (serviceManagement.AuthenticationType !=
AuthenticationProviderType.ActiveDirectory)
{
AuthenticationCredentials tokenCredentials =
serviceManagement.Authenticate(authCredentials);
return (TProxy)classType
.GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(SecurityTokenResponse) })
.Invoke(new object[] { serviceManagement, tokenCredentials.SecurityTokenResponse });
}
return (TProxy)classType
.GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(ClientCredentials) })
.Invoke(new object[] { serviceManagement, authCredentials.ClientCredentials });
}
static public void Main(string[] args)
{
AuthenticateWithNoHelp app = new AuthenticateWithNoHelp();
app.Run();
}
}
You can simplify it further by removing part with DiscoveryService and directly calling:
https://orgname.api.crm.dynamics.com/XRMServices/2011/Organization.svc
This should work on Sandboxed plugins as it uses only Sdk assemblies.
You already have your connection to CRM using the IOrganizationService that you've defined on the third line of your plugin. Unless you need to connect to another CRM instance in a different org, there is no login needed or required.
Basically just delete the 4 lines above your try, and you should be good.
Edit:
public void Execute(IServiceProvider serviceprovider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceprovider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory servicefactory = (IOrganizationServiceFactory)serviceprovider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = servicefactory.CreateOrganizationService(context.UserId);
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
Entity ent = (Entity)context.InputParameters["Target"];
if (ent.LogicalName != "opportunity")
return;
Guid fabercastel = new Guid("efd566dc-10ff-e511-80df-c4346bdcddc1");
Entity _account = new Entity("account");
_account = service.Retrieve(_account.LogicalName, fabercastel, new ColumnSet("name"));
string x = _account["name"].ToString();
throw new InvalidPluginExecutionException("Result of Query : " + x);
}
}
You do not need any additional libraries like Microsoft.Xrm.Tooling.Connector or others from SDK to consume CRM web services. Standard .NET mechanism related to SOAP / REST protocols will be enough (but of course this method may be little more difficult).
EDIT: I've made some additional investigation and it occurs that configuring auto-generated OrganizationServiceClient for Office365 authentication without using SDK libraries may be real pain in the ass. I'm not telling it is not possible however it is not documented by Microsoft. To add more details OAuth authentication is not supported by Visual Studio generated proxy classes.
Because of that - my second recommendation is to use facade web service communicating with CRM OnLine. You may host this web service on Windows Azure or any other cloud/hosting place in the internet. From your CRM 365 Plugin you may consume your custom web service methods and communicate with your CRM Online instance using this service. I suppose it will be much better approach that trying to run undocumented methods of connecting to CRM Online.**
You should be able to connect to another CRM instance without using any assemblies that are outside Online Sandbox (so other than Microsoft.Xrm.Sdk and related).
For example simply use the sample from SDK from SDK\SampleCode\CS\GeneralProgramming\Authentication\AuthenticateWithNoHelp\AuthenticateWithNoHelp.cs.

How to write client proxy for SPI and what the difference between client and server proxies?

I have developed own idGenerator based on Hazelcast IdGenerator class (with storing each last_used_id into db). Now I want to run hazelcast cluster as a single java application and my web-application as other app (web-application restart shouldn't move id values to next block). I move MyIdGeneratorProxy and MyIdGeneratorService to new application, run it, run web-application as a hazelcast-client and get
IllegalArgumentException: No factory registered for service: ecs:impl:idGeneratorService
It was okay when client and server were the same application.
It seems it's unable to process without some clientProxy. I have compared IdGeneratorProxy and ClientIdGeneratorProxy and it looks the same. What is the idea? How to write client proxy for services? I have found no documentation yet. Is direction of investigations correct? I thought it is possible to divide hazelcast inner services (like a id generator service) and my business-processes. Should I store custom ClientProxy (for custom spi) in my web-application?
This is a demo how to create a client proxy, the missing part CustomClientProxy function call, is quit complicated(more like a server proxy,here is called ReadRequest, the server is called Operation), you can find a how AtomicLong implement.For every client proxy method you have to make a request.
#Test
public void client() throws InterruptedException, IOException
{
ClientConfig cfg = new XmlClientConfigBuilder("hazelcast-client.xml").build();
ServiceConfig serviceConfig = new ServiceConfig();
serviceConfig.setName(ConnectorService.NAME)
.setClassName(ConnectorService.class.getCanonicalName())
.setEnabled(true);
ProxyFactoryConfig proxyFactoryConfig = new ProxyFactoryConfig();
proxyFactoryConfig.setService(ConnectorService.NAME);
proxyFactoryConfig.setClassName(CustomProxyFactory.class.getName());
cfg.addProxyFactoryConfig(proxyFactoryConfig);
HazelcastInstance hz = HazelcastClient.newHazelcastClient(cfg);
Thread.sleep(1000);
for (int i = 0; i < 10; i++)
{
Connector c = hz.getDistributedObject(ConnectorService.NAME, "Connector:" + ThreadLocalRandom.current()
.nextInt(10000));
System.out.println(c.snapshot());
}
}
private static class CustomProxyFactory implements ClientProxyFactory
{
#Override
public ClientProxy create(String id)
{
return new CustomClientProxy(ConnectorService.NAME, id);
}
}
private static class CustomClientProxy extends ClientProxy implements Connector
{
protected CustomClientProxy(String serviceName, String objectName)
{
super(serviceName, objectName);
}
#Override
public ConnectorState snapshot()
{
return null;
}
#Override
public void loadState(ConnectorState state)
{
}
#Override
public boolean reconnect(HostNode node)
{
return false;
}
#Override
public boolean connect()
{
return false;
}
}
EDIT
In hazelcast the IdGenerate is implemented as a wrapper for AtomicLong, you should implement you IdGenerate by you own, instead of extend IdGenerate.
So you have to implement these(more like a todo list XD):
API
interface MyIdGenerate
Server
MyIdGenerateService
MyIdGenerateProxy
MyIdGenerateXXXOperation
Client
ClientMyIdGenerateFactory
ClientMyIdGenerateProxy
MyIdGenerateXXXRequest
I also made a sequence(same as IdGenerate) here, this is backed by zookeeper or redis,also it's easy to add a db backend,too.I will integrate to hazelcast if I got time.

How can I instantiate OWIN IDataProtectionProvider in Azure Web Jobs?

I need an instance of IDataProtectionProvider to generate email confirmation tokens using the Identity Framework UserManager in an Azure Web Jobs worker:
var confirmToken = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
This crashes because a null IUserTokenProvider<User, int> was passed to the UserManager<User, int> upon constuction.
In the MVC application an instance is created like this:
public class OWINStartup
{
public void Configuration(IAppBuilder app)
{
var dataProtectionProvider = app.GetDataProtectionProvider();
But of course, Azure Web Jobs doesn't have an OWINStartup hook. Any advice?
Taking a look at the Katana source code for the OWIN startup context you can see the default implementation of the DataProtectionProvider is a MachineKeyDataProtectionProvider. Unfortunately this class is not exposed to us, only the DpapiDataProtectionProvider which will not work when hosted in azure.
You can find the implementation of the MachineKeyDataProtectionProvider here. You will need to also implement your own MachineKeyDataProtector as seen here. These are not difficult implmentations and are essentially wrappers around MachineKey.Protect() and MachineKey.Unprotect().
The implementation for MachineKeyDataProtectionProvider and MachineKeyDataProtector from the Katana project source (apache 2.0 license):
internal class MachineKeyProtectionProvider : IDataProtectionProvider
{
public IDataProtector Create(params string[] purposes)
{
return new MachineKeyDataProtector(purposes);
}
}
internal class MachineKeyDataProtector : IDataProtector
{
private readonly string[] _purposes;
public MachineKeyDataProtector(string[] purposes)
{
_purposes = purposes;
}
public byte[] Protect(byte[] userData)
{
return MachineKey.Protect(userData, _purposes);
}
public byte[] Unprotect(byte[] protectedData)
{
return MachineKey.Unprotect(protectedData, _purposes);
}
}
Once you have that implemented it is easy to plug into the UserManager:
var usermanager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>());
var machineKeyProtectionProvider = new MachineKeyProtectionProvider();
usermanager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(machineKeyProtectionProvider.Create("ASP.NET Identity"));
Hope that helps get you in the right direction.

"error": "invalid_client" from custom OWIN implementation

I am implementing OWIN authentication on a mysql backend, I dont thnk thats a problem as my registration work pretty well. I have basically worked off this post (i.e. nicked most of the code).
I am also using DI via autofac so I have changed a few things around to inject dependencies into the SimpleAuthorizationServerProvider
THE PROBLEM
I post grant_type=password, username and password to http://localhost/myappurl/token and I get back "error":"invalid_client". I get no hits when I try to debug so its probably failing in the library and not getting to my own code. Does anyone know why this would be?
Please pardon the lengthy code, I have no idea where the issue could be so I have posted everything I think is relevant, if anyone needs to see more code, please ask.
SimpleAuthorizationServerProvider
public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
private readonly IUserService _userService;
public SimpleAuthorizationServerProvider(IUserService userService)
{
_userService = userService;
}
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated();
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
var authenticate = await _userService.FindUser(context.UserName, context.Password);
if (!authenticate)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim("sub", context.UserName));
identity.AddClaim(new Claim("role", "user"));
context.Validated(identity);
}
}
Startup
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
ConfigureOAuth(app, (IOAuthAuthorizationServerProvider)config.DependencyResolver.GetService(typeof(IOAuthAuthorizationServerProvider)));
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
public void ConfigureOAuth(IAppBuilder app, IOAuthAuthorizationServerProvider provider)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(90),
Provider = provider,
ApplicationCanDisplayErrors=true,
};
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
}
IocConfig
public static class IocConfig
{
public static void Register(HttpConfiguration config)
{
var builder = new ContainerBuilder();
// Configure the container
// Register individual components
builder.Register(c => new MySQLContext()).As<IMySqlContext>().InstancePerRequest();
builder.RegisterType<SimpleAuthorizationServerProvider>().As<IOAuthAuthorizationServerProvider>();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}
}
You have a lot of code there, so it's not easy to isolate the problem. As a first step, consider removing the code for Autofac DI and see if that makes any difference. It's hard to tell what the problem might be otherwise.
If the issue is indeed related to the DI code, then perhaps this should be a raised as a separate question. In that case, try to create a small code example that demonstrates the issue succinctly. People are more likely to help if the problem code is short and to the point.
Make sure that you've set up SSL for your site. I had a similar issue and the problem was that I was not using SSL.

Resources