grails spring security rest /api/login 401 Unauthorized
Posted
技术标签:
【中文标题】grails spring security rest /api/login 401 Unauthorized【英文标题】: 【发布时间】:2017-06-25 06:28:12 【问题描述】:我已经使用 spring-security-core:2.0.0 + spring-security-rest:1.4.1 插件配置了一个 Grails(2.3.7) 应用程序为了有两种身份验证类型,一种用于网络的有状态身份验证,一种用于使用令牌(无状态)的移动设备。一切都很好,基本的 http 身份验证运行良好。尝试使用 POSTMAN REST 客户端对 http://localhost:8080/api/login 进行身份验证,在请求有效负载中有用户名和密码我得到 401 Unauthorized ,我无法理解为什么?什么是从下面的配置中丢失?非常感谢任何帮助。 我也尝试了 spring-security-rest:1.5.0 但我得到了相同的结果,401。
BuildConfig.groovy
plugins
...
compile ":spring-security-core:2.0.0"
compile ":spring-security-rest:1.4.1",
excludes ('spring-security-core')
...
Config.groovy
/ Added by the Spring Security Core plugin:
grails.plugin.springsecurity.successHandler.defaultTargetUrl = '/general'
grails.plugin.springsecurity.userLookup.userDomainClassName = 'org.sali.Users.SecUser'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'org.sali.Users.SecUserSecRole'
grails.plugin.springsecurity.authority.className = 'org.sali.Users.SecRole'
grails.plugin.springsecurity.securityConfigType = "Annotation"
grails.plugin.springsecurity.roleHierarchy = '''
ROLE_ADMIN > ROLE_OPERATOR
'''
grails.plugin.springsecurity.useSwitchUserFilter = true
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
'/j_spring_security_switch_user': ['permitAll'],
'/api/**': ['permitAll']
]
grails.plugin.springsecurity.filterChain.chainMap = [
//'/api/**': 'JOINED_FILTERS,-anonymousAuthenticationFilter,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter',// Stateless chain
'/api/**': 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter',
'/**': 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter', // Traditional chain
]
//gorm
grails.plugin.springsecurity.rest.token.storage.useGorm = true
grails.plugin.springsecurity.rest.token.storage.gorm.tokenDomainClassName = 'org.sali.Rest.AuthenticationToken'
grails.plugin.springsecurity.rest.token.storage.gorm.tokenValuePropertyName = 'token'
grails.plugin.springsecurity.rest.token.storage.gorm.usernamePropertyName = 'username'
//login
grails.plugin.springsecurity.rest.login.active=true
grails.plugin.springsecurity.rest.login.useJsonCredentials = true
grails.plugin.springsecurity.rest.login.failureStatusCode = 401
grails.plugin.springsecurity.rest.login.usernamePropertyName = 'username'
grails.plugin.springsecurity.rest.login.passwordPropertyName='password'
grails.plugin.springsecurity.rest.login.endpointUrl='/api/login'
grails.plugin.springsecurity.rest.login.useRequestParamsCredentials = false
//logout
grails.plugin.springsecurity.rest.logout.endpointUrl='/api/logout'
//token generation
grails.plugin.springsecurity.rest.token.generation.useUUID=false
grails.plugin.springsecurity.rest.token.generation.useSecureRandom=true
//token rendering
grails.plugin.springsecurity.rest.token.rendering.usernamePropertyName='username'
grails.plugin.springsecurity.rest.token.rendering.authoritiesPropertyName='roles'
grails.plugin.springsecurity.rest.token.rendering.tokenPropertyName='token'
//token validate
grails.plugin.springsecurity.rest.token.validation.useBearerToken = true
//if disable 'Bearer', you can configure a custom header.
//grails.plugin.springsecurity.rest.token.validation.useBearerToken = false
//grails.plugin.springsecurity.rest.token.rendering.tokenPropertyName access_token
//grails.plugin.springsecurity.rest.token.validation.headerName = 'x-auth-token'
grails.plugin.springsecurity.rest.token.validation.active=true
grails.plugin.springsecurity.rest.token.validation.endpointUrl='/api/validate'
//grails.plugin.springsecurity.rest.token.validation.headerName = 'X-Auth-Token'
//grails.plugin.springsecurity.rest.token.validation.useBearerToken = false
//grails.plugin.springsecurity.password.algorithm = 'SHA-256'
//grails.plugin.springsecurity.password.hash.iterations = 1
//cors
cors.enabled=true
cors.url.pattern = '/api/*'
cors.headers=[
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': true,
'Access-Control-Allow-Headers': 'origin, authorization, accept, content-type, x-requested-with,X-Auth-Token',
'Access-Control-Allow-Methods': 'GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS',
'Access-Control-Max-Age': 3600
]
UrlMappings.groovy
class UrlMappings
static mappings =
"/$controller/$action?/$id?"
constraints
// apply constraints here
"/"(controller: "login")
"404"(view:'/error')
"405"(view:'/error')
"500"(view:'/error')
"/login/$action?"(controller: "login")
"/logout/$action?"(controller: "logout")
非常欢迎任何想法。谢谢
【问题讨论】:
我认为首先你应该在你的控制器中放置一个断点来检查请求是否真的到达那里。 你的意思是什么控制器?据我所知,spring security rest 插件将这个 /api/login 暴露给身份验证。即使我像你说的那样设置断点,也不会到达。 您的配置似乎是正确的。如果我没记错的话,万一登录失败,由于此配置,服务器将响应 401 错误代码 -grails.plugin.springsecurity.rest.login.failureStatusCode = 401
。断点的想法是确认请求已到达后端代码,并且该特定 url 的过滤器没有任何问题。
如果您为grails.plugin.springsecurity
和org.springframework
启用日志,它也会很有用。 This link 将帮助您启用日志。
这是个好主意。我只是想知道... 401 可能是由来自chainMap 的过滤器引起的,我是否应该在UrlMappings 中添加一些内容以公开和启用/api/login?我确定我在配置中遗漏了一些东西。
【参考方案1】:
在 Config.groovy 中添加这些后工作:
grails.plugin.springsecurity.password.algorithm = 'SHA-256'
grails.plugin.springsecurity.password.hash.iterations = 1
【讨论】:
【参考方案2】:如果其他人仍在寻找解决方案,并且尝试了规则但没有运气,请检查类是否正确:
grails.plugin.springsecurity.userLookup.userDomainClassName = 'com.site.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'com.site.UserRole'
grails.plugin.springsecurity.authority.className = 'com.site.Role'
在我的例子中,我有 com.site.User
类并且我设置了 com.site.user.User
,这产生了这个问题!
参考:https://github.com/alvarosanchez/grails-spring-security-rest/issues/181#issuecomment-82260495
【讨论】:
以上是关于grails spring security rest /api/login 401 Unauthorized的主要内容,如果未能解决你的问题,请参考以下文章
Grails - grails-spring-security-rest - 无法从 application.yml 加载 jwt 机密
grails-spring-security-rest 插件和悲观锁定