4. Spring Boot Security角色管理持久化实现

来源:互联网 发布:顺丰淘宝合作价格表 编辑:程序博客网 时间:2024/06/06 00:04

1.概述,

在第三章里大家学会了怎么初步使用Spring Boot 结合Spring Security来实现权限控制和角色管理,  但是我们发现无论是使用那种方式角色管理和权限控制全部是在 xml中或则 配置类中写的, 没有实现持久化, 本次就为大家讲解怎么实现.本小结为大家讲 用户角色管理的实现,  至于权限控制来下一个小结会讲.

2.表和数据

这里写图片描述

PDM文件路径: https://github.com/masterjyq/Spring-Boot.git

数据

insert into sys_user_demo (user_id,user_name, user_passwd) values (1,'admin', 'admin');insert into sys_user_demo (user_id,user_name, user_passwd) values (2,'abel', 'abel');insert into sys_role_demo(role_id,role_name) values(1,'ROLE_ADMIN');insert into sys_role_demo(role_id,role_name) values(2,'ROLE_USER');insert into user_role_demo(user_role_id,role_id,user_id) values(1,1,1);insert into user_role_demo(user_role_id,role_id,user_id) values(2,2,2);

3.创建PO

这里写图片描述

SysUserDemo.java

package com.hand.sys.model;/** * Created by JQY on 2017/12/3. */public class SysUserDemo{    private  Integer userId;    private  String  userName;    private  String  userPasswd;    public Integer getUserId() {        return userId;    }    public void setUserId(Integer userId) {        this.userId = userId;    }    public String getUserName() {        return userName;    }    public void setUserName(String userName) {        this.userName = userName;    }    public String getUserPasswd() {        return userPasswd;    }    public void setUserPasswd(String userPasswd) {        this.userPasswd = userPasswd;    }}

SysRoleDemo.java

package com.hand.sys.model;/** * Created by JQY on 2017/12/3. */public class SysRoleDemo{    private Integer roleId;    private  String roleName;    public Integer getRoleId() {        return roleId;    }    public void setRoleId(Integer roleId) {        this.roleId = roleId;    }    public String getRoleName() {        return roleName;    }    public void setRoleName(String roleName) {        this.roleName = roleName;    }}

UserRoleDemo.java

package com.hand.sys.model;/** * Created by JQY on 2017/12/3. */public class UserRoleDemo{    private  Integer userRoleId;    private  Integer userId;    private  Integer roleId;    public Integer getUserRoleId() {        return userRoleId;    }    public void setUserRoleId(Integer userRoleId) {        this.userRoleId = userRoleId;    }    public Integer getUserId() {        return userId;    }    public void setUserId(Integer userId) {        this.userId = userId;    }    public Integer getRoleId() {        return roleId;    }    public void setRoleId(Integer roleId) {        this.roleId = roleId;    }}

4. 处理登录要用的类

4.1协助处理登录的DAO 和Mapper

UserDao.java

package com.hand.sys.dao;import com.hand.sys.model.SysUserDemo;import org.apache.ibatis.annotations.Mapper;import org.springframework.stereotype.Repository;import java.util.List;import java.util.Map;/** * Created by JQY on 2017/12/3. */@Repository@Mapperpublic interface UserDao{    public List<Map<String,String>> findRole(String name);}

UserMapper.xml

<?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.hand.sys.dao.UserDao" >    <!--khm 是配置文件的别名,本体是KeyHashMap-->    <select id="findRole"  resultType="khm" parameterType="String">        select *        from SYS_USER_DEMO u, SYS_ROLE_DEMO r,USER_ROLE_DEMO hr        WHERE  u.user_id (+) = hr.USER_ID        and    r.ROLE_ID (+)= hr.ROLE_ID        and    u.USER_NAME = #{userName}    </select></mapper>

4.2协助处理登录service

CustomUserService.java

package com.hand.security;import com.hand.sys.dao.UserDao;import org.springframework.beans.factory.annotation.Autowired;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 org.springframework.stereotype.Service;import java.util.ArrayList;import java.util.List;import java.util.Map;/** * Created by JQY on 2017/12/3. */@Servicepublic class CustomUserService implements UserDetailsService { //自定义UserDetailsService 接口    @Autowired    private  UserDao userDao;    //重写loadUserByUsername 方法获得 userdetails 类型用户    @Override    public UserDetails loadUserByUsername(String name) {        List<Map<String,String>> user = userDao.findRole(name);        if(user.get(0) == null){            throw new UsernameNotFoundException("用户名不存在");        }        List<SimpleGrantedAuthority> authorities = new ArrayList<>();        //来遍历用户角色添加到缓存        for(Map<String,String> role : user)        {            authorities.add(new SimpleGrantedAuthority(role.get("roleName")));            System.out.println(role.get("roleName"));        }        return new org.springframework.security.core.userdetails.User(user.get(0).get("userName"),                user.get(0).get("userPasswd"), authorities); //返回用户名密码, 来和前端传来的对比    }}

5.写配置注入刚刚的service

此处还是给大家讲了两种配置方式,配置类和 xml  建议 xml, 两种的切换使用见第三章

5.1 配置类的方式, 修改第三章的配置类

WebSecurityConfig.java

package com.hand.security;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.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.core.userdetails.UserDetailsService;/** * Created by JQY on 2017/11/21. * 去除注解暂时废弃 * *///@Configuration//@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter{    @Override    protected void configure(HttpSecurity http) throws Exception {        http                .authorizeRequests()                .antMatchers("/","/styles/**","/scripts/**").permitAll() //指定那些URL不要被保护                .antMatchers("/res/list").hasRole("USER") //ROLE_ 去除  一定要在 /** 前面才有作用                .antMatchers("/**").hasRole("ADMIN")  //此处要把 ROLE_ 去除                .anyRequest().authenticated()                .and()                .formLogin()                .loginPage("/login") //登录的时候你要跳转到哪里                .failureUrl("/login?error") //失败页面                .permitAll() //登录任意访问                .and()                .rememberMe() //rememberMe                .and() //注销行为任意访问                .logout()                .permitAll()                .and()                .csrf() //关闭csrf 不然不支持post                .disable();    }    @Bean    UserDetailsService customUserService(){ //注册UserDetailsService 的bean        return new CustomUserService(); //注入刚刚写的service    }    @Autowired    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {        auth.userDetailsService(customUserService()); //user Details Service验证        /*auth                .inMemoryAuthentication()                //用户名密码和角色                .withUser("jyq").password("123456").roles("USER");*/    }}

5.2 xml的配置

applicationContext-security.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:sec="http://www.springframework.org/schema/security"       xsi:schemaLocation="http://www.springframework.org/schema/beans                           http://www.springframework.org/schema/beans/spring-beans.xsd                           http://www.springframework.org/schema/security                           http://www.springframework.org/schema/security/spring-security-4.2.xsd">    <!--拦截器过滤配置-->    <sec:http auto-config="true">        <!--开启remember-me-->        <sec:remember-me />        <!--关闭csrf-->        <sec:csrf disabled="true"/>        <!--静态资源的URL-->        <sec:intercept-url pattern="/scripts/**" access="hasRole('ROLE_ANONYMOUS')"/>        <sec:intercept-url pattern="/styles/**" access="hasRole('ROLE_ANONYMOUS')"/>        <!--登录界面不要拦截-->        <sec:intercept-url pattern="/login" access="hasRole('ROLE_ANONYMOUS')"/>        <!--具体页面拦截规则-->        <sec:intercept-url pattern="/res/list" access="hasRole('ROLE_USER')"/>        <sec:intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')"/>        <!--自定义页面-->        <sec:form-login login-page="/login"   authentication-failure-url="/login?error"                        default-target-url="/login"/>    </sec:http>    <!--注入BEAN-->    <bean id="customUserService" class="com.hand.security.CustomUserService">    </bean>    <!--配置用户-->    <sec:authentication-manager>        <sec:authentication-provider user-service-ref="customUserService">            <!--<sec:user-service >                <sec:user name="jyq" password="123456" authorities="ROLE_ADMIN"/>            </sec:user-service>-->        </sec:authentication-provider>    </sec:authentication-manager></beans>

6. 我们再写一个给 user 角色的页面 我们配置的是res/list 那就写个测试页面

6.1写页面

这里写图片描述

role.html

<!DOCTYPE HTML><html xmlns:th="http://www.thymeleaf.org"><head>    <title>hello</title>    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body><h1>欢迎角色USER</h1><form th:action="@{/logout}" method="post">    <input type="submit" value="注销"/></form></body></html>

6.2修改controller 加上映射

ResourceTableController.java

package com.hand.demo.controller;import com.hand.demo.model.ResouceTable;import com.hand.demo.service.ResourceTableService;import com.jyq.utils.BeanUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import java.util.Map;/** * Created by JYQ on 2017/11/13. */@Controller@RequestMapping("res")public class ResourceTableController {    @Autowired    private ResourceTableService resourceTableService;    @RequestMapping("query")    public String query(Model model, ResouceTable resouceTable)    {       model.addAttribute("res",resourceTableService.query(resouceTable));       return "resource_table";    }    @RequestMapping("list")    public String list(Model model, ResouceTable resouceTable)    {        model.addAttribute("res",resourceTableService.query(resouceTable));        return "demo/role";    }}

7测试

先用 admin访问 http://localhost:8888/demo/res/query 和http://localhost:8888/demo/res/list
会发现都可以访问

但是用 user用户只可以访问http://localhost:8888/demo/res/list
访问http://localhost:8888/demo/res/query会显示没有权限

这里写图片描述

原创粉丝点击