Exemple #1
0
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddGrpc();

            services.AddCors(o => o.AddPolicy("AllowAll", builder =>
            {
                builder.AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader()
                .WithExposedHeaders("Grpc-Status", "Grpc-Message");
            }));

            services.AddTransient(typeof(IAppLogger <>), typeof(LoggerAdapter <>));

            services.AddScoped <IPhotosService, Backend.Core.Services.PhotosService>();
            services.AddScoped <IPhotosRepository, PhotosRepository>();

            services.AddDbContext <PhotoSharingApplicationContext>(options =>
                                                                   options.UseSqlServer(Configuration.GetConnectionString("PhotoSharingApplicationContext")));

            services.AddAuthentication("Bearer")
            .AddJwtBearer("Bearer", options =>
            {
                options.Authority            = "http://localhost:5000";
                options.RequireHttpsMetadata = false;
                options.TokenValidationParameters.NameClaimType = JwtClaimTypes.Name;
                options.Audience = "photos";
            });

            //don't know if this is going to work, had to add it, found on
            //https://github.com/grpc/grpc-dotnet/blob/master/examples/Ticketer/Server/Startup.cs
            services.AddAuthorization(options =>
            {
                options.AddPolicy(JwtBearerDefaults.AuthenticationScheme, policy =>
                {
                    policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
                    policy.RequireClaim(JwtClaimTypes.Name);
                });

                //found on https://chrissainty.com/securing-your-blazor-apps-configuring-policy-based-authorization-with-blazor/
                options.AddPolicy(Policies.EditDeletePhoto, Policies.CanEditDeletePhotoPolicy());
            });

            services.AddSingleton <IAuthorizationHandler, PhotoEditDeleteAuthorizationHandler>();

            //        services.AddIdentity<User, IdentityRole>(options =>
            //        {
            //            ...
            //options.ClaimsIdentity.UserIdClaimType = JwtRegisteredClaimNames.Sub;
            //        })
        }
        public static async Task Main(string[] args)
        {
            //Update service registrations that depend on IAccessTokenProvider to be scoped services instead of singleton services!

            var builder = WebAssemblyHostBuilder.CreateDefault(args);

            builder.RootComponents.Add <App>("app");

            builder.Services.AddSingleton(new HttpClient {
                BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
            });
            builder.Services.AddOidcAuthentication(options =>
            {
                //builder.Configuration.Bind("Local", options.ProviderOptions);
                // Configure your authentication provider options here.
                // For more information, see https://aka.ms/blazor-standalone-auth
                options.ProviderOptions.Authority = "http://localhost:5000"; // "https://localhost:5001";
                options.ProviderOptions.ClientId  = "blazorstandalone";

                options.ProviderOptions.ResponseType = "code";         //this is fundamental to talk to Identity Server 4

                options.ProviderOptions.DefaultScopes.Add("photos");   //you add these so that the user can consent
                options.ProviderOptions.DefaultScopes.Add("photosrest");
                options.ProviderOptions.DefaultScopes.Add("comments"); //and the access token contains the granted audiences
            });

            #region grpcPhotos
            //            builder.Services.AddSingleton(services =>
            //            {
            //#if DEBUG
            //                var backendUrl = "https://localhost:5011"; // Local debug URL
            //#else
            //                var backendUrl = "https://localhost:5011"; // Production URL
            //#endif

            //                // Now we can instantiate gRPC clients for this channel
            //                var httpClient = new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
            //                var channel = GrpcChannel.ForAddress(backendUrl, new GrpcChannelOptions { HttpClient = httpClient });
            //                return new Photosthingpackage.PhotosThing.PhotosThingClient(channel);
            //            });

            //            builder.Services.AddTransient<IPhotosService, PhotosService>();
            //            builder.Services.AddTransient<IPhotosRepository, PhotosGrpcClient>();
            #endregion

            #region WebApiPhotos
            builder.Services.AddSingleton(
                new HttpClient
            {
                BaseAddress = new Uri("https://localhost:5041/api/photos/")
            });

            builder.Services.AddTransient <IPhotosService, PhotosService>();
            builder.Services.AddTransient <IPhotosRepository, PhotosApiClient>();

            #endregion

            #region gRPCComments
            builder.Services.AddSingleton(services =>
            {
#if DEBUG
                var backendUrl = "https://localhost:5021"; // Local debug URL
#else
                var backendUrl = "https://localhost:5021"; // Production URL
#endif

                // Now we can instantiate gRPC clients for this channel
                var httpClient = new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
                var channel    = GrpcChannel.ForAddress(backendUrl, new GrpcChannelOptions {
                    HttpClient = httpClient
                });
                return(new Commentsthingpackage.CommentsThing.CommentsThingClient(channel));
            });
            #endregion
            builder.Services.AddTransient <ICommentsService, CommentsService>();
            builder.Services.AddTransient <ICommentsRepository, CommentsGrpcClient>();

            builder.Services
            .AddBlazorise(options =>
            {
                options.ChangeTextOnKeyPress = true;
            })
            .AddBootstrapProviders()
            .AddFontAwesomeIcons();

            builder.Services.AddAuthorizationCore(options =>
            {
                options.AddPolicy(Policies.EditDeletePhoto, Policies.CanEditDeletePhotoPolicy());
                options.AddPolicy(Policies.EditDeleteComment, Policies.CanEditDeleteCommentPolicy());
            });

            builder.Services.AddSingleton <IAuthorizationHandler, PhotoEditDeleteAuthorizationHandler>();
            builder.Services.AddSingleton <IAuthorizationHandler, CommentEditDeleteAuthorizationHandler>();

            var host = builder.Build();

            host.Services
            .UseBootstrapProviders()
            .UseFontAwesomeIcons();

            await host.RunAsync();
        }