Permalink
Browse files

Install the sprint-security-core plugin.

 * Create User and Role classes.
  • Loading branch information...
1 parent 2d9f9b5 commit ee648c1484f60706e4e9a004f4f391d5139967ab @jeantessier committed May 15, 2012
@@ -1,5 +1,5 @@
#Grails Metadata file
-#Mon May 14 22:37:46 PDT 2012
+#Mon May 14 22:57:54 PDT 2012
app.grails.version=2.0.3
app.name=martine
app.servlet.version=2.5
@@ -9,4 +9,5 @@ plugins.joda-time=1.4
plugins.mail=1.0
plugins.pretty-time=0.3
plugins.quartz2=0.2.2
+plugins.spring-security-core=1.2.7.3
plugins.svn=1.0.1
@@ -91,3 +91,8 @@ log4j = {
'org.hibernate',
'net.sf.ehcache.hibernate'
}
+
+// Added by the Spring Security Core plugin:
+grails.plugins.springsecurity.userLookup.userDomainClassName = 'com.martine.user.User'
+grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'com.martine.user.UserRole'
+grails.plugins.springsecurity.authority.className = 'com.martine.user.Role'
@@ -0,0 +1,134 @@
+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)
+ }
+}
@@ -0,0 +1,12 @@
+import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
+
+class LogoutController {
+
+ /**
+ * Index action. Redirects to the Spring security logout uri.
+ */
+ def index = {
+ // TODO put any pre-logout code here
+ redirect uri: SpringSecurityUtils.securityConfig.logout.filterProcessesUrl // '/j_spring_security_logout'
+ }
+}
@@ -0,0 +1,14 @@
+package com.martine.user
+
+class Role {
+
+ String authority
+
+ static mapping = {
+ cache true
+ }
+
+ static constraints = {
+ authority blank: false, unique: true
+ }
+}
@@ -0,0 +1,40 @@
+package com.martine.user
+
+class User {
+
+ transient springSecurityService
+
+ String username
+ String password
+ boolean enabled
+ boolean accountExpired
+ boolean accountLocked
+ boolean passwordExpired
+
+ static constraints = {
+ username blank: false, unique: true
+ password blank: false
+ }
+
+ static mapping = {
+ password column: '`password`'
+ }
+
+ Set<Role> getAuthorities() {
+ UserRole.findAllByUser(this).collect { it.role } as Set
+ }
+
+ def beforeInsert() {
+ encodePassword()
+ }
+
+ def beforeUpdate() {
+ if (isDirty('password')) {
+ encodePassword()
+ }
+ }
+
+ protected void encodePassword() {
+ password = springSecurityService.encodePassword(password)
+ }
+}
@@ -0,0 +1,57 @@
+package com.martine.user
+
+import org.apache.commons.lang.builder.HashCodeBuilder
+
+class UserRole implements Serializable {
+
+ User user
+ Role role
+
+ boolean equals(other) {
+ if (!(other instanceof UserRole)) {
+ return false
+ }
+
+ other.user?.id == user?.id &&
+ other.role?.id == role?.id
+ }
+
+ int hashCode() {
+ def builder = new HashCodeBuilder()
+ if (user) builder.append(user.id)
+ if (role) builder.append(role.id)
+ builder.toHashCode()
+ }
+
+ static UserRole get(long userId, long roleId) {
+ find 'from UserRole where user.id=:userId and role.id=:roleId',
+ [userId: userId, roleId: roleId]
+ }
+
+ static UserRole create(User user, Role role, boolean flush = false) {
+ new UserRole(user: user, role: role).save(flush: flush, insert: true)
+ }
+
+ static boolean remove(User user, Role role, boolean flush = false) {
+ UserRole instance = UserRole.findByUserAndRole(user, role)
+ if (!instance) {
+ return false
+ }
+
+ instance.delete(flush: flush)
+ true
+ }
+
+ static void removeAll(User user) {
+ executeUpdate 'DELETE FROM UserRole WHERE user=:user', [user: user]
+ }
+
+ static void removeAll(Role role) {
+ executeUpdate 'DELETE FROM UserRole WHERE role=:role', [role: role]
+ }
+
+ static mapping = {
+ id composite: ['role', 'user']
+ version false
+ }
+}
Oops, something went wrong.

0 comments on commit ee648c1

Please sign in to comment.