springBoot(23):spring-security-基本

  1. 云栖社区>
  2. 博客>
  3. 正文

springBoot(23):spring-security-基本

科技探索者 2017-11-14 21:12:00 浏览570
展开阅读全文

一、简介

Web应用的安全管理,主要包括两个方面的内容:身份认证、用户授权,此处使用spring-cloud-security来说明。

二、依赖管理

1
2
3
4
5
6
7
8
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
   <groupId>org.thymeleaf.extras</groupId>
   <artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>


三、安全策略配置

Spring Security已经大体实现了,我们这里只是需要一些配置与引用。

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
package com.example.demo.config;
 
import com.example.demo.utils.security.CustomUserService;
import com.example.demo.utils.security.LoginSuccessHandler;
import com.example.demo.utils.security.MyFilterSecurityInterceptor;
import com.example.demo.utils.security.SecuritySettings;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
 
/**
 * Security安全配置
 *
 * @Author: 我爱大金子
 * @Description: Security安全配置
 * @Date: Create in 15:20 2017/7/5
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
    @Autowired
    private CustomFilterSecurityInterceptor customFilterSecurityInterceptor;    // 权限管理过滤器
    @Autowired
    private SecuritySettings securitySettings;     // 自定义安全配置类
 
    /**注册UserDetailsService的bean*/
    @Bean
    public UserDetailsService customUserService(){
        return new CustomUserService();
    }
 
    /**登录认证*/
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserService()); //userDetailsService验证
 
    }
 
    /***设置不拦截规则*/
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/js/**""/css/**""/images/**""/druid/**");
    }
 
    /**安全策略配置*/
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 设置游客可以访问的URI
        if (StringUtils.isNotBlank(securitySettings.getPermitall())) {
            http.authorizeRequests().antMatchers(securitySettings.getPermitall().split(",")).permitAll();
        }
 
        http.authorizeRequests()
                .anyRequest().authenticated() //任何请求,登录后可以访问
                // 配置登录URI、登录失败跳转URI与登录成功后默认跳转URI
                .and().formLogin().loginPage("/login").failureUrl("/login?error").permitAll().defaultSuccessUrl("/"true).successHandler(loginSuccessHandler())
                // 注销行为任意访问
                .and().logout().permitAll()
                // 设置拒绝访问的提示URI
                .and().exceptionHandling().accessDeniedPage("/login?illegal")
        ;
 
        http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);
    }
 
    /**登录成功处理器*/
    private AuthenticationSuccessHandler loginSuccessHandler() {
        return new LoginSuccessHandler();
    }
}

说明:

 loginPage:设置一个实验自定义的登录URI

 loginSuccessHandler:设置自定义的登录处理器

 permitAll:是允许访问

 accessDeniedPage:配置拒绝访问的提示URI

 antMatchers:对URI的配置


假设我要管理员才可以访问admin文件夹下的内容,如:.antMatchers("/admin/**").hasRole("ROLE_ADMIN"),

也可以设置admin文件夹下的文件可以有多个角色来访问,如:.antMatchers("/admin/**").hasAnyRole("ROLE_ADMIN","ROLE_USER")

也可以通过hasIpAddress来指定某一个ip可以访问该资源,写法如下.antMatchers("/admin/**").hasIpAddress("210.210.210.210") 


wKioL1le6lbRnu1KAAFucw-RHo4498.jpg


3.1、自定义安全配置类 

为是更方便的使用springSecurity,我们自定义一个权限的配置类,如配置登录的URI、游客访问的URI等配置项

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
package com.example.demo.utils.security;
 
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
 
/**
 * 自定义安全配置类
 *
 * @Author: 我爱大金子
 * @Description: 自定义安全配置类
 * @Date: Create in 9:45 2017/7/6
 */
@Configuration
@ConfigurationProperties(prefix = "securityConfig")
public class SecuritySettings {
    /**允许访问的URL,多个用逗号分隔*/
    private String permitall;
 
    public String getPermitall() {
        return permitall;
    }
 
    public void setPermitall(String permitall) {
        this.permitall = permitall;
    }
}

3.2、登录成功处理器

登录成功后,如果需要对用户的行为做一些记录或者执行其它操作,则可以使用登录成功处理器。

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
package com.example.demo.utils.security;
 
import com.example.demo.pojo.SysUser;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
 
/**
 * 登录成功处理器
 *
 * @Author: 我爱大金子
 * @Description: 登录成功处理器
 * @Date: Create in 11:35 2017/7/6
 */
public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {
        User userDetails = (User) authentication.getPrincipal();
        System.out.println("登录用户:username=" + userDetails.getUsername() + ", uri=" + request.getContextPath());
        super.onAuthenticationSuccess(request, response, authentication);
    }
}

3.3、springMVC 配置(访问 /login 转向 login.html 页面)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.example.demo.config;
 
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
 
/**
 * springMVC 配置(注册访问 /login 转向 login.html 页面)
 *
 * @Author: 我爱大金子
 * @Description: springMVC 配置(注册访问 /login 转向 login.html 页面)
 * @Date: Create in 16:24 2017/7/5
 */
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
 
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
    }
}


四、登录认证

在安全策略配置代码中有,主要看自定义的CustomUserService,此类实现了UserDetailsService接口,重写了loadUserByUsername方法

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
package com.example.demo.utils.security;
 
import com.example.demo.dao.SysPermissionDao;
import com.example.demo.dao.SysUserDao;
import com.example.demo.pojo.SysPermission;
import org.springframework.security.core.userdetails.User;
import com.example.demo.pojo.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 * 自定义UserDetailsService,将用户权限交给springsecurity进行管控
 *
 * @Author: 我爱大金子
 * @Description: 将用户权限交给Springsecurity进行管控
 * @Date: Create in 16:19 2017/7/5
 */
public class CustomUserService implements UserDetailsService {
    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysPermissionDao sysPermissionDao;
 
    @Override
    public UserDetails loadUserByUsername(String username) {
        SysUser user = sysUserDao.findByUserName(username);
        if (user != null) {
            List<SysPermission> permissions = sysPermissionDao.findByAdminUserId(user.getId());
            List<GrantedAuthority> grantedAuthorities = new ArrayList <>();
            for (SysPermission permission : permissions) {
                if (permission != null && permission.getName()!=null) {
                    GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName());
                    //1:此处将权限信息添加到 GrantedAuthority 对象中,在后面进行全权限验证时会使用GrantedAuthority 对象。
                    grantedAuthorities.add(grantedAuthority);
                }
            }
            return new User(user.getUsername(), user.getPassword(), grantedAuthorities);
        else {
            throw new UsernameNotFoundException("admin: " + username + " do not exist!");
        }
    }
}


五、权限管理

在Security安全配置类中使用了权限管理过滤器CustomFilterSecurityInterceptor

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
package com.example.demo.utils.security;
 
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Service;
 
import java.io.IOException;
 
/**
 * 权限管理过滤器
 *
 * @Author: 我爱大金子
 * @Description: 权限管理过滤器
 * @Date: Create in 17:16 2017/7/5
 */
@Service
public class CustomFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
    @Autowired
    private CustomFilterInvocationSecurityMetadataSource customFilterInvocationSecurityMetadataSource;  // 权限配置资源管理器
 
    /**权限管理决断器*/
    @Autowired
    public void setMyAccessDecisionManager(CustomAccessDecisionManager customAccessDecisionManager) {
        super.setAccessDecisionManager(customAccessDecisionManager);
    }
 
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
 
    }
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
 
        FilterInvocation fi = new FilterInvocation(request, response, chain);
        invoke(fi);
    }
 
 
    public void invoke(FilterInvocation fi) throws IOException, ServletException {
        //fi里面有一个被拦截的url
        //里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限
        //再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够
        InterceptorStatusToken token = super.beforeInvocation(fi);
        try {
            //执行下一个拦截器
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
        finally {
            super.afterInvocation(token, null);
        }
    }
 
    @Override
    public void destroy() {
 
    }
 
    @Override
    public Class<?> getSecureObjectClass() {
        return FilterInvocation.class;
    }
 
    @Override
    public SecurityMetadataSource obtainSecurityMetadataSource() {
        return this.customFilterInvocationSecurityMetadataSource;
    }
}

说明:

 customFilterSecurityInterceptor:权限管理过滤器

 customAccessDecisionManager:权限管理决断器

 customFilterInvocationSecurityMetadataSource:权限配置资源管理器


其中过滤器在系统启动时开始工作,并同时导入权限配置资源管理器和权限管理决断器,对用户访问的资源进行管理。权限管理决断器对用户访问的资源与用户拥有的角色权限进行对比,以此来判断用户是否对某个资源具有访问权限。

5.1、权限管理过滤器

继承与AbstractSecurityInterceptor,实时监控用户的行为,防止用户访问未被授权的资源。

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 com.example.demo.utils.security;
 
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Service;
 
import java.io.IOException;
 
/**
 * 权限管理过滤器
 *
 * @Author: 我爱大金子
 * @Description: 权限管理过滤器
 * @Date: Create in 17:16 2017/7/5
 */
@Service
public class CustomFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
    Logger log = LoggerFactory.getLogger(CustomFilterSecurityInterceptor.class);
    @Autowired
    private CustomFilterInvocationSecurityMetadataSource customFilterInvocationSecurityMetadataSource;  // 权限配置资源管理器
 
    /**权限管理决断器*/
    @Autowired
    public void setMyAccessDecisionManager(CustomAccessDecisionManager customAccessDecisionManager) {
        super.setAccessDecisionManager(customAccessDecisionManager);
    }
 
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
 
    }
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
 
        FilterInvocation fi = new FilterInvocation(request, response, chain);
        log.info("【权限管理过滤器】请求URL:" + fi.getRequestUrl());
        invoke(fi);
    }
 
 
    public void invoke(FilterInvocation fi) throws IOException, ServletException {
        //fi里面有一个被拦截的url
        //里面调用CustomFilterInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限
        //再调用CustomAccessDecisionManager的decide方法来校验用户的权限是否足够
        InterceptorStatusToken token = super.beforeInvocation(fi);
        try {
            //执行下一个拦截器
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
        catch(Exception e) {
            log.error("【权限管理过滤器】【异常】" + e.getMessage(), e);
        finally {
            super.afterInvocation(token, null);
        }
    }
 
    @Override
    public void destroy() {
 
    }
 
    @Override
    public Class<?> getSecureObjectClass() {
        return FilterInvocation.class;
    }
 
    @Override
    public SecurityMetadataSource obtainSecurityMetadataSource() {
        return this.customFilterInvocationSecurityMetadataSource;
    }
}




5.2、权限管理决断器

权限管理的关键部分就是决断器,它实现了AccessDecisionManager,重写了decide方法,使用自定义的决断器,在用户访问受保护的资源时,决断器判断用户拥有的角色中是否对改资源具有访问权限,如果没有,则拒绝访问

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
package com.example.demo.utils.security;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;
 
import java.util.Collection;
import java.util.Iterator;
 
/**
 * 权限管理决断器
 *
 * @Author: 我爱大金子
 * @Description: 权限管理决断器
 * @Date: Create in 17:15 2017/7/5
 */
@Service
public class CustomAccessDecisionManager implements AccessDecisionManager {
    Logger log = LoggerFactory.getLogger(CustomAccessDecisionManager.class);
     
    // decide 方法是判定是否拥有权限的决策方法,
    //authentication 是释CustomUserService中循环添加到 GrantedAuthority 对象中的权限信息集合.
    //object 包含客户端发起的请求的requset信息,可转换为 HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
    //configAttributes 为MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法返回的结果,此方法是为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。
    @Override
    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
 
        if(null== configAttributes || configAttributes.size() <=0) {
            return;
        }
        ConfigAttribute c;
        String needRole;
        for(Iterator<ConfigAttribute> iter = configAttributes.iterator(); iter.hasNext(); ) {
            c = iter.next();
            needRole = c.getAttribute();
            for(GrantedAuthority ga : authentication.getAuthorities()) {//authentication 为在注释1 中循环添加到 GrantedAuthority 对象中的权限信息集合
                if(needRole.trim().equals(ga.getAuthority())) {
                    return;
                }
            }
            log.info("【权限管理决断器】需要role:" + needRole);
        }
        throw new AccessDeniedException("Access is denied");
    }
 
    @Override
    public boolean supports(ConfigAttribute attribute) {
        return true;
    }
 
    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }
}



5.3、权限配置资源管理器

权限配置资源管理器实现了FilterInvocationSecurityMetadataSource,在启动时就去加载了所有的权限列表,权限配置资源管理器为决断器实时提供支持,判断用户访问的资源是否在受保护的范围之内。

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
package com.example.demo.utils.security;
 
import com.example.demo.dao.SysPermissionDao;
import com.example.demo.pojo.SysPermission;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Service;
 
import javax.servlet.http.HttpServletRequest;
import java.util.*;
 
/**
 * 权限配置资源管理器
 *
 * @Author: 我爱大金子
 * @Description: 权限配置资源管理器
 * @Date: Create in 17:17 2017/7/5
 */
@Service
public class CustomFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
    @Autowired
    private SysPermissionDao sysPermissionDao;
 
    private HashMap<String, Collection<ConfigAttribute>> map =null;
 
    /**
     * 加载权限表中所有权限
     */
    public void loadResourceDefine(){
        map = new HashMap<>();
        Collection<ConfigAttribute> array;
        ConfigAttribute cfg;
        List<SysPermission> permissions = sysPermissionDao.findAll();
        for(SysPermission permission : permissions) {
            array = new ArrayList<>();
            cfg = new SecurityConfig(permission.getName());
            //此处只添加了用户的名字,其实还可以添加更多权限的信息,例如请求方法到ConfigAttribute的集合中去。此处添加的信息将会作为MyAccessDecisionManager类的decide的第三个参数。
            array.add(cfg);
            //用权限的getUrl() 作为map的key,用ConfigAttribute的集合作为 value,
            map.put(permission.getUrl(), array);
        }
    }
 
    //此方法是为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。
    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        if(map ==null) loadResourceDefine();
        //object 中包含用户请求的request 信息
        HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
        AntPathRequestMatcher matcher;
        String resUrl;
        for(Iterator<String> iter = map.keySet().iterator(); iter.hasNext(); ) {
            resUrl = iter.next();
            matcher = new AntPathRequestMatcher(resUrl);
            if(matcher.matches(request)) {
                return map.get(resUrl);
            }
        }
        return null;
    }
 
    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }
 
    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }
}


六、根据权限设置连接

对于权限管理,我们可能希望,在一个用户访问的界面中,不是等到用户点击了超链接之后,才来判断用户有没有这个权限,而是按照用户拥有的权限来显示超链接。这样的设计对于用户体验来说,会更友好。

6.1、方法1:使用sec标签(thymeleaf)

在html标签中引入的Spring Security的标签:

1
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"

sec:authentication="name":取当前登录用户的用户名

1
<title sec:authentication="name"></title>

sec:authorize="hasRole('ROLE_ADMIN'):表示当前用户是否拥有角色ROLE_ADMIN

1
<li sec:authorize="hasRole('ROLE_ADMIN')"><a th:href="@{/admin}"> admin </a></li>

sec:authorize="hasAuthority('admin')":表示当前用户是否拥有权限admin

1
<li sec:authorize="hasAuthority('admin')"><a th:href="@{/admin}"> admin </a></li>

6.2、方法二:代码

在控制层用代码获取是否有权限,然后将标识放入内容中,页面获取处理


七、其它代码

wKioL1le-47T_WyLAABw4KXMIDA929.png

7.1、controller

IndexController.java

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 com.example.demo.controller;
 
import com.example.demo.domain.Msg;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
 
/**
 * 描述
 *
 * @Author: 我爱大金子
 * @Description: 描述
 * @Date: Create in 15:25 2017/7/5
 */
@Controller
public class IndexController {
    /**系统首页*/
    @RequestMapping("/")
    public String index(Model model){
        Msg msg =  new Msg("测试标题","测试内容","欢迎来到HOME页面,您拥有index权限");
        model.addAttribute("msg", msg);
        return "home";
    }
 
    /**系统首页2*/
    @RequestMapping("/index2")
    public String index2(Model model){
        Msg msg =  new Msg("测试标题2","测试内容2","欢迎来到HOME页面,您拥有home权限");
        model.addAttribute("msg", msg);
        return "home";
    }
 
    @RequestMapping("/admin")
    @ResponseBody
    public String hello(){
        return "hello admin";
    }
 
    @RequestMapping("/yk")
    @ResponseBody
    public String hello2(){
        return "hello yk";
    }
}

7.2、dao

SysUserDao.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.example.demo.dao;
 
import com.example.demo.pojo.SysUser;
import org.apache.ibatis.annotations.Mapper;
 
/**
 * 系统用户dao
 *
 * @Author: 我爱大金子
 * @Description: 系统用户dao
 * @Date: Create in 16:15 2017/7/5
 */
@Mapper
public interface SysUserDao {
    public SysUser findByUserName(String username);
}

SysPermissionDao.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.example.demo.dao;
 
import com.example.demo.pojo.SysPermission;
import org.apache.ibatis.annotations.Mapper;
 
import java.util.List;
 
/**
 * 系统权限dao
 *
 * @Author: 我爱大金子
 * @Description: 描述
 * @Date: Create in 17:05 2017/7/5
 */
@Mapper
public interface SysPermissionDao {
    List<SysPermission> findAll();
    List<SysPermission> findByAdminUserId(Long userId);
}

7.3、domain

Msg.java

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
package com.example.demo.domain;
 
/**
 * 描述
 *
 * @Author: 我爱大金子
 * @Description: 描述
 * @Date: Create in 16:14 2017/7/5
 */
public class Msg {
    private String title;
    private String content;
    private String etraInfo;
    public Msg(String title, String content, String etraInfo) {
        super();
        this.title = title;
        this.content = content;
        this.etraInfo = etraInfo;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public String getEtraInfo() {
        return etraInfo;
    }
    public void setEtraInfo(String etraInfo) {
        this.etraInfo = etraInfo;
    }
}

7.4、pojo

SysUser.java

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
package com.example.demo.pojo;
 
import java.util.List;
 
/**
 * 系统用户
 *
 * @Author: 我爱大金子
 * @Description: 系统用户
 * @Date: Create in 16:12 2017/7/5
 */
public class SysUser {
    private Long id;
    private String username;
    private String password;
 
    private List<SysRole> roles;
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public String getUsername() {
        return username;
    }
 
    public void setUsername(String username) {
        this.username = username;
    }
 
    public String getPassword() {
        return password;
    }
 
    public void setPassword(String password) {
        this.password = password;
    }
 
    public List<SysRole> getRoles() {
        return roles;
    }
 
    public void setRoles(List<SysRole> roles) {
        this.roles = roles;
    }
}

SysRole.java

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 com.example.demo.pojo;
 
/**
 * 系统角色
 *
 * @Author: 我爱大金子
 * @Description: 系统角色
 * @Date: Create in 16:13 2017/7/5
 */
public class SysRole {
    private Long id;
    private String name;
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
}

SysPermission.java

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
package com.example.demo.pojo;
 
/**
 * 系统权限
 *
 * @Author: 我爱大金子
 * @Description: 系统权限
 * @Date: Create in 17:04 2017/7/5
 */
public class SysPermission {
    private Long id;
    //权限名称
    private String name;
 
    //权限描述
    private String descritpion;
 
    //授权链接
    private String url;
 
    //父节点id
    private int pid;
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getDescritpion() {
        return descritpion;
    }
 
    public void setDescritpion(String descritpion) {
        this.descritpion = descritpion;
    }
 
    public String getUrl() {
        return url;
    }
 
    public void setUrl(String url) {
        this.url = url;
    }
 
    public int getPid() {
        return pid;
    }
 
    public void setPid(int pid) {
        this.pid = pid;
    }
}

7.5、mapperXX.xml

SysUserDao.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.demo.dao.SysUserDao" >
    <resultMap id="userMap" type="SysUser">
        <id property="id" column="ID"/>
        <result property="username" column="username"/>
        <result property="password" column="PASSWORD"/>
        <collection property="roles" ofType="SysRole">
            <result column="name" property="name"/>
        </collection>
    </resultMap>
    <select id="findByUserName" parameterType="String" resultMap="userMap">
        select u.*
        ,r.name
        from sys_user u
        LEFT JOIN sys_user_role sru on u.id= sru.sys_user_id
        LEFT JOIN sys_role r on sru.sys_role_id=r.id
        where username= #{username}
    </select>
</mapper>

SysPermissionDao.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.demo.dao.SysPermissionDao" >
    <select id="findAll"  resultType="SysPermission">