Loading ...
Sorry, an error occurred while loading the content.

5528WSE-Security 3.0

Expand Messages
  • jvrobert
    Aug 7, 2006
      I've hacked (horribly, embarassingly) a wrapper to SOAP::Lite that
      seems to work and allows a SOAP::Lite Perl client to connect to a WSE-
      Security enabled .NET Web Service.

      It's terrible code, I'm not really experienced in Kerberos or
      SOAP::Lite, and I shamelessly copied some of the code from
      LWP::Authen::Negotiate for an example of how to encode the
      BinaryToken.

      I don't know enough about SOAP::Lite to do a real patch, so I kludged
      together a cheesy wrapper class for SOAP::Lite. It would be awesome
      if this functionality was built into SOAP::Lite at some point (that's
      why I'm posting this).

      It depends on GSSAPI. Here's an example script that uses the wrapper,
      followed by the wrapper itself.

      #!/path/to/perl

      use WSEWrap;
      #use SOAP::Lite +trace => [qw(all)];
      use MIME::Base64;

      my $soap = WSEWrap->new(ns => 'http://tempuri.org', proxy
      => 'http://mysoapserver.mycorp.com:8081/Service.asmx', on_action =>
      sub { join '/', 'http://tempuri.org', $_[1] }, debug => 1);
      if (! $soap->wse_auth()) {
      print $soap->auth_error() . "\n";
      exit(1);
      }

      my $hw = $soap->HelloWorld();
      my $whoami = $hw->result;
      print "You authenticated via kerberos as: $whoami\n";

      Here is the WSEWrap.pm code (ugly, but works for at least my casual
      needs)

      package WSEWrap;

      use SOAP::Lite;
      use MIME::Base64;
      use URI;
      use GSSAPI;

      sub new {
      my $class = shift;
      my $self = bless {}, $class;
      $self->{args} = {@_};
      $self->{soap} = SOAP::Lite->new(@_);
      my $st = "SOAP::Lite::";
      foreach my $f (keys %$st) {
      next if $f =~ /::/;
      my $sym = "$st$f";
      if (*{$sym}{CODE}) {
      $self->{delegates}->{$f} = 1;
      }
      }
      return $self;
      }

      sub auth_error {
      return $_[0]->{last_error};
      }

      sub wse_auth {
      my $self = shift;
      my $host = URI->new($self->{args}->{proxy})->host();
      my $target;
      my $status = GSSAPI::Name->import($target, "host\@$host",
      GSSAPI::OID::gss_nt_hostbased_service);
      $target->display($tname);
      # print "wse_auth: TNAME=$tname\n" if $self->{args}->{debug};
      my $ctx = GSSAPI::Context->new();
      my $imech = GSSAPI::OID::gss_mech_krb5;
      my $iflags = GSS_C_REPLAY_FLAG;
      my $bindings = GSS_C_NO_CHANNEL_BINDINGS;
      my $creds = GSS_C_NO_CREDENTIAL;
      my $itime = 0;
      $status = $ctx->init( $creds, $target, $imech, $iflags,
      $itime,
      $bindings,undef, undef,
      $otoken, undef, undef);
      if ($status->major != GSS_S_COMPLETE) {
      $self->{last_error} = $status->specific_message;
      if ($self->{last_error} =~ /open.*: No such file or
      directory/) {
      $self->{last_error} = "ERROR: Unable to open
      token file - did you kinit?\nERROR: [$self->{last_error}]";
      }
      return 0;
      }
      # Our binary token in base64
      $self->{pw} = encode_base64($otoken, "");
      # Add some namespace declarations
      $self->{soap}->serializer()->register_ns('http://docs.oasis-
      open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-
      1.0.xsd', 'wsse');
      $self->{soap}->serializer()->register_ns
      ('http://schemas.xmlsoap.org/ws/2004/08/addressing', 'wsa');
      $self->{soap}->serializer()->register_ns('http://docs.oasis-
      open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-
      1.0.xsd', 'wsu');
      # Build our header additions
      my $unt = SOAP::Data->name('wsse:BinarySecurityToken')->value
      ($self->{pw})->type('');
      $unt->attr({ ValueType => 'http://docs.oasis-
      open.org/wss/oasis-wss-kerberos-token-profile-
      1.1#GSS_Kerberosv5_AP_REQ', EncodingType => 'http://docs.oasis-
      open.org/wss/2004/01/oasis-200401-wss-soap-message-security-
      1.0#Base64Binary'});
      my $sec = SOAP::Data->name('wsse:Security' => \$unt);
      $sec->mustUnderstand(1);
      my $wsa = SOAP::Data->name('wsa:Action'
      => 'http://core.intel.com/schemas/pcam/test/06-30-
      2006/kerberos/WhoAmI')->type('');
      my $wsa1 = SOAP::Data->name('wsa:ReplyTo' => \SOAP::Data->name
      ('wsa:Address'))->value('http://chsamba.org');
      my $wsa2 = SOAP::Data->name('wsa:MessageID' => 'uuid:bebff702-
      0e8d-4705-8793-7dc39efecf0c');
      my $wsa3 = SOAP::Data->name('wsa:To'
      => 'http://ch7sdev999.amr.corp.intel.com:8081/Service.asmx');
      my $h = SOAP::Header->value($sec, $wsa, $wsa2, $wsa3);
      $self->{header} = $h;
      return 1;
      }



      sub AUTOLOAD {
      my $self = shift;
      $AUTOLOAD =~ s/WSEWrap:://;
      print @{SOAP::Lite::EXPORT_OK};
      if ($self->{header} && ! $self->{delegates}->{$AUTOLOAD}) {
      unshift(@_, $self->{header});
      }
      return &{"SOAP::Lite::$AUTOLOAD"}($self->{soap}, @_);
      }

      1;
    • Show all 4 messages in this topic