gpt4 book ai didi

grails - 如何使用 Grails-cxf 插件向 Web 服务提供动态凭据(用户名和密码)

转载 作者:行者123 更新时间:2023-12-02 13:46:19 27 4
gpt4 key购买 nike

我正在使用这个很棒的插件,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"
}
}

这非常有效,但我现在想要做的是让我的用户能够输入用户名和密码,以便他们可以输入他们的用户名和密码来使用该服务。有谁知道如何做到这一点?

我怀疑它在演示项目中使用了自定义拦截器:
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)
}
}

但是由于我没有实例化这个拦截器,也不了解它是如何实例化的,我不知道如何获取拦截器中使用的用户凭据。

有谁知道如何做到这一点/有任何示例代码?

谢谢!

最佳答案

假设您使用的是 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 = truesecurityInterceptor = '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 session 中,则不是 springSecurityService您可以使用 Spring RequestContextHolder ,其静态 getRequestAttributes()方法返回当前线程正在处理的 GrailsWebRequest,如果当前线程没有处理请求(例如,如果它是后台作业),则返回 null。
RequestContextHolder.requestAttributes?.session?.wsUser

或者,如果它们是请求属性(即您在 Controller 中说 request.wsUser = 'realUsername'),您可以使用 RequestContextHolder.requestAttributes?.currentRequest?.wsUser .

关于grails - 如何使用 Grails-cxf 插件向 Web 服务提供动态凭据(用户名和密码),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13701764/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com