Posts tagged tipy

Komunikace se zabezpecenymi webovymi sluzbami

0

Dnes jsem se trapil s tvorbou klienta, ktery se mel pripojit na vzdalenou webovou sluzbu s klientskym certifikatem a predevsim – autentikovat se pomoci jmena a hesla. Nakonec se chyba ukazala byt trochu jinde, nez jsem ji cekal, ale kdyz uz jsem s tim stravil cas, tak to tu trochu popisu, kdyby nahodou nekdo resil podobny problem.

Nejprve ona chyba – mam zdrojak pro klienta vygenerovany pomoci wsimportu a protoze jsem se snazil o univerzalni reseni, adresa koncoveho bodu je v .properties souboru. Lokalne mam ovsem ulozeny wsdl, na ktery se odkazuju pomoci anotace @WebServiceClient ve tride klienta:

@WebServiceClient(
    name = "myService",
    targetNamespace = "http://www.shmoula.cz/my/service",
    wsdlLocation = "META-INF/wsdl/myService.wsdl")
public class MyServiceClient extends Service{
 

No a tohle byl muj problem – toto lokalni wsdl se neshodovalo s deskriptorem na druhe strane (odstranil jsem policy cast), takze mi server porad odmital pozadavky:

javax.xml.ws.WebServiceException: Failed to access the WSDL at: https://shmoula.cz:8080/myService?wsdl. It failed with:
Connection refused.

Stacilo zmenit wsdlLocation na adresu deskriptoru na serveru a vse uz bezi v poradku. Hadam, ze kdyby lokalni wsdl presne odpovidalo tomu na serveru, fungovalo by to taky. Ted ale to podstatnejsi – jak autentikovat uzivatele?

Nejprve mejme vygenerovany a naimportovany certifikat v trusted certs, napr. pomoci keytool:

keytool -import -alias shmoula.cz -file certifikat.shmoula.cz.der -keystore <J2EE_HOME>/domains/domain1/config/cacerts.jks

Potom budeme potrebovat vlastni implementaci tridy Authenticator, kterou zajistime, aby byly autentikacni informace predavany pouze pri zabezpecenem spojeni:

package cz.shmoula.klient;

import java.net.Authenticator;
import java.net.PasswordAuthentication;

public class BasicHTTPAuthenticator extends Authenticator {
  private String userName;
  private String password;

  public BasicHTTPAuthenticator(String userName, String password){
    this.userName = userName;
    this.password = password;
  }

  @Override
  protected PasswordAuthentication getPasswordAuthentication(){
    if (this.getRequestingProtocol().equalsIgnoreCase("https"))
        return new PasswordAuthentication(userName, password.toCharArray());
    else
        return null;
  }

  public String getUserName() {
    return userName;
  }

  public void setUserName(String userName) {
    this.userName = userName;
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }
}

V aplikaci je potom nutne nejprve nastavit tento autentikator a teprve pote vytvorit instanci klienta:

URL baseUrl = cz.shmoula.klient.MyServiceClient.class.getResource(".");
URL url = new URL(baseUrl, "https://shmoula.cz:8080/myService?wsdl");
QName qName = new QName("http://www.shmoula.cz/myservice", "myService");

Authenticator.setDefault(new BasicHTTPAuthenticator("jmeno", "heslo"));
MyServiceIface service = new MyServiceClient(url, qName).getMyServicePort();

Pote je nutne jeste poupravit kontext pozadavku pomoci BindingProvidera a je mozne se pustit do volani vzdalenych metod, vse zabezpeceno:

BindingProvider bp = (BindingProvider) service;
bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "jmeno");
bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "heslo");
MyServiceResponse resp = service.makeCall(foo, bar);

Abych pravdu rekl, prestava se mi to libit cim dal tim vic, asi se vratim k JSONu. Podstatne je, ze to mam z krku.

Validace vstupu webových služeb

0

Potřeboval jsem validovat vstup webové služby na základě xsd šablony – a to jak typy, tak patterny a potřeboval jsem to pokud možno obecně a jednoduše. Postupně jsem se dobral řešení, které se pokusím níže popsat.

Měl jsem zadaný wsdl dokument, k němu definici typů v xsd a příkaz použít jax-ws. Takže jsem provedl wsimport a začal zkoušet. Na komplexní typy byl pomocí jaxb vytvořen binding, takže mi vznikla trochu poschoďovější struktura, která ovšem nebrala v úvahu definované simple typy a prostě je převedla na podobné typy jazyka Java. Pokud jsem tento projekt spustil na serveru, patterny těchto typů prostě zmizely a vygenerované xsd bylo úplně jiné, wsdl se jakž-takž podobalo. Stačilo ovšem přidat parametr k anotaci WebService, který specifikoval cestu k originálnímu wsdl.

@WebService(
    name = &quot;myServiceSei&quot;,
    targetNamespace = &quot;http://www.shmoula.cz/schema/myservice&quot;,
    wsdlLocation = &quot;META-INF/wsdl/myService.wsdl&quot;
)

V tomto okamžiku jsem měl ovšem problém s bindingem, který jsem původně přiřazoval nějaké chybičce ve jmenných prostorech, a ten způsoboval, že mi služba předávala null hodnoty. Nakonec se ukázalo, že v zadaném wsdl se vyskytuje zpráva z názvem doSomeStuffRequest, který se kryl s elementem ve vlastním těle této zprávy (navíc jax-ws přidává postfix Request automaticky), takže stačilo tento název změnit a vše bylo v pořádku a já byl o krok blíže k validování.

První, co mě napadlo, bylo použití anotace SchemaValidation, tak jsem ji použil. Služba se ovšem chovala, jako by tam tato anotace vůbec nebyla a prošlo naprosto všechno. Tudíž nastoupilo řešení číslo dvě – použítí Marshalleru, který by měl při nesrovnalostech skončit s výjimkou. Končil, ovšem s výjimkou jinou, než jsem čekal.

unable to marshal type "cz.foo.bar.DoSomeStuffRequest" as an element because it is missing an @XmlRootElement annotation

Důvody jejího vzniku pěkně rozebral Kohsuke Kawaguchi ve svém blogpostu a protože jsem nechtěl do všech typů cpát XmlRootElement, řídil jsem se jí a dobral se funkčnosti – opravdu mi to validuje! Ještě jsem si s řešením trochu pohrál a především využil vygenerované ObjectFactory, abych nemusel vytvářet vlastní JAXBElement. Výsledek vypadá (zhruba) následovně a funguje na výbornou.

@WebMethod
public void doSomeStuff(DoSomeStuffRequest serviceParameters) {

    ObjectFactory of = new ObjectFactory();
    JAXBElement&lt;DoSomeStuffRequest&gt; element = of.createParcelImportRequest(serviceParameters);
    SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);

    try {
        URLClassLoader cl = (URLClassLoader) getClass().getClassLoader();
        URL url = cl.findResource(&quot;META-INF/wsdl/myService.xsd&quot;);

        Schema schema = sf.newSchema(url);

        JAXBContext context = JAXBContext.newInstance(DoSomeStuffRequest.class);

        Marshaller marshaller = context.createMarshaller();
        marshaller.setSchema(schema);

        marshaller.marshal(element, new DefaultHandler());

    } catch (SAXException e) {
        e.printStackTrace();
    } catch (JAXBException e) {
        e.printStackTrace();
    }
}

PS. Nic to ovšem nemění na tom, že SOAP není mrtvý, ale nemrtvý (a vůbec že je to fuj)!

Nový blog

0

Respektive staronový – už dlouho mi stávající blog běžící na Drupalu pil krev – spam, „rychlost“, mobilní přístup… takže když jsem stál před rozhodnutím, jestli přejít na novější verzi drupalu, nebo přejít na WordPress, bylo jasno. Váhání napomohla ještě aplikačka pro Android.

Portace se neobešla bez potíží. Nejprve jsem zkoušel provést import pomocí skriptů v Ruby vytvořených pro songbird, ale potom, co se mi podařilo přimět hostingovou společnost, aby mi zpřístupnili databázi zvenčí, jsem zjistil, že to nebude tak jednoduché. Skripty jsem z velké části přepsal, ale stejně pořád nefungovaly, tak jsem se na to vyprdl a udělal to „po svém“.

Image and video hosting by TinyPic

Po chvíli googlení jsem našel rozumné howto, podle kterého jsem přesunul databáze na lokále a potom importoval na shmoula.cz. Export databáze z Drupalu má 12Megabajtů a po převedení do WordPressu má databáze něco nad jeden megabajt. To je mi teda rozdíl!! Ale stejně, napsal jsem toho docela dost, měl bych někde namasírovat ego v Hulán-stylu :-D.

Vybírám licenci pro geoANDhash

0

Když jsem doposud páchal jakýkoliv projekt, většinou jsem si nechal zdrojáky pro sebe a výslednou podobu jsem nějak vypustil mezi širokou veřejnost, šiř se jak šiř. Teď jsem však dospěl do fáze, kdy bych se rád nějakým způsobem podělil i o zdrojový kód, aby se mohli připojit další, resp. chcisi nechat projekt hostovat na google code a při registraci je potřeba uvést, pod jakou licencí je daný kód možné šířit. Proto bych chtěl vyzkoumat, která licence by pro mě byla nejvhodnější.

Nejvhodnější vlastnosti by pro mě měla zřejmě Creative Commons – Attribution-Share Alike 3.0 Unported, která povoluje šířit a modifikovat za podmínek, že produkt bude označen dle mých podmínek a pokud bude pozměněn, musí být dále šířen pod toutéž licencí, nebo licencí kompatibilní.

http://www.czilla.cz/podpora/shrnuti-mpl.html

http://www.root.cz/clanky/gnugpl-pravni-rozbor-licence/

http://www.martinvseticka.eu/index.php?sekce=browse&page=137

http://www.gnu.cz/article/30/

http://cs.wikipedia.org/wiki/BSD_licence

http://www.it-joker.cz/Pocitace-weby/71-Obsah-zdarma-a-licence,-aneb-jak-se-v-nich-vyznat.html

Geohashing

0

Jaro je čas, který s sebou přináší nové touhy a plány do budoucna. I na mě se jednou za čas přilepí pocit vyzkoušet něco nového, případně někde narazím na něco, co mě dokáže totálně pobláznit a definitivně tomu propadnout, než celý tento stav ve velmi brzké době zase nezmizí :-). Ne, nemám na mysli jarní zapalování lýtek mých vlastních, ani odhalování lýtek příslušnic něžného pohlaví. Mám na mysli věc mnohem více nerdí, ke které je spíše než vymýšlení originálního oslovení potřeba umět zahashovat řetězec algoritmem MD5. Mám na mysli Geohashing.

Image and video hosting by TinyPic

Ano, opravdu Geohashing, ne Geocaching, nespletl jsem se. Ovšem princip je velice podobný. Taky je k němu zapotřebí znát nějaké souřadnice, GPSka taky přijde vhod, stejně tak připojení k internetu pro získání Dow Jonesova indexu. Ale popořadě. V květnu 2008 vyšel na xkcd strip popisující algoritmus, jak získat náhodné souřadnice v rámci určité oblasti na celé zeměkouli. Představa je taková, že celý svět je rozdělen do mřížky 1×1 stupeň vždy počínaje celým číslem severní šířky a celým číslem východní délky o velikosti přibližně 110x110km. Každá takováto buňka se nazývá „gratikula“ (eng. graticule), která je většinou pojmenovaná podle největšího města, které v této oblasti leží. Každý den je na základě výše zmíněného Dow Jonesova indexu (ukazatel vývoje na americkém akciovém trhu, defakto jakýsi generátor pseudonáhodného čísla) vygenerována hodnota, která je spojena s aktuálním datem a zahashovaná algoritmem MD5. Výsledný 32bitový řetězec je rozdělen na dvě části, z nichž jedna po převodu dává přírůstek k severní šířce a druhá k východní délce. Tyto hodnoty se tedy přičtou k (celočíselným) výchozím souřadnicím dané gratikuly a vzniknou tak naprosto náhodné souřadnice místa uvnitř této oblasti. No a úkolem geohashera je se na tyto souřadnice v daný den dostat, zanechat tam zprávu a pořídit důkaz (foto).

Zní a vypadá to možná složitě, ale je to jednoduché. Existuje množství nástrojů, které výsledné souřadnice dokáží generovat, takže není nutné nic složitě ručně počítat. Mimo jiné existuje implementace pro iPhone, velmi pěkné počítadlo jako mashup uvnitř google mapy a v neposlední řadě, protože jsem majitelem telefonu se systémem Android, tak vzniká i implementace pro tento systém. To bude zřejmě důvodem existence tohoto článku – abych se pochlubil a dal vědět, že je se na co těšit :-). V prvotní fázi se seznamuju s SDK Androida a zkouším vyvíjet, ale počítám, že do konce příštího týdne by mohla spatřit světlo světa první betaverze generátoru geohashe.

Takže bych poprosil o poctivé sledování tématu geohashing v tomto blogu, protože se budou ve velmi brzké době dít veliké věci! Mám i veliké množství nápadů ne přímo do aplikace, ale i pro web a velmi rád bych je všechny uvedl do reality.

Go to Top