grails spring安全登录不起作用 [英] grails spring security login is not working
问题描述
我正在使用grails 2.1.0。我已经安装了spring-security-core插件。
当我创建用户时,它正在创建它。但是,当我尝试登录时,它显示:
对不起,我们无法找到具有该用户名和密码的用户。
还有一个事实是,当我为不同的用户使用相同的密码时,它不会像用户一样保存具有类似编码值的密码1我已经使用了像这样保存在数据库中的 123
密码
d535ce213a0e8e4f9e724af47c46eea409ef401c03617b749da618a82890d743
对于用户2我也使用了密码 123
,并且这次保存像这样
0849ea79a2c1bca057ded06c3053fb5bc5d7ba52b50982e73e44894d4f3e0aa6
我不明白。任何人都可以请帮助我吗?
我的config.groovy >>>
//位置来搜索合并到主配置中的配置文件;
//配置文件可以是ConfigSlurper脚本,Java属性文件或类
//在ConfigSlurper格式的类路径中
// grails.config.locations = [classpath :$ {appName} -config.properties,
//classpath:$ {appName} -config.groovy,
//file:$ {userHome} /。grails / $ {appName } -config.properties,
//file:$ {userHome} /。grails / $ {appName} -config.groovy]
// if(System.properties [ $ {appName} .config.location]){
// grails.config.locations<< file:+ System.properties [$ {appName} .config.location]
//}
grails.project.groupId = appName //改变它以改变默认值包名称和Maven发布目标
grails.mime.file.extensions = true //允许将URL中的文件扩展名解析为请求格式
grails.mime.use.accept.header = false
grails.mime.types = [
all:'* / *',
atom:'application / atom + xml',
css:'text / css',
csv:'text / csv',
form:'application / x-www-form-urlencoded',
html:['text / html','application / xhtml + xml'],
js:'text / javascript',
json:['application / json','text / json'],
multipartForm:'multipart / form-data',
rss :'application / rss + xml',
text:'text / plain',
xml:['text / xml','application / xml ']
]
// URL映射缓存最大大小,默认为5000
//grails.urlmapping.cache.maxsize = 1000
/ /资源插件应该处理哪些URL模式
grails.resources.adhoc.patterns = ['/ images / *','/ css / *','/ js / *','/ plugins / * ']
//使用$ {}
编码数据的默认编解码器grails.views.default.codec =none// none,html,base64
grails .views.gsp.encoding =UTF-8
grails.converters.encoding =UTF-8
//启用Sitemesh预处理GSP页面
grails.views.gsp.sitemesh .preprocess = true
//脚手架模板配置
grails.scaffolding.templates.domainSuffix ='实例'
//设置为false以使用新的Grails 1.2 JSONBuilder渲染方法
grails.json.legacy.builder = false
//启用native2ascii转换i18n属性文件
grails.enable.native2ascii = true
//包含在Spring中的包bean扫描
gra ils.spring.bean.packages = []
//是否禁止处理多部分请求
grails.web.disable.multipart = false
//请求参数在记录异常时掩码
grails.exceptionresolver.params.exclude = ['password']
//默认情况下配置查询的自动缓存(如果为false,可以使用缓存缓存单个查询:true')
grails.hibernate.cache.queries = false
environments {
development {
grails.logging.jul.usebridge = true
}
生产{
grails.logging.jul.usebridge = false
// TODO:grails.serverURL =http://www.changeme.com
}
// log4j配置
log4j = {
//更改默认控制台appender的日志模式示例:
//
// appenders {
// console name:'stdout',layout:pattern(conversionPattern:'%c {2}%m%n')
//}
错误'org.co dehaus.groovy.grails.web.servlet',//控制器
'org.codehaus.groovy.grails.web.pages',// GSP
'org.codehaus.groovy.grails.web。 sitemesh',//布局
'org.codehaus.groovy.grails.web.mapping.filter',// URL映射
'org.codehaus.groovy.grails.web.mapping',// URL映射
'org.codehaus.groovy.grails.commons',//核心/类加载
'org.codehaus.groovy.grails.plugins',//插件
'org.codehaus .groovy.grails.orm.hibernate',// hibernate集成
'org.springframework',
'org.hibernate',
'net.sf.ehcache.hibernate'
}
//由Spring Security Core插件添加:
grails.plugins.springsecurity.userLookup.userDomainClassName ='common.auth.User'
grails.plugins.springsecurity .userLookup.authorityJoinClassName = 'common.auth.UserAuthority'
grails.plugins.springsecurity.authority.className ='common.auth.Authority'
我的登录控制器>>>
import grails.converters.JSON
import javax.servlet.http.HttpServletResponse
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
import org.springframework.security.authentication.AccountExpiredException
import org.springframework.security.authentication.CredentialsExpiredException
import org.springframework.security.authentication.DisabledException
import org.springframework.security.authentication.LockedException
import org.springframework。 security.core.context.SecurityContextHolder作为SCH
导入org.springframework.security.web.WebAttributes
导入org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
类LoginController {
/ **
*用于authenticationTrustResolver的依赖注入。
* /
def authenticationTrustResolver
/ **
* springSecurityService的依赖注入。
* /
def springSecurityService
/ **
*默认操作;如果已登录,则重定向到defaultTargetUrl,否则重定向到/ login / auth。
* /
def index = {
if(springSecurityService.isLoggedIn()){
redirect uri:SpringSecurityUtils.securityConfig.successHandler.defaultTargetUrl
} else {
redirect action:'auth',params:params
}
}
/ **
*显示登录页面。
* /
def auth = {
def config = SpringSecurityUtils.securityConfig
if(springSecurityService.isLoggedIn()){
redirect uri:config.successHandler.defaultTargetUrl
return
}
String view ='auth'
String postUrl =$ {request.contextPath} $ {config.apf .filterProcessesUrl}
render view:view,model:[postUrl:postUrl,
rememberMeParameter:config.rememberMe.parameter]
}
/ **
* Ajax请求的重定向操作。
* /
def authAjax = {
response.setHeader'Location',SpringSecurityUtils.securityConfig.auth.ajaxLoginFormUrl
response.sendError HttpServletResponse.SC_UNAUTHORIZED
}
/ **
*显示被拒绝的页面。
* /
def denied = {
if(springSecurityService.isLoggedIn()&&
authenticationTrustResolver.isRememberMe(SCH.context?.authentication)){
//有cookie但页面有IS_AUTHENTICATED_FULLY
重定向动作:'full',params:params
}
}
/ **
*使用Remember-me Cookie的用户的登录页面,但访问IS_AUTHENTICATED_FULLY页面。
* /
def full = {
def config = SpringSecurityUtils.securityConfig
渲染视图:'auth',params:params,
模型:[hasCookie:authenticationTrustResolver。 isRememberMe(SCH.context?.authentication),
postUrl:$ {request.contextPath} $ {config.apf.filterProcessesUrl}]
}
/ **
*登录失败后回调。使用警告消息重定向到授权页面。
* /
def authfail = {
def username = session [UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
String msg =''
def exception = session [WebAttributes .AUTHENTICATION_EXCEPTION]
if(exception){
if(exception instanceof AccountExpiredException){
msg = g.message(code:springSecurity.errors.login.expired)
} else if(exception instanceof CredentialsExpiredException){
msg = g.message(code:springSecurity.errors.login.passwordExpired)
} else if(exception instanceof DisabledException){
msg = g .message(code:springSecurity.errors.login.disabled)
} else if(exception instanceof LockedException){
msg = g.message(code:springSecurity.errors.login.locked)
} else {
msg = g.message(code:springSecurity .errors.login.fail)
$ b $ if(springSecurityService.isAjax(request)){
render([error:msg] as JSON)
} else {
flash.message = msg
重定向操作:'auth',params:params
}
}
/ * *
* Ajax成功重定向网址。
* /
def ajaxSuccess = {
render([success:true,username:springSecurityService.authentication.name] as JSON)
}
/ **
* Ajax拒绝重定向网址。
* /
def ajaxDenied = {
render([error:'access denied'] as JSON)
}
}
my authority.groovy >>>
包common.auth
类权限{
字符串权限
静态映射= {
高速缓存真实
}
static constraints = {
authority blank:false,unique:true
}
}
我的用户domain.groovy将保存我的用户>>>
包common.auth
$ b类用户{
瞬间springSecurityService
字符串实名
字符串用户名
字符串密码
字符串指定
布尔启用
布尔accountExpired
布尔accountLocked
布尔passwordExpired
静态约束= {
用户名空白:false,unique:true
通过字空白:false
}
静态映射= {
密码列:'`password`'
}
Set< Authority> getAuthorities(){
UserAuthority.findAllByUser(this).collect {it.authority} as Set
}
def beforeInsert(){
encodePassword()
$ b $ def beforeUpdate(){
if(isDirty('password')){
encodePassword()
}
}
protected void encodePassword(){
password = springSecurityService.encodePassword(password)
}
}
我的userauthority.groovy >>>
package common.auth
import org.apache.commons.lang.builder.HashCodeBuilder
$ b $ class UserAuthority实现Serializable {
用户用户
权限
boolean equals(other){
if(!(other(UserAuthority)instanceof)){
return false
}
other.user?.id = = user?.id&&
other.authority?.id ==权限?.id
}
int hashCode(){
def builder = new HashCodeBuilder()
if (user)builder.append(user.id)
if(authority)builder.append(authority.id)
builder.toHashCode()
}
static UserAuthority get(long userId,long authorityId){
从UserAuthority中查找',其中user.id =:userId和authority.id =:authorityId',
[userId:userId,authorityId:authorityId]
)
UserAuthority(用户用户,权限管理机构,boolean flush = false){
UserAuthority(user:user,authority:authority).save(flush:flush,insert: true)
静态布尔remove(用户用户,权威机构,boolean flush = false){
UserAuthority instance = UserAuthority.findByUserAndAuthority(user,authority)
if(!instance){
返回false
}
instance.delete(flush:flush)
true
}
static void removeAll(User user){
executeUpdate'DELETE FROM UserAuthority WHERE user =:user',[user:user]
}
static void removeAll(Authority authority){
executeUpdate'DELETE FROM UserAuthority WHERE authority =:authority' ,[权威:权威]
}
静态映射= {
id复合:['authority','user']
版本false
}
}
我的createUser操作在AdministratorActionController中创建用户>>>
包管理员
导入common.auth.User
类AdmistratorActionController {
def springSecurityService
def index(){
redirect(controller:'admistratorAction',action:'createUser')
}
def createUser = {
用户用户=新用户(params)
def password = user.password
def salt = user.username //取决于您用作salt
用户的内容。密码= springSecurityService.encodePassword(密码,盐)
user.save()
flash.message =用户创建成功!!!
}
}
I认为你的密码是两次编码,你已经在域中的beforeInsert上编码了(),我认为你不需要再次编码它。
I am using grails 2.1.0. I have installed spring-security-core plugin.
When I create user it is creating it. But when I try to login then it shows:
"Sorry, we were not able to find a user with that username and password."
And there is also another fact that is when I use the same password for different user it does not save password with similar encoded value like for user 1 I have used password 123
which is saved in database like this
d535ce213a0e8e4f9e724af47c46eea409ef401c03617b749da618a82890d743
and for user 2 I also used password 123
and this time it is saved like this
0849ea79a2c1bca057ded06c3053fb5bc5d7ba52b50982e73e44894d4f3e0aa6
I don't understand. Can anyone please help me on this ?
my config.groovy >>>
// locations to search for config files that get merged into the main config;
// config files can be ConfigSlurper scripts, Java properties files, or classes
// in the classpath in ConfigSlurper format
// grails.config.locations = [ "classpath:${appName}-config.properties",
// "classpath:${appName}-config.groovy",
// "file:${userHome}/.grails/${appName}-config.properties",
// "file:${userHome}/.grails/${appName}-config.groovy"]
// if (System.properties["${appName}.config.location"]) {
// grails.config.locations << "file:" + System.properties["${appName}.config.location"]
// }
grails.project.groupId = appName // change this to alter the default package name and Maven publishing destination
grails.mime.file.extensions = true // enables the parsing of file extensions from URLs into the request format
grails.mime.use.accept.header = false
grails.mime.types = [
all: '*/*',
atom: 'application/atom+xml',
css: 'text/css',
csv: 'text/csv',
form: 'application/x-www-form-urlencoded',
html: ['text/html','application/xhtml+xml'],
js: 'text/javascript',
json: ['application/json', 'text/json'],
multipartForm: 'multipart/form-data',
rss: 'application/rss+xml',
text: 'text/plain',
xml: ['text/xml', 'application/xml']
]
// URL Mapping Cache Max Size, defaults to 5000
//grails.urlmapping.cache.maxsize = 1000
// What URL patterns should be processed by the resources plugin
grails.resources.adhoc.patterns = ['/images/*', '/css/*', '/js/*', '/plugins/*']
// The default codec used to encode data with ${}
grails.views.default.codec = "none" // none, html, base64
grails.views.gsp.encoding = "UTF-8"
grails.converters.encoding = "UTF-8"
// enable Sitemesh preprocessing of GSP pages
grails.views.gsp.sitemesh.preprocess = true
// scaffolding templates configuration
grails.scaffolding.templates.domainSuffix = 'Instance'
// Set to false to use the new Grails 1.2 JSONBuilder in the render method
grails.json.legacy.builder = false
// enabled native2ascii conversion of i18n properties files
grails.enable.native2ascii = true
// packages to include in Spring bean scanning
grails.spring.bean.packages = []
// whether to disable processing of multi part requests
grails.web.disable.multipart=false
// request parameters to mask when logging exceptions
grails.exceptionresolver.params.exclude = ['password']
// configure auto-caching of queries by default (if false you can cache individual queries with 'cache: true')
grails.hibernate.cache.queries = false
environments {
development {
grails.logging.jul.usebridge = true
}
production {
grails.logging.jul.usebridge = false
// TODO: grails.serverURL = "http://www.changeme.com"
}
}
// log4j configuration
log4j = {
// Example of changing the log pattern for the default console appender:
//
//appenders {
// console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n')
//}
error 'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages', // GSP
'org.codehaus.groovy.grails.web.sitemesh', // layouts
'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
'org.codehaus.groovy.grails.web.mapping', // URL mapping
'org.codehaus.groovy.grails.commons', // core / classloading
'org.codehaus.groovy.grails.plugins', // plugins
'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration
'org.springframework',
'org.hibernate',
'net.sf.ehcache.hibernate'
}
// Added by the Spring Security Core plugin:
grails.plugins.springsecurity.userLookup.userDomainClassName = 'common.auth.User'
grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'common.auth.UserAuthority'
grails.plugins.springsecurity.authority.className = 'common.auth.Authority'
my login controller >>>
import grails.converters.JSON
import javax.servlet.http.HttpServletResponse
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
import org.springframework.security.authentication.AccountExpiredException
import org.springframework.security.authentication.CredentialsExpiredException
import org.springframework.security.authentication.DisabledException
import org.springframework.security.authentication.LockedException
import org.springframework.security.core.context.SecurityContextHolder as SCH
import org.springframework.security.web.WebAttributes
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
class LoginController {
/**
* Dependency injection for the authenticationTrustResolver.
*/
def authenticationTrustResolver
/**
* Dependency injection for the springSecurityService.
*/
def springSecurityService
/**
* Default action; redirects to 'defaultTargetUrl' if logged in, /login/auth otherwise.
*/
def index = {
if (springSecurityService.isLoggedIn()) {
redirect uri: SpringSecurityUtils.securityConfig.successHandler.defaultTargetUrl
} else {
redirect action: 'auth', params: params
}
}
/**
* Show the login page.
*/
def auth = {
def config = SpringSecurityUtils.securityConfig
if (springSecurityService.isLoggedIn()) {
redirect uri: config.successHandler.defaultTargetUrl
return
}
String view = 'auth'
String postUrl = "${request.contextPath}${config.apf.filterProcessesUrl}"
render view: view, model: [postUrl: postUrl,
rememberMeParameter: config.rememberMe.parameter]
}
/**
* The redirect action for Ajax requests.
*/
def authAjax = {
response.setHeader 'Location', SpringSecurityUtils.securityConfig.auth.ajaxLoginFormUrl
response.sendError HttpServletResponse.SC_UNAUTHORIZED
}
/**
* Show denied page.
*/
def denied = {
if (springSecurityService.isLoggedIn() &&
authenticationTrustResolver.isRememberMe(SCH.context?.authentication)) {
// have cookie but the page is guarded with IS_AUTHENTICATED_FULLY
redirect action: 'full', params: params
}
}
/**
* Login page for users with a remember-me cookie but accessing a IS_AUTHENTICATED_FULLY page.
*/
def full = {
def config = SpringSecurityUtils.securityConfig
render view: 'auth', params: params,
model: [hasCookie: authenticationTrustResolver.isRememberMe(SCH.context?.authentication),
postUrl: "${request.contextPath}${config.apf.filterProcessesUrl}"]
}
/**
* Callback after a failed login. Redirects to the auth page with a warning message.
*/
def authfail = {
def username = session[UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
String msg = ''
def exception = session[WebAttributes.AUTHENTICATION_EXCEPTION]
if (exception) {
if (exception instanceof AccountExpiredException) {
msg = g.message(code: "springSecurity.errors.login.expired")
} else if (exception instanceof CredentialsExpiredException) {
msg = g.message(code: "springSecurity.errors.login.passwordExpired")
} else if (exception instanceof DisabledException) {
msg = g.message(code: "springSecurity.errors.login.disabled")
} else if (exception instanceof LockedException) {
msg = g.message(code: "springSecurity.errors.login.locked")
} else {
msg = g.message(code: "springSecurity.errors.login.fail")
}
}
if (springSecurityService.isAjax(request)) {
render([error: msg] as JSON)
} else {
flash.message = msg
redirect action: 'auth', params: params
}
}
/**
* The Ajax success redirect url.
*/
def ajaxSuccess = {
render([success: true, username: springSecurityService.authentication.name] as JSON)
}
/**
* The Ajax denied redirect url.
*/
def ajaxDenied = {
render([error: 'access denied'] as JSON)
}
}
my authority.groovy >>>
package common.auth
class Authority {
String authority
static mapping = {
cache true
}
static constraints = {
authority blank: false, unique: true
}
}
my user domain.groovy where my user will be saved >>>
package common.auth
class User {
transient springSecurityService
String realname
String username
String password
String designation
boolean enabled
boolean accountExpired
boolean accountLocked
boolean passwordExpired
static constraints = {
username blank: false, unique: true
password blank: false
}
static mapping = {
password column: '`password`'
}
Set<Authority> getAuthorities() {
UserAuthority.findAllByUser(this).collect { it.authority } as Set
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}
my userauthority.groovy >>>
package common.auth
import org.apache.commons.lang.builder.HashCodeBuilder
class UserAuthority implements Serializable {
User user
Authority authority
boolean equals(other) {
if (!(other instanceof UserAuthority)) {
return false
}
other.user?.id == user?.id &&
other.authority?.id == authority?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (user) builder.append(user.id)
if (authority) builder.append(authority.id)
builder.toHashCode()
}
static UserAuthority get(long userId, long authorityId) {
find 'from UserAuthority where user.id=:userId and authority.id=:authorityId',
[userId: userId, authorityId: authorityId]
}
static UserAuthority create(User user, Authority authority, boolean flush = false) {
new UserAuthority(user: user, authority: authority).save(flush: flush, insert: true)
}
static boolean remove(User user, Authority authority, boolean flush = false) {
UserAuthority instance = UserAuthority.findByUserAndAuthority(user, authority)
if (!instance) {
return false
}
instance.delete(flush: flush)
true
}
static void removeAll(User user) {
executeUpdate 'DELETE FROM UserAuthority WHERE user=:user', [user: user]
}
static void removeAll(Authority authority) {
executeUpdate 'DELETE FROM UserAuthority WHERE authority=:authority', [authority: authority]
}
static mapping = {
id composite: ['authority', 'user']
version false
}
}
And my createUser action to create user in AdministratorActionController >>>
package administrator
import common.auth.User
class AdmistratorActionController {
def springSecurityService
def index() {
redirect(controller: 'admistratorAction', action: 'createUser')
}
def createUser = {
User user = new User(params)
def password = user.password
def salt = user.username //depends on what you're using as a salt
user.password = springSecurityService.encodePassword(password, salt)
user.save()
flash.message = "User Create Successfully !!!"
}
}
I think you are encoding your password twice, you already have encode() on beforeInsert in the domain, I think you need not to encode it again.
这篇关于grails spring安全登录不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!