5

この素晴らしいプラグインhttp://grails.org/plugin/cxf-clientを使用して、セキュリティを備えたコントラクト ファーストの Web サービスを利用しています。

だから私はすでに私の設定にこのようなものを持っています:

 cxf {
   client {
    cybersourceClient {           
        clientInterface = com.webhost.soapProcessor
        serviceEndpointAddress = "https://webhost/soapProcessor"
        wsdl = "https://webhost/consumeMe.wsdl"
        secured = true
        username = "myUname"
        password = "myPwd"
    }   
}

これは非常にうまく機能しますが、ユーザーがユーザー名とパスワードを入力できるようにして、ユーザー名とパスワードを入力してサービスを利用できるようにしたいと考えています。誰もこれを行う方法を知っていますか?

デモ プロジェクトのように Custom In Interceptor を使用していると思われます。

package com.cxf.demo.security

import com.grails.cxf.client.CxfClientInterceptor

import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor
import org.apache.ws.security.WSPasswordCallback
import org.apache.ws.security.handler.WSHandlerConstants

import javax.security.auth.callback.Callback
import javax.security.auth.callback.CallbackHandler
import javax.security.auth.callback.UnsupportedCallbackException


class CustomSecurityInterceptor implements CxfClientInterceptor {

String pass
String user


   WSS4JOutInterceptor create() {
    Map<String, Object> outProps = [:]
    outProps.put(WSHandlerConstants.ACTION, org.apache.ws.security.handler.WSHandlerConstants.USERNAME_TOKEN)
    outProps.put(WSHandlerConstants.USER, user)
    outProps.put(WSHandlerConstants.PASSWORD_TYPE, org.apache.ws.security.WSConstants.PW_TEXT)
    outProps.put(WSHandlerConstants.PW_CALLBACK_REF, new CallbackHandler() {

        void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
            WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]
            pc.password = pass
            pc.identifier = user
        }
    })

    new WSS4JOutInterceptor(outProps)
}
}

しかし、私はこのインターセプターをインスタンス化していないか、インスタンス化の方法を理解していないため、インターセプターで使用されるユーザーの資格情報を取得する方法がわかりません。

これを行う方法を知っている人はいますか/サンプルコードはありますか?

ありがとう!

4

2 に答える 2

0

他の人のための一般的な答えは次のとおりです。

1.config.groovy

cxf {
    client {

        nameOfClient {
            clientInterface = com.webhost.soapProcessor
            serviceEndpointAddress = "https://webhost/soapProcessor"
            wsdl = "https://webhost/soapProcessorconsumeMe.wsdl"
            secured = true
            securityInterceptor = "nameOfSecurityInterceptorBean"
        }
    }
}

2.Resources.groovy

import com.company.package.MySecurityInterceptor

beans = {

nameOfSecurityInterceptorBean(MySecurityInterceptor) {
}

}

3. com.company.package の下に MySecurityInterceptor を作成します。

package com.company.package;

import com.grails.cxf.client.CxfClientInterceptor

import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor
import org.apache.ws.security.WSPasswordCallback
import org.apache.ws.security.handler.WSHandlerConstants

import javax.security.auth.callback.Callback
import javax.security.auth.callback.CallbackHandler
import javax.security.auth.callback.UnsupportedCallbackException

import org.springframework.web.context.request.RequestContextHolder

class MySecurityInterceptor implements CxfClientInterceptor {


WSS4JOutInterceptor create() {
    Map<String, Object> outProps = [:]
    outProps.put(WSHandlerConstants.ACTION, org.apache.ws.security.handler.WSHandlerConstants.USERNAME_TOKEN)
    outProps.put(WSHandlerConstants.USER, user)
    outProps.put(WSHandlerConstants.PASSWORD_TYPE, org.apache.ws.security.WSConstants.PW_TEXT)
    outProps.put(WSHandlerConstants.PW_CALLBACK_REF, new CallbackHandler() {

                void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
                    WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]
                    def requestObj = RequestContextHolder.requestAttributes?.currentRequest
                    pc.password = requestObj.soapPassword
                    pc.identifier = requestObj.soapIdentifier
                }
            })

    new WSS4JOutInterceptor(outProps)
}
}

4. 次に、ユーザー名とパスワードをリクエスト (スレッドセーフ) に入れ、インターセプターによって引き出されるようにする必要があります。

    import com.company.package.MySecurityInterceptor
    class MySoapSendingController {

    SoapProcessor nameOfClient


    def index() {

    request['soapIdentifier'] = "usernameToUse"
    request['soapPassword'] = "passwordToUse"


                 ...

        ReplyMessage replyMsg = nameOfClient.makeSOAPRequest(request)
       }
    }
于 2012-12-04T15:03:55.070 に答える
0

Spring Security プラグインを使用していて、使用する WS 資格情報がUserドメイン オブジェクトのプロパティであると仮定すると、次のようなものが動作するはずです (未テスト):

src/groovy/com/cxf/demo/security/CustomSecurityInterceptor.groovy

package com.cxf.demo.security

import com.grails.cxf.client.CxfClientInterceptor

import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor
import org.apache.ws.security.WSPasswordCallback
import org.apache.ws.security.handler.WSHandlerConstants

import javax.security.auth.callback.Callback
import javax.security.auth.callback.CallbackHandler
import javax.security.auth.callback.UnsupportedCallbackException


class CustomSecurityInterceptor implements CxfClientInterceptor {

   def springSecurityService
   def grailsApplication

   WSS4JOutInterceptor create() {
    Map<String, Object> outProps = [:]
    outProps.put(WSHandlerConstants.ACTION, org.apache.ws.security.handler.WSHandlerConstants.USERNAME_TOKEN)
    // take default username from config
    outProps.put(WSHandlerConstants.USER, grailsApplication.config.cxf.client.cybersourceClient.username)
    outProps.put(WSHandlerConstants.PASSWORD_TYPE, org.apache.ws.security.WSConstants.PW_TEXT)
    outProps.put(WSHandlerConstants.PW_CALLBACK_REF, new CallbackHandler() {

        void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
            WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]
            // take password from current user, fall back to config if no
            // user currently logged in/not in a request thread, etc.
            pc.password = (springSecurityService.currentUser?.wsPassword
               ?: grailsApplication.config.cxf.client.cybersourceClient.password)
        }
    })

    new CustomWSS4JOutInterceptor(springSecurityService, outProps)
  }
}

class CustomWSS4JOutInterceptor extends WSS4JOutInterceptor {
  def springSecurityService

  CustomWSS4JOutInterceptor(springSecurityService, outProps) {
    super(outProps)
    this.springSecurityService = springSecurityService
  }

  // overridden to fetch username dynamically from logged in user
  // but fall back on config if no user/not on a request hander thread
  public Object getOption(String key) {
    if(key == WSHandlerConstants.USER && springSecurityService.currentUser?.wsUser) {
      return springSecurityService.currentUser?.wsUser
    } else return super.getOption(key)
  }
}

grails-app/conf/spring/resources.groovy

import com.cxf.demo.security.CustomSecurityInterceptor
beans = {
  customSecurityInterceptor(CustomSecurityInterceptor) {
    springSecurityService = ref('springSecurityService')
    grailsApplication = ref('grailsApplication')
  }
}

構成では、次のように置き換えsecured = trueますsecurityInterceptor = 'customSecurityInterceptor'

Spring Security を使用していない場合、同じパターンが機能します。重要な部分はコールバック ハンドラです

            pc.password = (springSecurityService.currentUser?.wsPassword
               ?: grailsApplication.config.cxf.client.cybersourceClient.password)

およびユーザー名ロジックgetOption

    if(key == WSHandlerConstants.USER && springSecurityService.currentUser?.wsUser) {
      return springSecurityService.currentUser?.wsUser

たとえば、ユーザー名とパスワードが HTTP セッションに保存されている場合、代わりにSpring RequestContextHolderspringSecurityServiceを使用できます。この静的メソッドは、現在のスレッドによって処理されている GrailsWebRequest を返すか、現在のスレッドがリクエストを処理していない場合は null を返します (たとえば、バックグラウンド ジョブの場合)。getRequestAttributes()

RequestContextHolder.requestAttributes?.session?.wsUser

または、それらがリクエスト属性である場合 (つまり、コントローラーで言っrequest.wsUser = 'realUsername'た場合) を使用できますRequestContextHolder.requestAttributes?.currentRequest?.wsUser

于 2012-12-04T14:27:47.810 に答える