springBoot使用springSecurity入門詳細配置,自定義登錄,RBAC權限模型,數據庫(JPA+mysql)驗證登錄,驗證碼,json格式交互等(下篇)

上篇:springBoot使用springSecurity入門詳細配置,自定義登錄,RBAC權限模型,數據庫(mybatis+mysql)驗證登錄,驗證碼,json格式交互等(上篇)

寫了:

  • springBoot項目使用security
  • 配置介紹
  • 自定義登錄頁面
  • 自定義登陸成功失敗處理器
  • 添加驗證碼驗證過濾

下篇開始

1.自定義用戶認證的數據來源,內存以及數據庫

前面我們一直使用security默認提供的user賬號以及啓動生產來登錄,現在我們來配置自己用戶信息;
security用戶數據的配置在前面也已經介紹了,即配置類重寫configure(AuthenticationManagerBuilder auth)方法
下面將介紹兩種數據來源

  1. 直接配置在內存中
    這種比較簡單,直接在配置文件yml配置即可
    spring:
      security:
        user:
          name: admin
          password: admin
    這樣我們就配置一個用戶在我們的內存中,重新啓動項目你會發現控制檯不再打印一個加密的密碼,也就是說只有我們沒有配置自己用戶數據來源時security纔會給我們提供默認的用戶user,一旦我們配置自己的用戶數據將不再提供默認用戶user;

    成功!
     
  2. 配置數據庫來源
    更多的時候我們的用戶數據是放在數據庫中,我們就需要配置數據庫來源了,配置類重寫configure(AuthenticationManagerBuilder auth)指定我們自定義數據來源;
    數據庫:我使用的是mysql
    持久層框架:使用springJpa,之前一直使用的是mybatis,最近實習發現公司使用JPA比較多,所以這次順便學學使用JPA

    1.使用Jpa,並使用其自動創建表功能,準備好數據庫數據
    添加依賴
    <!--druid數據庫連接池-->    
    <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.1.10</version>
            </dependency>
    <!--mysql-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.35</version>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
    在自己的mysql數據庫建立一個security數據庫
    配置Jpa以及數據庫連接池
    spring:
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver: com.mysql.jdbc.Driver
        druid:
          username: 
          password: 
          url: jdbc:mysql://localhost:3306/security?useUnicode=true&characterEncoding=utf-8&useSSL=false
          initial-size: 1
          max-active: 5
          min-idle: 1
      jpa:
        show-sql: true  #顯示sql語句
        hibernate:
          ddl-auto: update  #自動建表
        open-in-view: true
        properties:
          hibernate:
            enable_lazy_load_no_trans: true   #將Jpa的session生命週期擴大
    用戶Entity類,實現UserDetails接口
    @Data
    @Entity
    @Table(name = "user",
            uniqueConstraints = {@UniqueConstraint(columnNames = {"username"}), @UniqueConstraint(columnNames = {"email"})})
    public class User implements UserDetails {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Integer u_id;
        @Column(nullable = false)
        @Length(min = 3, max = 20)
        private String username;
        @Column(nullable = false,length = 100)
        @JsonIgnore
        private String password;
        @Column(nullable = false)
        @Length(min = 3, max = 20)
        private String realName;
        @Column(nullable = false, length = 50)
        private String email;
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
        private Date registerDate;
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
        private Date lastLogin;
        private boolean isEnabled=true;
        private boolean isAccountNonExpired=true;
        private boolean isAccountNonLocked=true;
        private boolean isCredentialsNonExpired=true;
        @ManyToMany
        @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "u_id"),
                inverseJoinColumns = @JoinColumn(name = "r_id"))
        private List<Role> roleList;
        //    存儲用戶的權限
        @Transient
        private List<GrantedAuthority> authorities;
    
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (!(obj instanceof User)) return false;
            User user = (User) obj;
            boolean boo = this.username.equals(user.getUsername());
            return boo;
        }
    
        @Override
        public int hashCode() {
            return username != null ? username.hashCode() : 0;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "u_id=" + u_id +
                    ", username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    ", realName='" + realName + '\'' +
                    ", email='" + email + '\'' +
                    ", registerDate=" + registerDate +
                    ", lastLogin=" + lastLogin +
                    ", isEnabled=" + isEnabled +
                    ", isAccountNonExpired=" + isAccountNonExpired +
                    ", isAccountNonLocked=" + isAccountNonLocked +
                    ", isCredentialsNonExpired=" + isCredentialsNonExpired +
                    ", roleList=" + roleList +
                    ", authorities=" + authorities +
                    '}';
        }
    }
    
    當我們啓動項目使Jpa會自動會幫我們創建表,使用mybatis的,自己用下面sql創建表以及添加一條數據
    SET NAMES utf8mb4;
    SET FOREIGN_KEY_CHECKS = 0;
    
    -- ----------------------------
    -- Table structure for user
    -- ----------------------------
    DROP TABLE IF EXISTS `user`;
    CREATE TABLE `user`  (
      `u_id` int(11) NOT NULL AUTO_INCREMENT,
      `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
      `is_account_non_expired` bit(1) NOT NULL,
      `is_account_non_locked` bit(1) NOT NULL,
      `is_credentials_non_expired` bit(1) NOT NULL,
      `is_enabled` bit(1) NOT NULL,
      `last_login` datetime NULL DEFAULT NULL,
      `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
      `real_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
      `register_date` datetime NULL DEFAULT NULL,
      `username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
      PRIMARY KEY (`u_id`) USING BTREE,
      UNIQUE INDEX `UKsb8bbouer5wak8vyiiy4pf2bx`(`username`) USING BTREE,
      UNIQUE INDEX `UKob8kqyqqgmefl0aco34akdtpe`(`email`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
    
    -- ----------------------------
    -- Records of user
    -- ----------------------------
    INSERT INTO `user` VALUES (1, '[email protected]', b'1', b'1', b'1', b'1', NULL, '$2a$10$RaDnhjsjVAoXE9DuOJxPV.BhJ0uX5oBtRJqvn6PSjQR7ASvZ53Z.a', 'admin', NULL, 'admin');
    
    SET FOREIGN_KEY_CHECKS = 1;
    

    Jpa在測試類添加一個用戶,mybatis使用上面添加一條用戶的跳過這個
    @SpringBootTest
    public class SecurityApplicationTests {
    
        @Autowired
        UserRepository userRepository;
    //    @Autowired
    //    RoleRepository roleRepository;
    //    @Autowired
    //    PermissionRepository permissionRepository;
        @Test
        void contextLoads() {
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            User user = new User();
            user.setUsername("admin");
            user.setPassword(bCryptPasswordEncoder.encode("admin"));
            user.setEmail("[email protected]");
            user.setRealName("admin");
    
    //        Permission adminPermission = new Permission();
    //        adminPermission.setPermName("管理員用戶權限");
    //        adminPermission.setPermTag("ROLE_ADMIN");
    //        Permission commonPermission = new Permission();
    //        commonPermission.setPermName("普通用戶權限");
    //        commonPermission.setPermTag("ROLE_COMMON");
    //        permissionRepository.save(adminPermission);
    //        permissionRepository.save(commonPermission);
    //
    //        List<Permission> permissions = new ArrayList<>();
    //
    //        permissions.add(commonPermission);
    //        Role commonRole= new Role();
    //        commonRole.setRoleName("普通用戶");
    //        commonRole.setRoleDesc("普通用戶角色");
    //        commonRole.setPermissionList(permissions);
    //        roleRepository.save(commonRole);
    //
    //        permissions.add(adminPermission);
    //        Role adminRole= new Role();
    //        adminRole.setRoleName("管理員用戶");
    //        adminRole.setRoleDesc("管理員用戶角色");
    //        adminRole.setPermissionList(permissions);
    //        roleRepository.save(adminRole);
    //
    //        List<Role> roles = new ArrayList<>();
    //
    //        roles.add(adminRole);
    //        user.setRoleList(roles);
            userRepository.save(user);
            System.out.println(user);
            System.out.println(userRepository.findAll());
        }
    }
    
    運行項目成功,看自己的數據庫

    數據庫數據準備完畢
    1.自定義數據來源,將數據庫的用戶提供給security,供其驗證登陸
    jpa接口
    public interface UserRepository extends JpaRepository<User,Integer> {
        User findByUsername(String username);
    }
    
    實現UserDetailsService接口實現UserDetails loadUserByUsername(String s)方法,security根據這個方法獲取數據庫用戶數據
    //security自定義驗證登陸用戶時的數據來源,從數據庫獲取
    @Component
    public class MyUserDetailService implements UserDetailsService {
    
        @Autowired
        UserRepository userRepository;
    
        /**
         * 根據用戶名獲取用戶信息
         *
         * @param s 用戶名
         * @return User 返回一個用戶信息
         * @throws UsernameNotFoundException
         */
        @Override
        public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
    
            User user = userRepository.findByUsername(s);
            System.out.println(user);
    //        if (user != null) {
    //            List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    //            for (Role role : user.getRoleList()) {
    //                for (Permission p : role.getPermissionList()) {
    //                    GrantedAuthority authority = new SimpleGrantedAuthority(p.getPermTag());
    //                    authorities.add(authority);
    //                }
    //                //將權限集合放進user
    //                user.setAuthorities(authorities);
    //                System.out.println("當前用戶是: " + user.getUsername());
    //            }
    //        }
            return user;
        }
    }
    

    將該實現類配置給security,在配置類重寫void configure(AuthenticationManagerBuilder auth)

    @Autowired
        private MyUserDetailService myUserDetailService;
    @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
        @Override
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(myUserDetailService).passwordEncoder(passwordEncoder());
        }

    ok!啓動項目

    成功!!
     

2.RBAC權限模型

可以看出前面所有用戶都是一樣的,這樣的功能有點單調,如果我們希望用戶是有所區別,就像windows用戶組一樣,我們希望不同的用戶擁有不同的權限,因爲我們網站不同模塊有些對所有人開放,有些只對管理員開放,有些只對vip用戶開放;這樣就需要RBAC權限模型了
關於概念理念可以看看:
https://www.cnblogs.com/aoxueshou/p/10115359.html

我們就開始我們代碼:三張基本表user、role、permission,以及闡述之間關係多對多的兩張中間表,E-R圖如下

1.JPA的Entity:
user:

//implements UserDetails
@Data
@Entity
@Table(name = "user",
        uniqueConstraints = {@UniqueConstraint(columnNames = {"username"}), @UniqueConstraint(columnNames = {"email"})})
public class User implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer u_id;
    @Column(nullable = false)
    @Length(min = 3, max = 20)
    private String username;
    @Column(nullable = false,length = 100)
    @JsonIgnore
    private String password;
    @Column(nullable = false)
    @Length(min = 3, max = 20)
    private String realName;
    @Column(nullable = false, length = 50)
    private String email;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date registerDate;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date lastLogin;
    private boolean isEnabled=true;
    private boolean isAccountNonExpired=true;
    private boolean isAccountNonLocked=true;
    private boolean isCredentialsNonExpired=true;
    @ManyToMany
    @JoinTable(name="user_role",joinColumns = @JoinColumn(name="u_id"),
            inverseJoinColumns = @JoinColumn(name="r_id"))
    List<Role> roleList;
    @Transient
    private List<GrantedAuthority> authorities;


    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (!(obj instanceof User)) return false;
        User user = (User) obj;
        boolean boo = this.username.equals(user.getUsername());
        return boo;
    }

    @Override
    public int hashCode() {
        return username != null ? username.hashCode() : 0;
    }


}

role:
 

@Data
@Entity
@Table(name = "role",uniqueConstraints = {@UniqueConstraint(columnNames = {"roleName"})})
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer r_id;
    @Column(nullable = false)
    @Length(max = 20)
    private String roleName;
    @Column(nullable = false)
    @Length(max = 20)
    private String roleDesc;
    @ManyToMany
    @JoinTable(name="role_permission",joinColumns = @JoinColumn(name="r_id"),
                inverseJoinColumns = @JoinColumn(name="p_id"))
    private List<Permission> permissionList;

    public Role() {
    }
}

permission:
 

@Data
@Entity
@Table(name = "permission",uniqueConstraints = {@UniqueConstraint(columnNames = {"permName"}),@UniqueConstraint(columnNames = {"permTag"})})
public class Permission implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer p_id;
    @Column(nullable = false)
    @Length(max = 20)
    private String permName;
    @Column(nullable = false)
    @Length(max = 20)
    private String permTag;


    public Permission(){

    }
    
}

啓動項目,自動創建如ER圖裏面對應的表
2.將數據庫之前插入的用戶刪了,然後把測試類的方法註釋全部弄掉運行測試方法,插入一個RBAC模型下的一個用戶

啓動測試方法,插入一個admin用戶,兩個角色(管理員,普通用戶),兩個權限(管理員權限,普通權限),admin用戶擁有管理員角色,管理員角色擁有管理員權限以及普通權限;
mybatis就需要自己根據下面sql弄了:

 

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `u_id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `is_account_non_expired` bit(1) NOT NULL,
  `is_account_non_locked` bit(1) NOT NULL,
  `is_credentials_non_expired` bit(1) NOT NULL,
  `is_enabled` bit(1) NOT NULL,
  `last_login` datetime NULL DEFAULT NULL,
  `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `real_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `register_date` datetime NULL DEFAULT NULL,
  `username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  PRIMARY KEY (`u_id`) USING BTREE,
  UNIQUE INDEX `UKsb8bbouer5wak8vyiiy4pf2bx`(`username`) USING BTREE,
  UNIQUE INDEX `UKob8kqyqqgmefl0aco34akdtpe`(`email`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (2, '[email protected]', b'1', b'1', b'1', b'1', NULL, '$2a$10$sm2TYwjob0JCIDrKUBpBvusSDeUbhjn/4dzjYpoKtyusBBlW1fnF2', 'admin', NULL, 'admin');

SET FOREIGN_KEY_CHECKS = 1;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for role
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role`  (
  `r_id` int(11) NOT NULL AUTO_INCREMENT,
  `role_desc` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `role_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  PRIMARY KEY (`r_id`) USING BTREE,
  UNIQUE INDEX `UKbgeqjb5opmijvwc14fbtaj4xx`(`role_name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES (1, '普通用戶角色', '普通用戶');
INSERT INTO `role` VALUES (2, '管理員用戶角色', '管理員用戶');

SET FOREIGN_KEY_CHECKS = 1;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user_role
-- ----------------------------
DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role`  (
  `u_id` int(11) NOT NULL,
  `r_id` int(11) NOT NULL,
  INDEX `FKto8gqveqi41eyylx7a2tqlfip`(`r_id`) USING BTREE,
  INDEX `FKhqbsm81qe5n0g3phrjs0kucos`(`u_id`) USING BTREE,
  CONSTRAINT `FKhqbsm81qe5n0g3phrjs0kucos` FOREIGN KEY (`u_id`) REFERENCES `user` (`u_id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
  CONSTRAINT `FKto8gqveqi41eyylx7a2tqlfip` FOREIGN KEY (`r_id`) REFERENCES `role` (`r_id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of user_role
-- ----------------------------
INSERT INTO `user_role` VALUES (2, 2);

SET FOREIGN_KEY_CHECKS = 1;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for permission
-- ----------------------------
DROP TABLE IF EXISTS `permission`;
CREATE TABLE `permission`  (
  `p_id` int(11) NOT NULL AUTO_INCREMENT,
  `perm_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `perm_tag` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  PRIMARY KEY (`p_id`) USING BTREE,
  UNIQUE INDEX `UKnojgqoyrg7x15s2qpu9x8tu5q`(`perm_name`) USING BTREE,
  UNIQUE INDEX `UKqhboiosst3rok6m9scsef9f5x`(`perm_tag`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of permission
-- ----------------------------
INSERT INTO `permission` VALUES (1, '管理員用戶權限', 'ROLE_ADMIN');
INSERT INTO `permission` VALUES (2, '普通用戶權限', 'ROLE_COMMON');

SET FOREIGN_KEY_CHECKS = 1;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for role_permission
-- ----------------------------
DROP TABLE IF EXISTS `role_permission`;
CREATE TABLE `role_permission`  (
  `r_id` int(11) NOT NULL,
  `p_id` int(11) NOT NULL,
  INDEX `FK92po1qlba53d8v5iuh13uhbsh`(`p_id`) USING BTREE,
  INDEX `FKgdhemjxik42hbj22wao654453`(`r_id`) USING BTREE,
  CONSTRAINT `FKgdhemjxik42hbj22wao654453` FOREIGN KEY (`r_id`) REFERENCES `role` (`r_id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
  CONSTRAINT `FK92po1qlba53d8v5iuh13uhbsh` FOREIGN KEY (`p_id`) REFERENCES `permission` (`p_id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of role_permission
-- ----------------------------
INSERT INTO `role_permission` VALUES (1, 2);
INSERT INTO `role_permission` VALUES (2, 2);
INSERT INTO `role_permission` VALUES (2, 1);

SET FOREIGN_KEY_CHECKS = 1;

如此便成功使用了RBAC設計模型;

應用RBAC到security

要知道真正代表權限的是peimission的perm_tag字段,又用角色關聯權限,用戶又關聯角色來實現賦權;

前面我們只有管理員用戶並且擁有管理員角色,管理員角色又有普通用戶權限和管理員權限,現在我們添加一個普通用戶並賦予普通用戶角色使其擁有普通權限;
測試類:

@Test
    void contextLoads() {
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        User user = new User();
        user.setUsername("common");
        user.setPassword(bCryptPasswordEncoder.encode("common"));
        user.setEmail("[email protected]");
        user.setRealName("common");

        List<Role> roles = new ArrayList<>();
        Role role= new Role();
        role.setR_id(1);
        roles.add(role);
        user.setRoleList(roles);
        userRepository.save(user);
}

運行,然後成功;
現在我們有兩個用戶common、admin,分別綁定普通用戶角色跟管理員角色,而普通用戶角色綁定普通用戶權限,管理員角色綁定普通用戶權限以及管理員權限;
配置security配置類:void configure(HttpSecurity http)方法

@Override
    protected void configure(HttpSecurity http) throws Exception {
        //添加驗證碼過濾器
        http.addFilterBefore(checkCodeAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
        http
                .authorizeRequests()
                .antMatchers("/admin/**").hasAuthority("ROLE_ADMIN")//需要ROLE_ADMIN才能訪問
                .antMatchers("/common/**").hasAuthority("ROLE_COMMON")//需要ROLE_COMMON才能訪問
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .usernameParameter("username")//與登陸頁面一致
                .passwordParameter("password")//與登陸頁面一致
                .loginPage("/login.html")//自定義登陸頁面
                .permitAll()//設置爲允許所有人訪問
                .loginProcessingUrl("/securityLogin")//登陸處理請求路徑與action一致即可,不需要我們實現
                .permitAll()//設置爲允許所有人訪問
                .successHandler(myAuthenticationSuccessHandler)
                .failureHandler(myAuthenticationFailureHandler)
                .and()
                .logout()//登出配置
                .logoutUrl("/logout")//不需要我們實現,訪問這個自動登出
                .invalidateHttpSession(true)
                .deleteCookies("JSESSIONID")
                .and()
                .httpBasic()
                .disable()
                .csrf()
                .disable();
    }

找到之前的MyUserDetailService類,將其中註釋去掉;這步的目的就是將在登陸時,從數據庫找到用戶信息以及用戶的權限組封裝起來交給security去進行其他的認證操作;需要用戶類User實現UserDetails接口並定義List<GrantedAuthority> authorities屬性以及其get、set方法,security會根據這個屬性判斷該用戶擁有什麼權限

@Component
public class MyUserDetailService implements UserDetailsService {

    @Autowired
    UserRepository userRepository;

    /**
     * 根據用戶名獲取用戶信息
     *
     * @param s 用戶名
     * @return User 返回一個用戶信息
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {

        User user = userRepository.findByUsername(s);
        System.out.println(user);
        if (user != null) {
            List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
            for (Role role : user.getRoleList()) {
                for (Permission p : role.getPermissionList()) {
                    GrantedAuthority authority = new SimpleGrantedAuthority(p.getPermTag());
                    authorities.add(authority);
                }
                //將權限集合放進user
                user.setAuthorities(authorities);
                System.out.println("當前用戶是: " + user.getUsername());
            }
        }
        return user;
    }
}

提供一個controller類

@RestController
public class SecurityController {

    @RequestMapping("/admin/hello")
    public String adminHello() {
        return "admin Hello World";
    }


    @RequestMapping("/common/hello")
    public String commonHello() {
        return "common Hello World";
    }

}

ok,重啓項目,使用common登陸
登陸成功!分別訪問:
http://localhost:8080/security/common/hello        //能訪問

http://localhost:8080/security/admin/hello    //無法訪問,因爲admin下需要ROLE_ADMIN權限才能訪問

使用admin用戶登陸訪問看看:全部能訪問



運用成功

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章