Skip to content

Commit

Permalink
again a sample app for zyro23/grails-spring-websocket#64 (this time w…
Browse files Browse the repository at this point in the history
…ith spring-security-core)
  • Loading branch information
zyro23 committed Apr 23, 2018
1 parent 760eeca commit f2e7168
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 36 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ dependencies {
testRuntime "net.sourceforge.htmlunit:htmlunit:2.18"

compile "org.grails.plugins:grails-spring-websocket:2.4.1"
compile "org.grails.plugins:spring-security-core:3.2.1"
compile "org.springframework.security:spring-security-config"
compile "org.springframework.security:spring-security-messaging"
compile "org.springframework.security:spring-security-web"
}

bootRun {
Expand Down
29 changes: 29 additions & 0 deletions grails-app/conf/application.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@


// Added by the Spring Security Core plugin:
grails.plugin.springsecurity.userLookup.userDomainClassName = 'myapp.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'myapp.UserRole'
grails.plugin.springsecurity.authority.className = 'myapp.Role'
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
[pattern: '/', access: ['permitAll']],
[pattern: '/error', access: ['permitAll']],
[pattern: '/index', access: ['permitAll']],
[pattern: '/index.gsp', access: ['permitAll']],
[pattern: '/shutdown', access: ['permitAll']],
[pattern: '/assets/**', access: ['permitAll']],
[pattern: '/**/js/**', access: ['permitAll']],
[pattern: '/**/css/**', access: ['permitAll']],
[pattern: '/**/images/**', access: ['permitAll']],
[pattern: '/**/favicon.ico', access: ['permitAll']],
[pattern: '/stomp/**', access: ['hasRole("USER")']],
]

grails.plugin.springsecurity.filterChain.chainMap = [
[pattern: '/assets/**', filters: 'none'],
[pattern: '/**/js/**', filters: 'none'],
[pattern: '/**/css/**', filters: 'none'],
[pattern: '/**/images/**', filters: 'none'],
[pattern: '/**/favicon.ico', filters: 'none'],
[pattern: '/**', filters: 'JOINED_FILTERS']
]

2 changes: 2 additions & 0 deletions grails-app/controllers/myapp/ExampleController.groovy
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package myapp

import grails.plugin.springsecurity.annotation.Secured
import grails.web.controllers.ControllerMethod
import org.springframework.messaging.handler.annotation.MessageExceptionHandler
import org.springframework.messaging.handler.annotation.MessageMapping
Expand All @@ -9,6 +10,7 @@ import org.springframework.security.access.prepost.PreAuthorize

class ExampleController {

@Secured("hasRole('USER')")
def index() {}

@ControllerMethod
Expand Down
23 changes: 23 additions & 0 deletions grails-app/domain/myapp/Role.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package myapp

import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import grails.compiler.GrailsCompileStatic

@GrailsCompileStatic
@EqualsAndHashCode(includes='authority')
@ToString(includes='authority', includeNames=true, includePackage=false)
class Role implements Serializable {

private static final long serialVersionUID = 1

String authority

static constraints = {
authority nullable: false, blank: false, unique: true
}

static mapping = {
cache true
}
}
33 changes: 33 additions & 0 deletions grails-app/domain/myapp/User.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package myapp

import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import grails.compiler.GrailsCompileStatic

@GrailsCompileStatic
@EqualsAndHashCode(includes='username')
@ToString(includes='username', includeNames=true, includePackage=false)
class User implements Serializable {

private static final long serialVersionUID = 1

String username
String password
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired

Set<Role> getAuthorities() {
(UserRole.findAllByUser(this) as List<UserRole>)*.role as Set<Role>
}

static constraints = {
password nullable: false, blank: false, password: true
username nullable: false, blank: false, unique: true
}

static mapping = {
password column: '`password`'
}
}
87 changes: 87 additions & 0 deletions grails-app/domain/myapp/UserRole.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package myapp

import grails.gorm.DetachedCriteria
import groovy.transform.ToString

import org.codehaus.groovy.util.HashCodeHelper
import grails.compiler.GrailsCompileStatic

@GrailsCompileStatic
@ToString(cache=true, includeNames=true, includePackage=false)
class UserRole implements Serializable {

private static final long serialVersionUID = 1

User user
Role role

@Override
boolean equals(other) {
if (other instanceof UserRole) {
other.userId == user?.id && other.roleId == role?.id
}
}

@Override
int hashCode() {
int hashCode = HashCodeHelper.initHash()
if (user) {
hashCode = HashCodeHelper.updateHash(hashCode, user.id)
}
if (role) {
hashCode = HashCodeHelper.updateHash(hashCode, role.id)
}
hashCode
}

static UserRole get(long userId, long roleId) {
criteriaFor(userId, roleId).get()
}

static boolean exists(long userId, long roleId) {
criteriaFor(userId, roleId).count()
}

private static DetachedCriteria criteriaFor(long userId, long roleId) {
UserRole.where {
user == User.load(userId) &&
role == Role.load(roleId)
}
}

static UserRole create(User user, Role role, boolean flush = false) {
def instance = new UserRole(user: user, role: role)
instance.save(flush: flush)
instance
}

static boolean remove(User u, Role r) {
if (u != null && r != null) {
UserRole.where { user == u && role == r }.deleteAll()
}
}

static int removeAll(User u) {
u == null ? 0 : UserRole.where { user == u }.deleteAll() as int
}

static int removeAll(Role r) {
r == null ? 0 : UserRole.where { role == r }.deleteAll() as int
}

static constraints = {
user nullable: false
role nullable: false, validator: { Role r, UserRole ur ->
if (ur.user?.id) {
if (UserRole.exists(ur.user.id, r.id)) {
return ['userRole.exists']
}
}
}
}

static mapping = {
id composite: ['user', 'role']
version false
}
}
3 changes: 3 additions & 0 deletions grails-app/init/myapp/Application.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package myapp

import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration
import org.springframework.context.annotation.ComponentScan

@ComponentScan
@EnableAutoConfiguration(exclude = [SecurityFilterAutoConfiguration])
class Application extends GrailsAutoConfiguration {
static void main(String[] args) {
GrailsApp.run(Application, args)
Expand Down
9 changes: 9 additions & 0 deletions grails-app/init/myapp/BootStrap.groovy
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
package myapp

import grails.plugin.springsecurity.SpringSecurityService

class BootStrap {

SpringSecurityService springSecurityService

def init = { servletContext ->
User.withNewTransaction {
Role role = new Role(authority: "ROLE_USER").save()
User user = new User(username: "user", password: springSecurityService.encodePassword("password")).save()
UserRole.create user, role, true
}
}
def destroy = {
}
Expand Down
35 changes: 0 additions & 35 deletions grails-app/init/myapp/WebSecurityConfig.groovy

This file was deleted.

2 changes: 2 additions & 0 deletions grails-app/init/myapp/WebSocketSecurityConfig.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package myapp

import org.springframework.context.annotation.Configuration
import org.springframework.messaging.simp.SimpMessageType
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity
import org.springframework.security.config.annotation.web.messaging.MessageSecurityMetadataSourceRegistry
import org.springframework.security.config.annotation.web.socket.AbstractSecurityWebSocketMessageBrokerConfigurer

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

@Override
Expand Down

0 comments on commit f2e7168

Please sign in to comment.