我试图自定义弹簧安全UI插件。我想达到什么:grails-弹簧安全UI奇怪的行为
1)管理从春季安全用户界面创建与电子邮件的新用户
2)应用程序生成的链接,并将其发送给用户的电子邮件
3)用户点击链接,看到页面,在那里他可以指定密码,并将其保存
4)用户提交页面的帐户被激活与他指定
为此,我决定自定义UserController中由弹簧SECU提供的密码后默认情况下RITY UI:
class UserController extends grails.plugin.springsecurity.ui.UserController {
def mailService
def save() {
def user = lookupUserClass().newInstance(params)
if (!user.save(flush: true)) {
render view: 'create', model: [user: user, authorityList: sortedRoles()]
return
}
//generate secured link
def registrationCode = new RegistrationCode(username: user.username).save(flush: true)
String url = generateLink('verifyRegistration', [t: registrationCode.token])
def conf = SpringSecurityUtils.securityConfig
//here we should send an invitation mail
mailService.sendMail {
async true
to user.email
from conf.ui.register.emailFrom
subject conf.ui.register.emailSubject
html url
}
addRoles(user)
flash.message = "${message(code: 'default.created.message', args: [message(code: 'user.label', default: 'User'), user.id])}"
redirect action: 'edit', id: user.id
}
def verifyRegistration() {
def conf = SpringSecurityUtils.securityConfig
String defaultTargetUrl = conf.successHandler.defaultTargetUrl
String token = params.t
println token
def registrationCode = token ? RegistrationCode.findByToken(token) : null
if (!registrationCode) {
println registrationCode
flash.error = message(code: 'spring.security.ui.register.badCode')
redirect uri: defaultTargetUrl
return
}
render(view: "initpassword", model: [token: token])
}
def savePassword() {
String token = params.token
def conf = SpringSecurityUtils.securityConfig
String defaultTargetUrl = conf.successHandler.defaultTargetUrl
def registrationCode = token ? RegistrationCode.findByToken(token) : null
//TODO check if passwords are equal
if (!registrationCode) {
flash.error = message(code: 'spring.security.ui.register.badCode')
redirect uri: defaultTargetUrl
return
}
def user
RegistrationCode.withTransaction { status ->
String usernameFieldName = SpringSecurityUtils.securityConfig.userLookup.usernamePropertyName
user = lookupUserClass().findWhere((usernameFieldName): registrationCode.username)
if (!user) {
return
}
user.accountLocked = false
String salt = saltSource instanceof NullSaltSource ? null : params.username
user.password = springSecurityUiService.encodePassword(params.password1, salt)
user.save(flush: true)
def UserRole = lookupUserRoleClass()
def Role = lookupRoleClass()
for (roleName in conf.ui.register.defaultRoleNames) {
UserRole.create user, Role.findByAuthority(roleName)
}
registrationCode.delete()
}
if (!user) {
flash.error = message(code: 'spring.security.ui.register.badCode')
redirect uri: defaultTargetUrl
return
}
}
}
和initpassword.gsp是非常简单的,看起来像这样:
<g:form action="savePassword" absolute="true" method="POST">
<g:passwordField name="password1"/>
<g:passwordField name="password2"/>
<g:hiddenField value="${token}" name="token"/>
<g:actionSubmit value="Save"/>
</g:form>
一切看起来好为止(至少对我来说,请让我知道,如果你”已经观察到水木清华错了),但是当我尝试测试很奇怪的事情发生了:
1)我点击(verifyRegistration()被调用方法是在电子邮件中发送的链接)
2)表观s上3)我提交的页面(这里savePassword()应该被调用,但由于某种原因,它没有被调用)和应用程序显示我默认页面用于创建一个新的用户从弹簧安全UI插件与验证erros它说,用户(所有的一个接一个)字段不能为空
4)当我尝试调试(在savePassword()方法开始时断点)没有反应 - 似乎控制器只是不赶上要求savePassword()
但当我尝试只是从浏览器打开savePassword()方法(t yping localhost/myApp/user/savePassword)控制器捕获该请求并在该断点上进行调试。
我花了近4个小时处理这个问题。不知道究竟发生了什么。 Grails带来一些魔力。 有人可以帮助我吗?谢谢!!!
你的'initpassword.gsp'位于哪里?请从项目根目录获取完整路径。并且你调用这个视图的控制器代码 – wwarlock
initpassword.gsp在%PROJECT%/ grails-app/views/user下面,它用在UserController的def verifyRegistration()方法中(post above) –
我看着我的代码,我已经开发出类似的案例:1)将'initpassword.gsp'重命名为'_initpassword.gsp'; 2)将render(view:“initpassword”,model:[token:token])重写为'render(controller:“user”,template:“initpassword”,model:[token:token])''。请尝试,这必须工作。 – wwarlock