This time code only.
1. Entity classes
You will also have to write simple DAOs for entity classes.
1.1 User 
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 | package pl.dziurdziak.shiro.jpaRealm.user;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import pl.dziurdziak.shiro.jpaRealm.permission.Permission;
import pl.dziurdziak.shiro.jpaRealm.role.Role;
@Entity
@Table(name = "users")
public class User {
 @Id
 @GeneratedValue
 private long id;
 @NotNull
 private String login;
 @NotNull
 @Column(length = 64)
 private String password;
 @NotNull
 @Column(length = 80)
 private String salt;
 @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
 private Set<Role> roles;
 @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER)
 private Set<Permission> permissions;
 
 // getters and setters omitted
}
 | 
 
1.2 Role
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 | package pl.dziurdziak.easyReckoning.model.role;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.validation.constraints.Size;
import pl.dziurdziak.shiro.jpaRealm.user.User;
@Entity
@Table(name = "roles")
public class Role {
 @Id
 @GeneratedValue
 private long id;
 @Size(max = 100)
 private String roleName;
 @ManyToMany(mappedBy = "roles")
 private Set<User> users;
 // getters and setters ommitted
}
 | 
 
1.3 Permission
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 | package pl.dziurdziak.shiro.jpaRealm.permission;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.Size;
import pl.dziurdziak.shiro.jpaRealm.User;
@Entity
@Table(name = "permissions")
public class Permission {
 @Id
 @GeneratedValue
 private long id;
 @Size(max = 100)
 private String permission;
 @ManyToOne()
 @JoinColumn(name = "USER_ID")
 private User user;
 // getters and setters omitted
}
 | 
 
2. Realm
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84 | package pl.dziurdziak.shiro.jpaRealm.realm;
import java.util.HashSet;
import java.util.Set;
import javax.enterprise.inject.Default;
import javax.inject.Inject;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAccount;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.authz.permission.WildcardPermission;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import pl.dziurdziak.shiro.jpaRealm.permission.Permission;
import pl.dziurdziak.shiro.jpaRealm.role.Role;
import pl.dziurdziak.shiro.jpaRealm.user.User;
import pl.dziurdziak.shiro.jpaRealm.user.UserDao;
public class JpaAuthorizingRealm extends AuthorizingRealm {
 public static final String REALM_NAME = "MY_REALM";
 public static final int HASH_ITERATIONS = 200;
 @Inject
 private UserDao userDao;
 @Override
 protected AuthorizationInfo doGetAuthorizationInfo(final PrincipalCollection principals) {
  final String username = (String) principals.getPrimaryPrincipal();
  final User user = userDao.findByLogin(username);
  final Set<String> roles = new HashSet<>(user.getRoles().size());
  for (final Role role : user.getRoles()) {
   roles.add(role.getRoleName());
  }
  final Set<pl.dziurdziak.shiro.jpaRealm.permission.Permission> permissions = new HashSet<>(user.getPermissions().size());
  for (final Permission permission : user.getPermissions()) {
   permissions.add(new WildcardPermission(permission.getPermission()));
  }
  final SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(roles);
  authorizationInfo.setObjectPermissions(permissions);
  return authorizationInfo;
 }
 @Override
 protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken token) throws AuthenticationException {
  if (!(token instanceof UsernamePasswordToken)) {
   throw new IllegalStateException("Token has to be instance of UsernamePasswordToken class");
  }
  final UsernamePasswordToken userPassToken = (UsernamePasswordToken) token;
  if (userPassToken.getUsername() == null) {
   throw new AccountException("Null usernames are not allowed by this realm.");
  }
  final User user = userDao.findByLogin(userPassToken.getUsername());
  final SimpleAccount simpleAccount = new SimpleAccount(user.getLogin(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()),
    REALM_NAME);
  return simpleAccount;
 }
 @Override
 @Inject
 public void setCredentialsMatcher(final CredentialsMatcher credentialsMatcher) {
  super.setCredentialsMatcher(credentialsMatcher);
 }
}
 | 
 
3. Utils class
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 | package pl.dziurdziak.shiro.jpaRealm;
import javax.enterprise.inject.Default;
import javax.enterprise.inject.Produces;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.crypto.hash.SimpleHash;
import pl.dziurdziak.shiro.jpaRealm.realm.JpaAuthorizingRealm;
public final class JpaSecurityUtil {
 public static final int SALT_LENGTH = 80;
 public static final int PASSWORD_LENGTH = 64;
 public static String getSalt() {
  return new SecureRandomNumberGenerator().nextBytes(60).toBase64();
 }
 public static String hashPassword(final String value, final String salt) {
  final Sha256Hash sha256Hash = new Sha256Hash(value, salt, VaadinAuthorizingRealm.HASH_ITERATIONS);
  return sha256Hash.toHex();
 }
 @Produces
 @Default
 public CredentialsMatcher getCredentialMatcher() {
  final HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
  credentialsMatcher.setHashAlgorithmName(Sha256Hash.ALGORITHM_NAME);
  credentialsMatcher.setHashIterations(JpaAuthorizingRealm.HASH_ITERATIONS);
  return credentialsMatcher;
 }
 @Produces
 @Default
 public SimpleHash getHash() {
  final Sha256Hash sha256Hash = new Sha256Hash();
  sha256Hash.setIterations(JpaAuthorizingRealm.HASH_ITERATIONS);
  return sha256Hash;
 }
}
 | 
 
4. Usage
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18 | package pl.dziurdziak.shiro.jpaRealm;
import pl.dziurdziak.shiro.jpaRealm.user.User;
import pl.dziurdziak.shiro.jpaRealm.user.UserDao;
public class TestClass {
 @Inject
 private UserDao userDao;
 public void register(final String login, final String password) {
  User user = new User();
  user.setLogin(login);
  user.setSalt(JpaSecurityUtil.getSalt());
  user.setPassword(JpaSecurityUtil.hashPassword(password, user.getSalt()));
  userDao.persist(user);
 }
}
 |