springboot集成shiro

释放双眼,带上耳机,听听看~!

一、概念

Shiro是一个Java安全框架,可以帮助我们完成:认证、授权、加密、会话管理、与Web集成、缓存等。

 

springboot集成shiro

 

 

**Subject:**即当前用户,在权限管理的应用程序里往往需要知道谁能够操作什么,谁拥有操作该程序的权利,shiro中则需要通过Subject来提供基础的当前用户信息,Subject 不仅仅代表某个用户,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。

**SecurityManager:**管理所有Subject,这是Shiro框架的核心组件,可以把他看做是一个Shiro框架的全局管理组件,用于调度各种Shiro框架的服务。

**Realm:**域,Shiro从从Realm获取安全数据(如用户、角色、权限),可以看成数据库。

 

认证流程:

springboot集成shiro

 

使用流程:

 1. 自定义realm

 

 2.构建SecurityManager环境

 

 3.提交认证,将携带的信息储存在 UsernamePasswordToken中


1
2
1UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username,password);
2

 4.获取subject


1
2
1Subject subject = SecurityUtils.getSubject();
2

5.登录


1
2
1subject.login(usernamePasswordToken);
2

 

 

二、代码

代码层级

springboot集成shiro

 

1.pom文件


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
1<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2  <modelVersion>4.0.0</modelVersion>
3  <artifactId>springboot-shiro-10095</artifactId>
4  
5   <parent>
6       <groupId>org.springframework.boot</groupId>
7       <artifactId>spring-boot-starter-parent</artifactId>
8       <version>2.0.2.RELEASE</version>
9       <relativePath/>
10      </parent>
11  <dependencies>
12      <dependency>
13          <groupId>org.springframework.boot</groupId>
14          <artifactId>spring-boot-devtools</artifactId>
15        </dependency>
16      <dependency>
17            <groupId>org.springframework.boot</groupId>
18            <artifactId>spring-boot-starter-web</artifactId>
19        </dependency>
20        <dependency>
21            <groupId>org.springframework.boot</groupId>
22            <artifactId>spring-boot-starter-data-jpa</artifactId>
23        </dependency>
24        <dependency>
25          <groupId>mysql</groupId>
26          <artifactId>mysql-connector-java</artifactId>
27          <version>5.1.44</version>
28          <scope>runtime</scope>
29      </dependency>
30      <dependency>
31            <groupId>com.alibaba</groupId>
32            <artifactId>druid</artifactId>
33            <version>1.1.4</version>
34        </dependency>
35        <!-- shiro -->
36        <dependency>
37          <groupId>org.apache.shiro</groupId>
38          <artifactId>shiro-spring</artifactId>
39          <version>1.3.2</version>
40      </dependency>
41  </dependencies>
42 
43  <build>
44      <plugins>
45          <plugin>
46              <groupId>org.apache.maven.plugins</groupId>
47              <artifactId>maven-compiler-plugin</artifactId>
48              <configuration>
49                  <source>1.8</source>
50                  <target>1.8</target>
51              </configuration>
52          </plugin>
53      </plugins>
54  </build>
55
56</project>
57

2.application.yml


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
1server:
2  port: 10095
3spring:
4  application:
5    name: shiro
6#  zipkin:
7#    base-url: http://127.0.0.1:10092
8#eureka
9#eureka:
10#  client:
11#    service-url:
12#      defaultZone: http://localhost:10090/eureka/
13  datasource:
14    driver-class-name: com.mysql.jdbc.Driver
15    url: jdbc:mysql://localhost:3306/shiro?useUnicode=true&characterEncoding=UTF-8
16    username: root
17    password: root
18    type: com.alibaba.druid.pool.DruidDataSource
19  jpa:
20    show-sql: true
21    hibernate:
22      ddl-auto: update
23  http:
24    encoding:
25      charset: utf-8
26      enabled: true
27

 

3.关于shiro的表5张,利用JPA自动生成

(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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
1/**  
2 * All rights Reserved
3 * @Title:  User.java  
4 * @Package com.yanwu.www.entity  
5 * @Description: TODO(用一句话描述该文件做什么)  
6 * @author: harvey
7 * @date:   2018年8月30日 下午2:05:58  
8 * @version V1.0
9 * @Copyright: 2018
10 */
11package com.yanwu.www.entity;
12
13import java.util.List;
14
15import javax.persistence.Entity;
16import javax.persistence.GeneratedValue;
17import javax.persistence.GenerationType;
18import javax.persistence.Id;
19
20/**  
21 * @ClassName:  User  
22 * @Description:TODO(这里用一句话描述这个类的作用)  
23 * @author: harvey
24 * @date:   2018年8月30日 下午2:05:58  
25 *    
26 * @Copyright: 2018
27 */
28@Entity(name="user")
29public class User {
30  @Id
31    @GeneratedValue(strategy = GenerationType.AUTO)
32    private Long id;
33    
34    private String name;
35    private String password;
36
37    public Long getId() {
38        return id;
39    }
40
41    public void setId(Long id) {
42        this.id = id;
43    }
44
45    public String getName() {
46        return name;
47    }
48
49    public void setName(String name) {
50        this.name = name;
51    }
52
53  public String getPassword() {
54      return password;
55  }
56
57  public void setPassword(String password) {
58      this.password = password;
59  }
60
61    
62}
63

(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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
1/**  
2 * All rights Reserved
3 * @Title:  Role.java  
4 * @Package com.yanwu.www.entity  
5 * @Description: TODO(用一句话描述该文件做什么)  
6 * @author: harvey
7 * @date:   2018年8月30日 下午2:07:43  
8 * @version V1.0
9 * @Copyright: 2018
10 */
11package com.yanwu.www.entity;
12
13import javax.persistence.Entity;
14import javax.persistence.GeneratedValue;
15import javax.persistence.GenerationType;
16import javax.persistence.Id;
17
18/**  
19 * @ClassName:  Role  
20 * @Description:TODO(这里用一句话描述这个类的作用)  
21 * @author: harvey
22 * @date:   2018年8月30日 下午2:07:43  
23 *    
24 * @Copyright: 2018
25 */
26@Entity
27public class Role {
28  @Id
29    @GeneratedValue(strategy = GenerationType.AUTO)
30    private Long id;
31    private String roleName;
32
33    public Long getId() {
34        return id;
35    }
36
37    public void setId(Long id) {
38        this.id = id;
39    }
40
41    public String getRoleName() {
42        return roleName;
43    }
44
45    public void setRoleName(String roleName) {
46        this.roleName = roleName;
47    }
48}
49

(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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
1/**  
2 * All rights Reserved
3 * @Title:  Permission.java  
4 * @Package com.yanwu.www.entity  
5 * @Description: TODO(用一句话描述该文件做什么)  
6 * @author: harvey
7 * @date:   2018年8月30日 下午2:12:42  
8 * @version V1.0
9 * @Copyright: 2018
10 */
11package com.yanwu.www.entity;
12
13import javax.persistence.Entity;
14import javax.persistence.GeneratedValue;
15import javax.persistence.GenerationType;
16import javax.persistence.Id;
17
18/**  
19 * @ClassName:  Permission  
20 * @Description:TODO(这里用一句话描述这个类的作用)  
21 * @author: harvey
22 * @date:   2018年8月30日 下午2:12:42  
23 *    
24 * @Copyright: 2018
25 */
26@Entity
27public class Permission {
28 
29  @Id
30    @GeneratedValue(strategy = GenerationType.AUTO)
31    private Long id;
32 
33    private String permission;
34
35    public Long getId() {
36        return id;
37    }
38
39    public void setId(Long id) {
40        this.id = id;
41    }
42
43    public String getPermission() {
44        return permission;
45    }
46
47    public void setPermission(String permission) {
48        this.permission = permission;
49    }
50}
51

 

(4)UserRole 用户和角色关联


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
1/**  
2 * All rights Reserved
3 * @Title:  UserRole.java  
4 * @Package com.yanwu.www.entity  
5 * @Description: TODO(用一句话描述该文件做什么)  
6 * @author: harvey
7 * @date:   2018年8月30日 下午2:15:24  
8 * @version V1.0
9 * @Copyright: 2018
10 */
11package com.yanwu.www.entity;
12
13import javax.persistence.Entity;
14import javax.persistence.GeneratedValue;
15import javax.persistence.GenerationType;
16import javax.persistence.Id;
17
18/**  
19 * @ClassName:  UserRole  
20 * @Description:TODO(这里用一句话描述这个类的作用)  
21 * @author: harvey
22 * @date:   2018年8月30日 下午2:15:24  
23 *    
24 * @Copyright: 2018
25 */
26@Entity
27public class UserRole {
28  @Id
29    @GeneratedValue(strategy = GenerationType.AUTO)
30    private Long id;
31 
32  private String userId;
33 
34  private String roleId;
35
36  public Long getId() {
37      return id;
38  }
39
40  public void setId(Long id) {
41      this.id = id;
42  }
43
44  public String getUserId() {
45      return userId;
46  }
47
48  public void setUserId(String userId) {
49      this.userId = userId;
50  }
51
52  public String getRoleId() {
53      return roleId;
54  }
55
56  public void setRoleId(String roleId) {
57      this.roleId = roleId;
58  }
59}
60

(5)RolePermission 角色和权限关联


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
1/**  
2 * All rights Reserved
3 * @Title:  RolePermission.java  
4 * @Package com.yanwu.www.entity  
5 * @Description: TODO(用一句话描述该文件做什么)  
6 * @author: harvey
7 * @date:   2018年8月30日 下午2:17:02  
8 * @version V1.0
9 * @Copyright: 2018
10 */
11package com.yanwu.www.entity;
12
13import javax.persistence.Entity;
14import javax.persistence.GeneratedValue;
15import javax.persistence.GenerationType;
16import javax.persistence.Id;
17
18/**  
19 * @ClassName:  RolePermission  
20 * @Description:TODO(这里用一句话描述这个类的作用)  
21 * @author: harvey
22 * @date:   2018年8月30日 下午2:17:02  
23 *    
24 * @Copyright: 2018
25 */
26@Entity
27public class RolePermission {
28 
29  @Id
30    @GeneratedValue(strategy = GenerationType.AUTO)
31    private Long id;
32 
33  private String roleId;
34 
35  private String permissionId;
36
37  public Long getId() {
38      return id;
39  }
40
41  public void setId(Long id) {
42      this.id = id;
43  }
44
45  public String getRoleId() {
46      return roleId;
47  }
48
49  public void setRoleId(String roleId) {
50      this.roleId = roleId;
51  }
52
53  public String getPermissionId() {
54      return permissionId;
55  }
56
57  public void setPermissionId(String permissionId) {
58      this.permissionId = permissionId;
59  }
60 
61}
62

 

4.自定义realm(需要继承AuthorizingRealm)


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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
1/**  
2 * All rights Reserved
3 * @Title:  UserRealm.java  
4 * @Package com.yanwu.www.config  
5 * @Description: TODO(用一句话描述该文件做什么)  
6 * @author: harvey
7 * @date:   2018年8月30日 下午2:48:54  
8 * @version V1.0
9 * @Copyright: 2018
10 */
11package com.yanwu.www.config;
12
13import java.util.List;
14
15import org.apache.shiro.authc.AuthenticationException;
16import org.apache.shiro.authc.AuthenticationInfo;
17import org.apache.shiro.authc.AuthenticationToken;
18import org.apache.shiro.authc.SimpleAuthenticationInfo;
19import org.apache.shiro.authc.UnknownAccountException;
20import org.apache.shiro.authc.UsernamePasswordToken;
21import org.apache.shiro.authz.AuthorizationInfo;
22import org.apache.shiro.authz.SimpleAuthorizationInfo;
23import org.apache.shiro.crypto.hash.SimpleHash;
24import org.apache.shiro.realm.AuthorizingRealm;
25import org.apache.shiro.subject.PrincipalCollection;
26import org.apache.shiro.util.ByteSource;
27import org.springframework.beans.factory.annotation.Autowired;
28import org.springframework.stereotype.Component;
29
30import com.yanwu.www.entity.Permission;
31import com.yanwu.www.entity.Role;
32import com.yanwu.www.entity.User;
33import com.yanwu.www.repository.PermissionRipository;
34import com.yanwu.www.repository.RoleRipository;
35import com.yanwu.www.repository.UserRipository;
36
37/**  
38 * @ClassName:  UserRealm  
39 * @Description: 自定义realm  
40 * @author: harvey
41 * @date:   2018年8月30日 下午2:48:54  
42 *    
43 * @Copyright: 2018
44 */
45@Component
46public class MyShiroRealm extends AuthorizingRealm{
47
48  @Autowired
49  private UserRipository userRipository;
50 
51  @Autowired
52  private RoleRipository roleRipository;
53 
54  @Autowired
55  private PermissionRipository permissionRipository;
56 
57  /**  
58   * <p>Title: doGetAuthorizationInfo</p>  
59   * <p>Description: </p>  
60   * @param arg0
61   * @return  
62   * @see org.apache.shiro.realm.AuthorizingRealm#doGetAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection)  
63   */
64  @Override
65  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
66     
67      //获取登录用户名
68        String username= (String) principalCollection.getPrimaryPrincipal();
69        //查询用户名称
70        User user = userRipository.findByName(username);
71        
72        //添加角色和权限
73        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
74        List<Role> roles = roleRipository.findRolesByUserId(user.getId().toString());
75        for(Role role : roles){
76          // 添加角色
77          simpleAuthorizationInfo.addRole(role.getRoleName());
78          for(Permission permission : permissionRipository.findPermissionsByRoleId(role.getId().toString())){
79              // 添加权限
80              simpleAuthorizationInfo.addStringPermission(permission.getPermission());
81          }
82        }
83        
84        return simpleAuthorizationInfo;
85     
86  }
87
88  /**  
89   * <p>Title: doGetAuthenticationInfo</p>  
90   * <p>Description: </p>  
91   * @param arg0
92   * @return
93   * @throws AuthenticationException  
94   * @see org.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)  
95   */
96  @Override
97  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
98     
99      // 1.把AuthenticationToken转为UsernamePasswordToken对象
100     UsernamePasswordToken upToken = (UsernamePasswordToken) token;
101
102     // 2.从UsernamePasswordToken获取username
103     String userName = upToken.getUsername();
104
105     // 3.调用数据库方法,从数据库中查询username对应的用户记录
106     System.out.println("从数据库中获取信息userName:" + userName + "所对应信息");
107     User user = userRipository.findByName(userName);
108    
109     // 4.若用户不存在,则可以抛出异常
110     if (null == user) {
111         throw new UnknownAccountException("用户不存在");
112     }
113    
114     // 5.根据用户情况,来构建AuthenticationInfo对象并返回,通常使用的实现类是SimpleAuthenticationInfo
115    
116     // 1)principal,用户名,认证实体,可以是实体,也可以是数据表对应的实体类对象
117     Object principal = userName;
118    
119     // 2)credential,密码,明文密码,即构建UsernamePasswordToken对象时的密码
120     Object credentials = user.getPassword().toString();
121    
122     // 3)realmName:当前realm对象的name,调用父类的getName即可
123     String realmName = getName();
124    
125     // 4.盐值(避免同一密码加密时产生相同的字符串,一般是用用户名做盐值)
126     ByteSource credentialsSalt = ByteSource.Util.bytes(userName);
127
128     // 不加密
129     //SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credentials, realmName);
130    
131     // 加密
132     SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(principal,credentials, credentialsSalt, realmName);
133
134     return info;
135 }
136
137
138 // 增加用户时可以使用SimpleHash产生加密后的密码字符串存入数据库,避免数据库的用户密码明文显示
139 public static void main(String[] args) {
140     String algorithmName="MD5";
141     Object source="1234";
142     Object salt=ByteSource.Util.bytes("user2");
143     int hashIterations=1024;
144     Object result=new SimpleHash(algorithmName, source, salt, hashIterations);
145     System.out.println(result);
146 }
147
148}
149

 

5.shiro配置类


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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
1/**  
2 * All rights Reserved
3 * @Title:  ShiroConfig.java  
4 * @Package com.yanwu.www.config  
5 * @Description: TODO(用一句话描述该文件做什么)  
6 * @author: harvey
7 * @date:   2018年8月30日 下午2:47:16  
8 * @version V1.0
9 * @Copyright: 2018
10 */
11package com.yanwu.www.config;
12
13import java.util.HashMap;
14import java.util.Map;
15
16import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
17import org.apache.shiro.mgt.SecurityManager;
18import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
19import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
20import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
21import org.springframework.context.annotation.Bean;
22import org.springframework.context.annotation.Configuration;
23
24/**  
25 * @ClassName:  ShiroConfig  
26 * @Description:shiro配置类  
27 * @author: harvey
28 * @date:   2018年8月30日 下午2:47:16  
29 *    
30 * @Copyright: 2018
31 */
32@Configuration
33public class ShiroConfig {
34 
35 
36  /**
37     * 密码校验规则HashedCredentialsMatcher
38     * 这个类是为了对密码进行编码的 ,
39     * 防止密码在数据库里明码保存 , 当然在登陆认证的时候 ,
40     * 这个类也负责对form里输入的密码进行编码
41     * 处理认证匹配处理器:如果自定义需要实现继承HashedCredentialsMatcher
42     */
43    @Bean
44    public HashedCredentialsMatcher hashedCredentialsMatcher() {
45        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
46        //指定加密方式为MD5
47        credentialsMatcher.setHashAlgorithmName("MD5");
48        //加密次数
49        credentialsMatcher.setHashIterations(1024);
50        credentialsMatcher.setStoredCredentialsHexEncoded(true);
51        return credentialsMatcher;
52    }
53 
54  //将自己的验证方式加入容器
55    @Bean
56    public MyShiroRealm myShiroRealm() {
57        MyShiroRealm myShiroRealm = new MyShiroRealm();
58        
59        // 设置加密方式
60        myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
61        
62        return myShiroRealm;
63    }
64
65    //权限管理,配置主要是Realm的管理认证
66    @Bean
67    public SecurityManager securityManager() {
68        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
69        securityManager.setRealm(myShiroRealm());
70        
71        return securityManager;
72    }
73
74    //Filter工厂,设置对应的过滤条件和跳转条件
75    @Bean
76    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
77        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
78        shiroFilterFactoryBean.setSecurityManager(securityManager);
79        Map<String,String> map = new HashMap<String, String>();
80        
81        //anon表示可以匿名访问,authc表示需要认证
82        //登出
83        map.put("/logout","anon");
84        //对所有用户认证
85        map.put("/**","authc");
86        //登录
87        shiroFilterFactoryBean.setLoginUrl("/login");
88        
89        //首页
90        shiroFilterFactoryBean.setSuccessUrl("/index");
91        
92        //错误页面,认证不通过跳转
93        shiroFilterFactoryBean.setUnauthorizedUrl("/error");
94        
95        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
96        return shiroFilterFactoryBean;
97    }
98
99    //加入注解的使用,不加入这个注解不生效
100    @Bean
101    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
102        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
103        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
104        return authorizationAttributeSourceAdvisor;
105    }
106    
107}
108

 

6.Repositoty

(1)BaseRepository


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1package com.yanwu.www.repository;
2
3import java.io.Serializable;
4
5import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
6import org.springframework.data.repository.NoRepositoryBean;
7import org.springframework.data.repository.PagingAndSortingRepository;
8/**
9 *
10 * @ClassName:  BaseRepository  
11 * @Description:TODO(这里用一句话描述这个类的作用)  
12 * @author: harvey
13 * @date:   2018年8月30日 下午2:21:18  
14 *  
15 * @param <T>
16 * @param <I>  
17 * @Copyright: 2018
18 */
19@NoRepositoryBean
20public interface BaseRepository<T,I extends Serializable> extends PagingAndSortingRepository<T,I>,JpaSpecificationExecutor<T>{
21
22}
23

 

(2)UserRipository


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
1/**  
2 * All rights Reserved
3 * @Title:  UserRipository.java  
4 * @Package com.yanwu.www.repository  
5 * @Description: TODO(用一句话描述该文件做什么)  
6 * @author: harvey
7 * @date:   2018年8月30日 下午2:20:19  
8 * @version V1.0
9 * @Copyright: 2018
10 */
11package com.yanwu.www.repository;
12
13import org.springframework.stereotype.Repository;
14
15import com.yanwu.www.entity.User;
16
17/**  
18 * @ClassName:  UserRipository  
19 * @Description:TODO(这里用一句话描述这个类的作用)  
20 * @author: harvey
21 * @date:   2018年8月30日 下午2:20:19  
22 *    
23 * @Copyright: 2018
24 */
25@Repository
26public interface UserRipository extends BaseRepository<User, Long>{
27 
28  User findByName(String username);
29}
30

(3)RoleRipository


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
1/**  
2 * All rights Reserved
3 * @Title:  UserRipository.java  
4 * @Package com.yanwu.www.repository  
5 * @Description: TODO(用一句话描述该文件做什么)  
6 * @author: harvey
7 * @date:   2018年8月30日 下午2:20:19  
8 * @version V1.0
9 * @Copyright: 2018
10 */
11package com.yanwu.www.repository;
12
13import java.util.List;
14
15import org.springframework.data.jpa.repository.Query;
16import org.springframework.stereotype.Repository;
17
18import com.yanwu.www.entity.Role;
19
20/**  
21 * @ClassName:  UserRipository  
22 * @Description:TODO(这里用一句话描述这个类的作用)  
23 * @author: harvey
24 * @date:   2018年8月30日 下午2:20:19  
25 *    
26 * @Copyright: 2018
27 */
28@Repository
29public interface RoleRipository extends BaseRepository<Role, Long>{
30 
31  @Query(value = "select distinct r.* from role r inner join role_permission rp on rp.role_id = r.id inner join user_role ur on ur.role_id = r.id where ur.user_id =?1" ,nativeQuery=true)
32  List<Role> findRolesByUserId(String userId);
33}
34

(4)PermissionRipository


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
1/**  
2 * All rights Reserved
3 * @Title:  UserRipository.java  
4 * @Package com.yanwu.www.repository  
5 * @Description: TODO(用一句话描述该文件做什么)  
6 * @author: harvey
7 * @date:   2018年8月30日 下午2:20:19  
8 * @version V1.0
9 * @Copyright: 2018
10 */
11package com.yanwu.www.repository;
12
13import java.util.List;
14
15import org.springframework.data.jpa.repository.Query;
16import org.springframework.stereotype.Repository;
17
18import com.yanwu.www.entity.Permission;
19
20/**  
21 * @ClassName:  UserRipository  
22 * @Description:TODO(这里用一句话描述这个类的作用)  
23 * @author: harvey
24 * @date:   2018年8月30日 下午2:20:19  
25 *    
26 * @Copyright: 2018
27 */
28@Repository
29public interface PermissionRipository extends BaseRepository<Permission, Long>{
30 
31  @Query(value = "select distinct p.*  from permission p  inner join role_permission rp on rp.permission_id = p.id inner join role r on r.id = rp.role_id  where r.id =?1" ,nativeQuery=true)
32  List<Permission> findPermissionsByRoleId(String roleId);
33}
34

 

7.service

(1)UserService


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
1/**  
2 * All rights Reserved
3 * @Title:  UserService.java  
4 * @Package com.yanwu.www.service  
5 * @Description: TODO(用一句话描述该文件做什么)  
6 * @author: harvey
7 * @date:   2018年8月30日 下午2:25:11  
8 * @version V1.0
9 * @Copyright: 2018
10 */
11package com.yanwu.www.service;
12
13/**  
14 * @ClassName:  UserService  
15 * @Description:TODO(这里用一句话描述这个类的作用)  
16 * @author: harvey
17 * @date:   2018年8月30日 下午2:25:11  
18 *    
19 * @Copyright: 2018
20 */
21public interface UserService {
22  /**
23   *
24   * @Title: login  
25   * @Description: 用户登录  
26   * @param username
27   * @param password
28   * @return
29   * @return: String
30   */
31  String login(String username,String password);
32 
33  /**
34   *
35   * @Title: logout  
36   * @Description: 用户登出  
37   * @return
38   * @return: String
39   */
40  String logout();
41}
42

 

(2)UserServiceImpl


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
1/**  
2 * All rights Reserved
3 * @Title:  UserServiceImpl.java  
4 * @Package com.yanwu.www.service  
5 * @Description: TODO(用一句话描述该文件做什么)  
6 * @author: harvey
7 * @date:   2018年8月30日 下午2:27:15  
8 * @version V1.0
9 * @Copyright: 2018
10 */
11package com.yanwu.www.service;
12
13import org.apache.shiro.SecurityUtils;
14import org.apache.shiro.authc.AuthenticationException;
15import org.apache.shiro.authc.UnknownAccountException;
16import org.apache.shiro.authc.UsernamePasswordToken;
17import org.apache.shiro.subject.Subject;
18import org.springframework.stereotype.Component;
19import org.springframework.util.StringUtils;
20
21/**  
22 * @ClassName:  UserServiceImpl  
23 * @Description:TODO(这里用一句话描述这个类的作用)  
24 * @author: harvey
25 * @date:   2018年8月30日 下午2:27:15  
26 *    
27 * @Copyright: 2018
28 */
29@Component
30public class UserServiceImpl implements UserService {
31
32  /**  
33   * <p>Title: login</p>  
34   * <p>Description: </p>  
35   * @param username
36   * @param password  
37   * @see com.yanwu.www.service.UserService#login(java.lang.String, java.lang.String)  
38   */
39  @Override
40  public String login(String username, String password) {
41     
42      if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)){
43          throw new UnknownAccountException("账号或者密码为空");
44      }
45     
46      UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username,password);
47     
48      Subject subject = SecurityUtils.getSubject();
49     
50      try{
51          subject.login(usernamePasswordToken);
52         
53          // 设置闲置session时间
54          subject.getSession().setTimeout(5*1000);
55          return "login ok";
56      }catch( AuthenticationException e){
57          System.out.println("==========");
58          System.out.println(e.getMessage());
59      }
60     
61      return "login failure";
62
63  }
64
65  /**  
66   * <p>Title: logout</p>  
67   * <p>Description: </p>  
68   * @return  
69   * @see com.yanwu.www.service.UserService#logout()  
70   */
71  @Override
72  public String logout() {
73     
74      Subject subject = SecurityUtils.getSubject();
75     
76      subject.logout();
77     
78      return "logout ok";
79  }
80}
81

8.controller


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
1/**  
2 * All rights Reserved
3 * @Title:  UserController.java  
4 * @Package com.yanwu.www.controller  
5 * @Description: TODO(用一句话描述该文件做什么)  
6 * @author: harvey
7 * @date:   2018年8月30日 下午3:31:43  
8 * @version V1.0
9 * @Copyright: 2018
10 */
11package com.yanwu.www.controller;
12
13import org.apache.shiro.authz.annotation.RequiresRoles;
14import org.springframework.beans.factory.annotation.Autowired;
15import org.springframework.web.bind.annotation.RequestMapping;
16import org.springframework.web.bind.annotation.RequestMethod;
17import org.springframework.web.bind.annotation.RestController;
18
19import com.yanwu.www.service.UserService;
20
21/**  
22 * @ClassName:  UserController  
23 * @Description:TODO(这里用一句话描述这个类的作用)  
24 * @author: harvey
25 * @date:   2018年8月30日 下午3:31:43  
26 *    
27 * @Copyright: 2018
28 */
29@RestController
30public class UserController {
31 
32  @Autowired
33  private UserService userService;
34 
35  //登录
36    @RequestMapping(value = "/login")
37    public String login(String username,String password){
38     
39      String status = userService.login(username, password);
40     
41        return status;
42    }
43    
44    //首页
45    @RequestMapping(value = "/index")
46    public String index(){
47    
48        return "index";
49    }
50 
51  //登出
52    @RequestMapping(value = "/logout")
53    public String logout(){
54     
55      userService.logout();
56     
57        return "logout";
58    }
59
60    //错误页面展示
61    @RequestMapping(value = "/error",method = RequestMethod.POST)
62    public String error(){
63        return "error ok!";
64    }
65    
66    // 测试shiro注解
67    @RequestMapping(value = "/test",method = RequestMethod.GET)
68    @RequiresRoles(value={"admin"})
69    public String test(){
70        return "test ok!";
71    }
72    
73    
74}
75

三、注意点

加密

本博客已经配置,需要在自定义realm,securityManager进行修改,如下配置如何获得加密后的字符串


1
2
3
4
5
6
7
8
9
10
11
1// 增加用户时可以使用SimpleHash产生加密后的密码字符串存入数据库,避免数据库的用户密码明文显示
2public static void main(String[] args) {
3  String algorithmName="MD5";
4  Object source="1234";
5  // 加盐
6  Object salt=ByteSource.Util.bytes("user2");
7  int hashIterations=1024;
8  Object result=new SimpleHash(algorithmName, source, salt, hashIterations);
9  System.out.println(result);
10}
11

给TA打赏
共{{data.count}}人
人已打赏
安全技术

C/C++内存泄漏及检测

2022-1-11 12:36:11

安全运维

【下一代核心技术DevOps】:(一)容器服务的Rancher选型

2021-10-12 11:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索