gpt4 book ai didi

grails - Grails中的错误:刷新之前保存临时实例

转载 作者:行者123 更新时间:2023-12-02 14:02:16 24 4
gpt4 key购买 nike

我在使用spring-security和LDAP的Grails应用程序中运行用户身份验证时遇到问题。

与LDAP的连接工作正常,我得到了结果。但是我没有管理用户可以登录并且数据保存在本地数据库中。

我已更改/创建了以下文件:

config.groovy

grails.plugin.springsecurity.ldap. context.managerDn = 'USERNAME'
grails.plugin.springsecurity.ldap. context.managerPassword = 'PASSWORD'
grails.plugin.springsecurity.ldap. context.server ='ldap://LDAPSERVER:389/'
grails.plugin.springsecurity.ldap. authorities.ignorePartialResultException = true // typically needed for Active Directory
grails.plugin.springsecurity.ldap. search.base = 'DC=example,DC=com'
grails.plugin.springsecurity.ldap. search.filter='(sAMAccountName={0})' // for Active Directory you need this
grails.plugin.springsecurity.ldap. search.searchSubtree = true
grails.plugin.springsecurity.ldap.authorities.groupSearchBase ='DC=example,DC=com'
grails.plugin.springsecurity.ldap.authorities.groupSearchFilter = 'member={0}'
grails.plugin.springsecurity.ldap.authorities.retrieveDatabaseRoles = false
grails.plugin.springsecurity.ldap. auth.hideUserNotFoundExceptions = false
grails.plugin.springsecurity.ldap. search.attributesToReturn = ['mail', 'displayName', 'title', 'fullname'] // extra attributes you want returned; see below for custom classes that access this data
grails.plugin.springsecurity.providerNames = ['ldapAuthProvider']
grails.plugin.springsecurity.ldap.useRememberMe = false
grails.plugin.springsecurity.ldap.authorities.defaultRole = 'ROLE_USER'
grails.plugin.springsecurity.ldap.mapper.userDetailsClass = 'CustomUserDetails'

src / grovvy / CustomUserDetailsMapper.grovvy
package com.example


import com.example.CustomUserDetails
import org.springframework.ldap.core.DirContextAdapter
import org.springframework.ldap.core.DirContextOperations
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.ldap.userdetails.UserDetailsContextMapper

import groovy.sql.Sql

import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.ldap.userdetails.UserDetailsContextMapper
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.GrantedAuthority


import org.springframework.security.core.userdetails.UsernameNotFoundException
import org.springframework.security.authentication.DisabledException

class CustomUserDetailsContextMapper implements UserDetailsContextMapper {

private static final List NO_ROLES = [new SimpleGrantedAuthority("ROLE_USER")]

def dataSource

@Override
public CustomUserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<GrantedAuthority> authority) {

username = username.toLowerCase()

User.withTransaction {

User user = User.findByUsername(username)

String firstName = ctx.originalAttrs.attrs['givenname'].values[0]
String lastName = ctx.originalAttrs.attrs['sn'].values[0]


def roles



if(!user){
user = new User(username: username, enabled: true, firstName: firstName, lastName: lastName)
user.save(flush: true)
}
else {
user = User.findByUsername(username)
user.firstName = firstName
user.lastName = lastName
user.save(flush)
}

roles = user.getAuthorities()
}

if( !user.enabled )
throw new DisabledException("User is disabled", username)


def authorities = roles.collect { new SimpleGrantedAuthority(it.authority) }
authorities.addAll(authority)
def userDetails = new CustomUserDetails(username, user.password, user.enabled, false, false, false, authorities, user.id, user.firstName, user.lastName)

return userDetails
}

@Override
public void mapUserToContext(UserDetails arg0, DirContextAdapter arg1) {
}
}

src / grovvy / CustomUserDetails.groovy
 package com.example


import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.userdetails.User


class CustomUserDetails extends User{
final String firstName
final String lastName

CustomUserDetails(String username, String password, boolean enabled,
boolean accountNonExpired, boolean credentialsNonExpired,
boolean accountNonLocked,
Collection<GrantedAuthority> authorities,
long id, String firstName, String lastName) {
super(username, password, enabled, accountNonExpired,
credentialsNonExpired, accountNonLocked, authorities, id)

this.firstName = firstName
this.lastName = lastName
}
}

src / groovy / CustomUserDetailsS​​ervice.groovy
package com.example


import grails.plugin.springsecurity.userdetails.GrailsUserDetailsService
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.core.userdetails.UsernameNotFoundException


class CustomUserDetailsService implements GrailsUserDetailsService {

/**
* Some Spring Security classes (e.g. RoleHierarchyVoter) expect at least one role, so
* we give a user with no granted roles this one which gets past that restriction but
* doesn't grant anything.
*/
static final List NO_ROLES = [new SimpleGrantedAuthority("NO_ROLE")]

UserDetails loadUserByUsername(String username, boolean loadRoles)
throws UsernameNotFoundException {
return loadUserByUsername(username)
}

UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

User.withTransaction { status ->

User user = User.findByUsername(username)
if (!user) throw new UsernameNotFoundException('User not found', username)

def authorities = user.authorities.collect {new SimpleGrantedAuthority(it.authority)}

return new CustomUserDetails(user.username, user.password, user.enabled,
!user.accountExpired, !user.passwordExpired,
!user.accountLocked, authorities ?: NO_ROLES, user.id,
user.firstName, user.lastName)
} as UserDetails
}
}

conf / resources.groovy
// Place your Spring DSL code here
import com.example.CustomUserDetailsContextMapper
import com.example.CustomUserDetailsService

beans = {
userDetailsService(CustomUserDetailsService)

ldapUserDetailsMapper(CustomUserDetailsContextMapper) {
dataSource = ref("dataSource")
}
}

当我使用此配置运行并尝试登录时,出现以下错误消息:
 Message: object references an unsaved transient instance - save the transient instance before flushing: com.example.User; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.example.User

最佳答案

我有同样的问题。错误消息指出未保存User实例。我通过更改CustomUserDetailsMapper.grovvy中的以下行来修复它

user = new User(username: username, enabled: true, firstName: firstName, lastName: lastName)


user = new User(username: username, enabled: true, firstName: firstName, lastName: lastName, accountLocked: false, passwordExpired: false, accountExpired: false, password: "test")

并通过将firstName和lastName添加到User域类。

如您所见,我只是向应该添加的用户添加了一些默认值。密码总是设置为“test”没关系。由于您正在使用LDAP,因此不会使用。

关于grails - Grails中的错误:刷新之前保存临时实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20288478/

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