Avatar billede pablopablo Nybegynder
24. juli 2008 - 20:35 Der er 38 kommentarer og
1 løsning

HttpHandler og Blokering af IP

Hejsa...

Nogen her, som kan hjælpe mig med kode til en HttpHandler, som kan blokkere for IP adresser?

Mvh. PabloPablo
Avatar billede pablopablo Nybegynder
24. juli 2008 - 21:09 #1
Avatar billede arne_v Ekspert
25. juli 2008 - 01:05 #2
Ja.

Jeg ville nok skrive det IHttpModule en lille smule anderledes, men det er ikke
et andet design - bare lidt bedre kode.
Avatar billede arne_v Ekspert
25. juli 2008 - 01:06 #3
Avatar billede pablopablo Nybegynder
25. juli 2008 - 01:14 #4
Hej Arne!

Ok, altså jeg er interesseret i den bedste løsning når vi snakker om performance...jeg har implementeret den løsning jeg linkede til, og mine blokkerede IP'er ligger i min db...ved ikke om det er for resourcekrævende at lave et db kald hver gang?

Hvad ser du som den optimale løsning? Hvad ville du evt. rette i IHttpModul'et?
Avatar billede arne_v Ekspert
25. juli 2008 - 01:24 #5
Nu var det slet ikke bedre kode på det niveau.

Min lile demo ser ud som:

using System;
using System.Web;

public class BlockerModule : IHttpModule
{
    public void Init(HttpApplication app)
    {
        app.BeginRequest += OnBeginRequest;
    }
    protected void OnBeginRequest(object sender, EventArgs e)
    {
        HttpApplication app = (HttpApplication)sender;
        string ip = app.Context.Request.UserHostAddress;
        if(ip == "192.168.0.10" || ip == "192.168.0.11")
        {
            app.Context.Response.StatusCode = 403;
            app.Context.Response.SuppressContent = true;
            app.Context.Response.End();
        }
    }
    public void Dispose()
    {
    }
}

Nogle færre linier !
Avatar billede arne_v Ekspert
25. juli 2008 - 01:26 #6
Med hensyn til optimal opbevaring af IP adresserne, så læs dem op i et Dictionary
i Init og slå op i det i OnBeginRequest.

Det er så ligegyldigt om du gemmer i fil eller database.
Avatar billede pablopablo Nybegynder
25. juli 2008 - 01:29 #7
I see...

Ja, det med at hardcode IP'erne ind var også min første tanke...men det er en bestemt type af brugere, som skal have adgang til at blokkere andre brugere, og det skal de kunne ved blot at klikke på en knap, i forskellige UI, dvs. både via asp.net og flash, derfor lagde jeg IP'erne i db...men er det så skidt? Synes du jeg skal prøve, at læse/skrive til en txt-fil på serveren i stedet for? Vinder jeg meget på det tror du?
Avatar billede pablopablo Nybegynder
25. juli 2008 - 01:31 #8
okey...hmm...ang. Dictionary...kan du vise mig hvordan du vil gøre det? Bliver det så gemt i brugerens Session data eller?
Avatar billede arne_v Ekspert
25. juli 2008 - 01:39 #9
Næh. Bare i modulet.

using System;
using System.Collections.Generic;
using System.Web;

public class BlockerModule : IHttpModule
{
    private Dictionary<string,string> banlist;
    public void Init(HttpApplication app)
    {
        banlist = new Dictionary<string,string>();
        // læs banlist fra fil eller database - her tildeler vi bare et par værdier
        banlist.Add("192.168.0.10", "Ingen adgang");
        banlist.Add("192.168.0.11", "Forsvind");
        app.BeginRequest += OnBeginRequest;
    }
    protected void OnBeginRequest(object sender, EventArgs e)
    {
        HttpApplication app = (HttpApplication)sender;
        string ip = app.Context.Request.UserHostAddress;
        if(banlist.ContainsKey(ip))
        {
            app.Context.Response.StatusCode = 403;
            app.Context.Response.StatusDescription = banlist[ip];
            app.Context.Response.SuppressContent = true;
            app.Context.Response.End();
        }
    }
    public void Dispose()
    {
    }
}
Avatar billede arne_v Ekspert
25. juli 2008 - 01:42 #10
Og database er helt fint.

Jeg gider bare ikke oprette en tabel og læse fra den for at skrive denne demo kode.
Avatar billede pablopablo Nybegynder
25. juli 2008 - 01:54 #11
aarh...det er bare en collection, kunne i pricipper også bruge en arraylist eller lign...

hhmmm...Jeg er nok ikke helt med, når du skriver i ovenstående kode at jeg kan hente IPs fra db...Det må selvfølgelig være fordi at INIT metoden ikke bliver kaldt så ofte som OnBeginRequest...Men fortæl mig lige, hvor ofte/hvornår kaldes INIT metoden?
Avatar billede arne_v Ekspert
25. juli 2008 - 01:54 #12
Ah - der er natturligvis lige en lille finesse med database og den Dictionary.

Hvis ikke du vil restarte web app efter ændringer er du nødt til enten at opdatere
eller reloade den Dictionary.

Hvis du gemmer den i Application er det nemt at lade din management kode opdatere den.
Avatar billede arne_v Ekspert
25. juli 2008 - 01:57 #13
Init bliver kun kaldt en gang efter hver genstart af web app.
Avatar billede pablopablo Nybegynder
25. juli 2008 - 02:06 #14
Dvs.... er INIT kode bliver hvad..? Kun kaldt én eneste gang? eller?

Ja, man kan opdatere Dictionary via et db kald...men hvor vil det være hensigtmæssigt at lave det db kald?
Avatar billede pablopablo Nybegynder
25. juli 2008 - 02:14 #15
Okey...I got it ;)

Dvs. hver gang en ny brugeren åben min side i fx. IE så kaldes INIT metoden, og de efterfølgende request i samme browser vindue tricker ikke INIT metoden?
Avatar billede arne_v Ekspert
25. juli 2008 - 02:22 #16
Nej. Init kaldes kun når serveren starter op eller web app genstartes. En gang om dagen eller en gang
om ugen.
Avatar billede pablopablo Nybegynder
25. juli 2008 - 02:23 #17
Hvis jeg har forstået det korrekt....så læg blot et svar Arne!

Nu hvor jeg har dig...kender du svaret på:

http://www.eksperten.dk/spm/839381
Avatar billede arne_v Ekspert
25. juli 2008 - 02:23 #18
Du lader den side som opdaterer DB også opdate din ban liste (som så skal flyttes
fra module instans til Application objektet).
Avatar billede arne_v Ekspert
25. juli 2008 - 02:24 #19
Desværre ikke. Det er sådan noget browser HTML noget. Det har jeg ikke forstand på.
Avatar billede arne_v Ekspert
25. juli 2008 - 02:25 #20
Og et svar
Avatar billede pablopablo Nybegynder
25. juli 2008 - 02:29 #21
nå for søren...ja det duer ikke umiddelbart...den skulle jo gerne virke, uden jeg behøves at pille ved serveren eller uploade noget på ny uden grund...

Hvordan laves det således, at collectionen KUN bliver fyldt op, hver gang en ny bruger viser siden?
Avatar billede arne_v Ekspert
25. juli 2008 - 02:48 #22
Det virker da perfekt.

Den loader fra databasen op i memory ved start af web app.

Ved hver request slår den brugerens IP op i memory.

Hvis du vil opdatere ban listen uden at genstarte web app, så skal den side som
opdatere både opdatere databasen og in memory kopien.
Avatar billede pablopablo Nybegynder
25. juli 2008 - 02:51 #23
Hvad med at lægge noget logik i global asax filen? Session_Start lyder lige som det man kunne bruge??
Avatar billede pablopablo Nybegynder
25. juli 2008 - 02:56 #24
Dvs. hvis vi ref. til din ovenstående kode, så mener du, at jeg skal indsætte et db kald i OnBeginRequest metoden? Eller hvad? I så fald, kaldes db jo for hvert request? Kan du give mig et eksempel, det tror jeg hurtigere jeg forstår...
Avatar billede arne_v Ekspert
25. juli 2008 - 02:59 #25
Nej.

Læsning fra database skal sættes ind her:

        // læs banlist fra fil eller database - her tildeler vi bare et par værdier
        banlist.Add("192.168.0.10", "Ingen adgang");
        banlist.Add("192.168.0.11", "Forsvind");
Avatar billede pablopablo Nybegynder
25. juli 2008 - 03:00 #26
hvorfor kan global asax filen ikke benyttes?

Jeg er ikke med, det er jo i init metode, som IKKE opdateres løbende som jeg ønsker...
Avatar billede arne_v Ekspert
25. juli 2008 - 03:04 #27
Et HTTP modul og global.asax kan ca. det samme, så det kan du muligvis også.

De 3 linier er i Init, så der kun læses fra databasen en gang.
Avatar billede arne_v Ekspert
25. juli 2008 - 03:05 #28
Du kan så tilføje:

Application["banlist"] = banlist;

således at din side som opdaterer bannede IP numre har mulighed for at opdatere
in memory kopien også.

(og principielt behøver banlist ikke være en instans member længere, fordi request
handleren også kan hente fra Application)
Avatar billede pablopablo Nybegynder
25. juli 2008 - 03:14 #29
hvis det ikke er en dårligere løsning, at bruge global.asax så virker det da meget mere lige til? Session_Start kaldes jo kun, for det første request, som tilhøre en given session...dermed kan man bare tjekke Ip'en via en stored procedure direkte der hver gang, når det er nødvendigt. Så slippen man for at holde styr på collections mv...eller er det bare mig som tror det er smart?? :)

Jeg er efterhånden med på alt det du har forklaret...dog har jeg misset én ting og det er, at når jeg ønsker, at opdaterer collectionen via db, så skal jeg jo tilgå collection i Http modulet fra et eller andet sted fra mit asp.net projekt...hvordan gør man det? (Hvis det er tilfældet, tror jeg det bliver en lidt besværlig løsning, når det også skal kunne kaldes fra flash)
Avatar billede arne_v Ekspert
25. juli 2008 - 03:19 #30
Hvis du kun vil checke ved session start, så kan det lade sig gøre med HTTP Module.
Men ved opslag i Dictionary så koster det ingenting at teste hver request.

Et opslag i DB ved hver session creation er langt dyrere end at loade alle
ved start af web app.
Avatar billede arne_v Ekspert
25. juli 2008 - 03:21 #31
Hvis du har tilføjet:

Application["banlist"] = banlist;

i Init, så kan din opdaterende side lave:

(Dictionary<string,string>Application["banlist"]).Add(nyip, nytext);
Avatar billede pablopablo Nybegynder
25. juli 2008 - 03:21 #32
"(og principielt behøver banlist ikke være en instans member længere, fordi request
handleren også kan hente fra Application)"

Forstår ikke den sidste del, af det...

Men forstår at man kan tilgå request handleren via et key-index i Application, korrekt? Altså gemme handleren deri og derigennem tilgå banlisten? eller hvad?

Af ren interesse, kan du vise mig det?
Avatar billede arne_v Ekspert
25. juli 2008 - 03:25 #33
Ja.

Vise hvad ? Det citerede ?
Avatar billede pablopablo Nybegynder
25. juli 2008 - 03:31 #34
hehe, OK! Så er jeg helt med!
Det sidste problem er så bare, at jeg ikke kan se, hvordan jeg kan kaldes:
(Dictionary<string,string>Application["banlist"]).Add(nyip, nytext); fra flash af...hehe...eller i hvert fald sætte noget i gang, som resulterer i det samme...

Hvis jeg nu siger, at jeg kan kalde en JS metode fra flash, kan det så bruges til et eller andet i denne sammenhæng? ved godt at alt det andet køre server side...
Avatar billede arne_v Ekspert
25. juli 2008 - 11:57 #35
Flash kører client side.

Det her skal køres server side.

Så det kan du ikke.

Du kan lade din flash sende en HTTP request til en side som gøre det.
Avatar billede pablopablo Nybegynder
08. august 2008 - 21:28 #36
Hej Arne >> kan et importeret dot net assembly / en dll fil godt tilgå min "banlist"?

Hvis det er muligt, hvordan ser koden så ud?? Jeg opretter gerne en ny tråd hvis du ønsker flere points...
Avatar billede arne_v Ekspert
09. august 2008 - 02:20 #37
En vilkårlig DLL bør kunne bruge

(Dictionary<string,string>HttpContext.Current.Application["banlist"])
Avatar billede pablopablo Nybegynder
09. august 2008 - 03:31 #38
Hej Arne!

Yes! Jeg fandt den selv...

((Dictionary<string, string>)HttpContext.Current.ApplicationInstance.Context.Application["banlist"].... der er vel ikke forskel på din og min version? Det virker i hvert fald?
Avatar billede arne_v Ekspert
09. august 2008 - 04:14 #39
Jeg tror at de gør det samme.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester