碼雲地址:https://gitee.com/huatao1994/springSecuritycss
/* Navicat MySQL Data Transfer Source Server : localhost Source Server Version : 50529 Source Host : localhost:3306 Source Database : security Target Server Type : MYSQL Target Server Version : 50529 File Encoding : 65001 Date: 2019-12-21 14:04:04 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `authority_menu` -- ---------------------------- DROP TABLE IF EXISTS `authority_menu`; CREATE TABLE `authority_menu` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id', `url` varchar(255) DEFAULT NULL COMMENT '請求路徑', `menu_name` varchar(255) DEFAULT NULL COMMENT '菜單名稱', `parent_id` int(11) DEFAULT NULL COMMENT '父菜單id', `update_time` varchar(255) DEFAULT NULL COMMENT '更新時間', `remark` varchar(255) DEFAULT NULL COMMENT '備註', `url_pre` varchar(255) DEFAULT NULL COMMENT '路由(前端本身匹配用)', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of authority_menu -- ---------------------------- -- ---------------------------- -- Table structure for `authority_role` -- ---------------------------- DROP TABLE IF EXISTS `authority_role`; CREATE TABLE `authority_role` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id', `role_name` varchar(255) DEFAULT NULL COMMENT '角色名稱(必須以ROLE_起始命名)', `role_name_CN` varchar(255) DEFAULT NULL COMMENT '角色名稱中文', `update_time` varchar(255) DEFAULT NULL COMMENT '更新時間', `remark` varchar(255) DEFAULT NULL COMMENT '備註', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of authority_role -- ---------------------------- -- ---------------------------- -- Table structure for `authority_role_menu` -- ---------------------------- DROP TABLE IF EXISTS `authority_role_menu`; CREATE TABLE `authority_role_menu` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id', `role_id` int(11) DEFAULT NULL, `menu_id` int(11) DEFAULT NULL, `update_time` varchar(255) DEFAULT NULL COMMENT '更新時間', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of authority_role_menu -- ---------------------------- -- ---------------------------- -- Table structure for `authority_user` -- ---------------------------- DROP TABLE IF EXISTS `authority_user`; CREATE TABLE `authority_user` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id', `username` varchar(255) DEFAULT NULL COMMENT '用戶名', `password` varchar(255) DEFAULT NULL COMMENT '密碼', `email` varchar(255) DEFAULT NULL COMMENT '郵箱', `phone` varchar(255) DEFAULT NULL COMMENT '手機號', `valid_time` varchar(255) DEFAULT NULL COMMENT '有效截止時間', `update_time` varchar(255) DEFAULT NULL COMMENT '更新時間', `remark` mediumtext COMMENT '備註', `nickname` varchar(255) DEFAULT NULL COMMENT '暱稱', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of authority_user -- ---------------------------- -- ---------------------------- -- Table structure for `authority_user_role` -- ---------------------------- DROP TABLE IF EXISTS `authority_user_role`; CREATE TABLE `authority_user_role` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id', `user_id` int(11) DEFAULT NULL, `role_id` int(11) DEFAULT NULL, `update_time` varchar(255) DEFAULT NULL COMMENT '更新時間', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=74 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of authority_user_role -- ---------------------------- -- ---------------------------- -- Table structure for `persistent_logins` -- ---------------------------- DROP TABLE IF EXISTS `persistent_logins`; CREATE TABLE `persistent_logins` ( `username` varchar(64) NOT NULL, `series` varchar(64) NOT NULL, `token` varchar(64) NOT NULL, `last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`series`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of persistent_logins -- ----------------------------
package cn.**.controller; import cn.**.dao.UserDao; import cn.**.service.UserService1; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @ProjectName: springbootSecurity * @Package: cn.**.security.controller * @Author: huat * @Date: 2019/12/12 14:56 * @Version: 1.0 */ @RestController public class UserController { @Autowired UserService1 userService1; //@Secured("ROLE_ADMIN")//security權限註解 //@RolesAllowed("ROLE_ADMIN") //jsr250註解 //@PreAuthorize("hasRole('ROLE_ADMIN')")//spring的註解 @RequestMapping("/login") public String login(String username,String password){ //獲取登錄的用戶名 String username1= SecurityContextHolder.getContext().getAuthentication().getName(); System.out.println(username); return "index"; } @RequestMapping("test") public String test(){ return "hello test"; } }
package cn.**.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * @ProjectName: springbootSecurity * @Package: cn.**.security.controller * @Author: huat * @Date: 2019/12/16 15:16 * @Version: 1.0 */ @Controller public class IntoController { @RequestMapping("intoTest") public String intoTest(){ return "/test"; } @RequestMapping("intoIndex") public String intoIndex(){ return "index"; } @RequestMapping("intoFail") public String intoFail(){ return "fail"; } @RequestMapping("intoLogin") public String intoLogin(){ return "login"; } @RequestMapping("dologin") public String dologin(){ return "index"; } }
package cn.**.entity; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import java.util.Collection; import java.util.List; /** * @ProjectName: springbootSecurity * @Package: cn.**.security.entity * @Author: huat * @Date: 2019/12/12 15:12 * @Version: 1.0 * 建立實體類第一種方式 */ public class AuthorityUser1 { private int id; private String username; private String password; private List<AuthorityRole> authorityRoles; public int getId() { return id; } public void setId(int 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<AuthorityRole> getAuthorityRoles() { return authorityRoles; } public void setAuthorityRoles(List<AuthorityRole> authorityRoles) { this.authorityRoles = authorityRoles; } }
package cn.**.entity; import com.fasterxml.jackson.annotation.JsonIgnore; import org.springframework.security.core.GrantedAuthority; /** * @ProjectName: springbootSecurity * @Package: cn.**.security.entity * @Author: huat * @Date: 2019/12/12 16:14 * @Version: 1.0 */ public class AuthorityRole1 { private int id; private String roleName; private String roleNameCN; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getRoleName() { return roleName; } public void setRoleName(String roleName) { this.roleName = roleName; } public String getRoleNameCN() { return roleNameCN; } public void setRoleNameCN(String roleNameCN) { this.roleNameCN = roleNameCN; } }
package cn.**.entity; /** * @ProjectName: springbootSecurity * @Package: cn.**.security.entity * @Author: huat * @Date: 2019/12/16 18:45 * @Version: 1.0 */ public class AuthorityMenu1 { private int id; private String url; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package cn.**.service; import org.springframework.security.core.userdetails.UserDetailsService; /** * @ProjectName: springbootSecurity * @Package: cn.**.security.service * @Author: huat * @Date: 2019/12/12 17:35 * @Version: 1.0 */ //UserDetailsService 是security中的類 public interface UserService extends UserDetailsService { }
package cn.**.service; import cn.**.dao1.*; import cn.**.entity.AuthorityRole1; import cn.**.entity.AuthorityUser1; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; /** * @ProjectName: springbootSecurity * @Package: cn.**.utile * @Author: huat * @Date: 2019/12/12 14:48 * @Version: 1.0 */ @Service//將這個類注入到spring容器中 public class UserService1Impl implements UserService1 { @Autowired private UserDao1 userDao1;//獲取用戶 @Autowired private RoleDao1 roleDao1;//獲取角色 @Autowired private MenuDao1 menuDao1;//獲取路徑集合 @Autowired private PasswordEncoder myPasswordEncoder; //使用springSecurity加密規則 //@Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { try{ //根據用戶名查詢用戶 AuthorityUser1 authorityUser =userDao1.getUser(username); if(null== authorityUser){ //返回null表明驗證失敗 return null; } //放角色的集合 List<SimpleGrantedAuthority> authorities=new ArrayList<SimpleGrantedAuthority>(); List<AuthorityRole1> roleList=roleDao1.getAllRole(authorityUser.getId()); //list中放入角色權限 if(null!=roleList&&roleList.size()>0){ for (AuthorityRole1 role:roleList) { authorities.add(new SimpleGrantedAuthority(role.getRoleName())); } } //{noop}表明使用明文驗證 // UserDetails userDetails=new User(authorityUser.getUsername(),"{noop}"+authorityUser.getPassword(),authorities); //使用密文驗證 UserDetails userDetails=new User(authorityUser.getUsername(),authorityUser.getPassword(),authorities); return userDetails; }catch (Exception e){ e.printStackTrace(); //返回null表明驗證失敗 return null; } } public static void main(String[] args) { BCryptPasswordEncoder passwordEncoder=new BCryptPasswordEncoder(); //passwordEncoder.encode("123456")加密方法 //執行屢次加密後的結果均不同 //執行第一次:$2a$10$RSlzzO4xAubBLZMB8jPL8eMFX17gM61JfrgINpzOiaEsBdtKBuSDe //執行第二次:$2a$10$2uQWdP9qAXGK4H0um0gtG.o1QzbGhBlbxx8YjX526jIrVBNKyziFe //執行第三次:$2a$10$8CWttAISfamloSErsqEAPemALyZvj8VWaUCBJKcm2GE1dhFR.7oYG //security加密方式是動態加鹽 System.out.println(passwordEncoder.encode("123456")); //比較明文和密文是否一致 System.out.println(passwordEncoder.matches("123456","$2a$10$lstWyJ6NlbdZ2uVr8ncsHOUKsG0VAT4FzDdy0gqy6gbaOqpp6ouDq")); } }
package cn.**.dao; import cn.**.entity.AuthorityUser; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; /** * @ProjectName: springbootSecurity * @Package: cn.**.security.dao * @Author: huat * @Date: 2019/12/12 15:04 * @Version: 1.0 */ @Mapper public interface UserDao { /** * 根據用戶名查詢角色 * @param username 用戶名 * @return */ AuthorityUser getUser(@Param("username") String username); /** * 添加用戶 * @param username 用戶名 * @param password 密碼 * @return */ int saveUser(@Param("username") String username, @Param("password") String password); }
<?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="cn.**.dao1.UserDao1"> <select id="getUser" resultType="authorityUser1"> select * from authority_user where username=#{username} </select> <insert id="saveUser"> insert into authority_user(username,password) values(#{username},#{password}) </insert> </mapper>
package cn.**.dao1; import cn.**.entity.AuthorityRole; import cn.**.entity.AuthorityRole1; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; /** * @ProjectName: springbootSecurity * @Package: cn.**.security.dao * @Author: huat * @Date: 2019/12/12 16:15 * @Version: 1.0 */ @Mapper public interface RoleDao1 { //根據用戶id獲取對應的權限 List<AuthorityRole1> getAllRole(@Param("id") int id); }
<?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="cn.**.dao1.RoleDao1"> <select id="getAllRole" resultType="authorityRole1"> SELECT r.id,r.role_name roleName FROM authority_user_role a LEFT JOIN authority_user u ON u.id=a.user_id LEFT JOIN authority_role r ON r.id=a.role_id WHERE u.id=#{id} </select> </mapper>
package cn.**.dao1; import cn.**.entity.AuthorityMenu; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; /** * @ProjectName: springbootSecurity * @Package: cn.**.security.dao * @Author: huat * @Date: 2019/12/17 11:31 * @Version: 1.0 */ @Mapper public interface MenuDao1 { /** * 根據角色id查詢全部路徑 * @param roleId 角色id * @return */ List<AuthorityMenu> getMenuById(@Param("roleId") int roleId); }
<?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="cn.**.dao1.MenuDao1"> <select id="getMenuById" resultType="authorityMenu1"> select m.url,m.menu_name name,m.id from authority_role r LEFT JOIN authority_role_menu rm ON rm.role_id=r.id LEFT JOIN authority_menu m ON rm.menu_id=m.id where r.id=#{roleId} </select> </mapper>
package cn.**.util; import cn.**.service.UserService; import cn.**.service.UserService1; 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.method.configuration.EnableGlobalMethodSecurity; 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.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; /** * @ProjectName: springbootSecurity * @Package: cn.**.security.util * @Author: huat * @Date: 2019/12/14 8:06 * @Version: 1.0 */ /** * 開啓security註解支持 * @EnableWebSecurity * (securedEnabled=true) 開啓@Secured 註解過濾權限 * (jsr250Enabled=true)開啓@RolesAllowed 註解過濾權限 * (prePostEnabled=true) 使用表達式時間方法級別的安全性 4個註解可用 * @EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled=true,jsr250Enabled=true) */ @Configuration @EnableWebSecurity //@EnableGlobalMethodSecurity(prePostEnabled = true) @EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled=true,jsr250Enabled=true) public class SpringSercurityConfig extends WebSecurityConfigurerAdapter { /* @Autowired UserService1 userService;*/ @Autowired UserService userService; /** * 將security中加密方式注入到spring容器中 * @return */ @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } /** * 將帳號密碼設置在數據庫當中 * @param auth * @throws Exception */ @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth //將UserDetailsService放到容器中 .userDetailsService(userService) //加密方式放入 .passwordEncoder(passwordEncoder()); } @Override public void configure(HttpSecurity http) throws Exception { //釋放靜態資源,指定資源攔截規則, // 指定自定義認證頁面,指定退出認證配置,csrf(跨域僞造請求)配置 http.authorizeRequests() .antMatchers("intoLogin","login.jsp","/css/**","fail.jsp","/intoIndex","/index.jsp").permitAll()//釋放這些資源,容許匿名訪問 .antMatchers("/**").hasAnyRole("ADMIN","USER") .anyRequest().authenticated()//其餘資源須要認證 .and() .formLogin() .loginPage("/intoLogin")//登錄頁請求的接口 .loginProcessingUrl("/dologin")//登錄地址,由springSecurity提供 .successForwardUrl("/intoTest")//登錄成功 .failureForwardUrl("/intoFail")//登陸失敗 .permitAll()//指定全部資源釋放 .and() .logout()//登出 .logoutUrl("/logout")//指定登出路徑 .logoutSuccessUrl("/login.jsp")//登出成功後跳轉的url .invalidateHttpSession(true)//是否清空session .permitAll() .and() .csrf() .disable();//關閉csrf(跨域僞造請求) } /* *//** * ajax 登錄 * @param http * @throws Exception *//* @Override public void configure(HttpSecurity http) throws Exception { //釋放靜態資源,指定資源攔截規則, // 指定自定義認證頁面,指定退出認證配置,csrf(跨域僞造請求)配置 http.authorizeRequests() .antMatchers("intoLogin","login.jsp","/css/**","fail.jsp","/intoIndex","/index.jsp").permitAll()//釋放這些資源,容許匿名訪問 .antMatchers("/**").hasAnyRole("ADMIN","USER") .antMatchers("/test").hasRole("USER") .anyRequest().authenticated()//其餘資源須要認證 .and() .formLogin() .loginPage("/intoLogin")//登錄頁請求的接口 .successHandler(authenticationSuccessHandler)//登錄成功後返回的數據 .failureHandler(authenticationFailureHandler) .loginProcessingUrl("/login")//登錄地址,由springSecurity提供 .usernameParameter("name") .passwordParameter("pwd") .permitAll()//指定全部資源釋放 .and() .logout()//登出 .logoutUrl("/logout")//指定登出路徑 .logoutSuccessUrl("/login.jsp")//登出成功後跳轉的url .invalidateHttpSession(true)//是否清空session .permitAll() .and() .cors() .and() .csrf() .disable() ;//關閉csrf(跨域僞造請求) }*/ }