springboot整合springsecurity

接着上篇博客springboot整合springsecurity,本次主要是对其进行了优化

首先需要建立三张表,分别是user, role, user_role

创建表的时候特别需要注意:在创建role角色的时候,一定要按照 "ROLE_xxx"这种格式来写,这是security的规范,不然不会生效。

DROP TABLE IF EXISTS `user`;
DROP TABLE IF EXISTS `role`;
DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user` (
	id INT PRIMARY KEY AUTO_INCREMENT,
	`name` VARCHAR(10),
	`password` VARCHAR(10)
) ENGINE = INNODB DEFAULT CHARSET = utf8;

CREATE TABLE `role` (
	id INT PRIMARY KEY AUTO_INCREMENT,
	`name` VARCHAR(10)
) ENGINE = INNODB DEFAULT CHARSET = utf8;

CREATE TABLE `user_role` (
	user_id BIGINT(10),
	role_id BIGINT(10)
) ENGINE = INNODB DEFAULT CHARSET = utf8;

INSERT INTO `user`(`name`,`password`) VALUES('zhangsan','123456');
INSERT INTO `user`(`name`,`password`) VALUES('lisi','123456');
INSERT INTO `user`(`name`,`password`) VALUES('wangwu','123456');
INSERT INTO `user`(`name`,`password`) VALUES('赵六','123456');

INSERT INTO `role`(`name`) VALUES('ROLE_VIP1');
INSERT INTO `role`(`name`) VALUES('ROLE_VIP2');
INSERT INTO `role`(`name`) VALUES('ROLE_VIP3');

INSERT INTO `user_role`(`user_id`,`role_id`) VALUES(1,2);
INSERT INTO `user_role`(`user_id`,`role_id`) VALUES(1,3);
INSERT INTO `user_role`(`user_id`,`role_id`) VALUES(2,3);
INSERT INTO `user_role`(`user_id`,`role_id`) VALUES(3,1);

user是用户表,role是角色表,通过user_role将两张表建立联系

创建好数据库之后,创建项目

pom文件:

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.atguigu</groupId>
    <artifactId>springboot-05-security</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>springboot-05-security</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.12.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
        <thymeleaf-layout-dialect.version>2.3.0</thymeleaf-layout-dialect.version>
        <thymeleaf-extras-springsecurity4.version>3.0.2.RELEASE</thymeleaf-extras-springsecurity4.version>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity4 -->
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>persistence-api</artifactId>
            <version>1.0</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

然后创建application.yml文件,完成数据库相关配置

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/securitytest?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT

创建实体类:users, role

package com.example.security.entity;

import lombok.Data;

import javax.persistence.Table;

@Data
@Table(name = "user")
public class Users {

    private int id;

    private String name;

    private String password;

}
package com.example.security.entity;

import lombok.Data;

import javax.persistence.Table;

@Data
@Table(name = "role")
public class Role {

    private int id;

    private String name;

}

创建mapper: userMapper, roleMapper

package com.example.security.mapper;

import com.example.security.entity.Users;
import org.apache.ibatis.annotations.Select;

public interface UserMapper {

    @Select("select * from user where name = #{name}")
    Users loadUserByUsername(String name);

}
package com.example.security.mapper;

import com.example.security.entity.Role;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface RoleMapper {

    @Select("SELECT r.`name` FROM role r WHERE r.id IN (SELECT role_id FROM user_role s inner JOIN `user` u ON s.`user_id` = u.`id` and u.id = #{id})")
    List<Role> findRoleByUserId(int id);

}

创建service: userService 继承UserDetailsService,

package com.example.security.service;

import org.springframework.security.core.userdetails.UserDetailsService;

public interface UserService extends UserDetailsService {
}

实现类

package com.example.security.service.Impl;

import com.example.security.entity.Role;
import com.example.security.entity.Users;
import com.example.security.mapper.RoleMapper;
import com.example.security.mapper.UserMapper;
import com.example.security.service.UserService;
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.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private RoleMapper roleMapper;

    @Override
    public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {

        try {
           //获取用户信息,如果没有用户信息直接返回
            Users users = userMapper.loadUserByUsername(name);
            if(users == null){
                return null;
            }

            List<SimpleGrantedAuthority> authorityList = new ArrayList<>();
            List<Role> roles = roleMapper.findRoleByUserId(users.getId());
            for(Role role: roles){
                authorityList.add(new SimpleGrantedAuthority(role.getName()));
            }

            UserDetails userDetails = new User(users.getName(),users.getPassword(),authorityList);
            return userDetails;

        }catch (Exception e){
            e.printStackTrace();
            return null;
        }

    }
}

最后配置类:

package com.example.security.config;

import com.example.security.service.Impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
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;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserServiceImpl userServiceImpl;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //super.configure(http);
        //定制请求的授权规则
        http.authorizeRequests().antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("VIP1")
                .antMatchers("/level2/**").hasRole("VIP2")
                .antMatchers("/level3/**").hasRole("VIP3");

        //开启自动配置的登陆功能,效果,如果没有登陆,没有权限就会来到登陆页面
        http.formLogin().usernameParameter("user").passwordParameter("pwd")
                .loginPage("/userlogin");
        //1、/login来到登陆页
        //2、重定向到/login?error表示登陆失败
        //3、更多详细规定
        //4、默认post形式的 /login代表处理登陆
        //5、一但定制loginPage;那么 loginPage的post请求就是登陆


        //开启自动配置的注销功能。
        http.logout().logoutSuccessUrl("/");//注销成功以后来到首页
        //1、访问 /logout 表示用户注销,清空session
        //2、注销成功会返回 /login?logout 页面;

        //开启记住我功能
        http.rememberMe().rememberMeParameter("remember");
        //登陆成功以后,将cookie发给浏览器保存,以后访问页面带上这个cookie,只要通过检查就可以免登录
        //点击注销会删除cookie

    }

    //定义认证规则
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

//        //super.configure(auth);
//        auth.inMemoryAuthentication()
//                .withUser("zhangsan").password("123456").roles("VIP1","VIP2")
//                .and()
//                .withUser("lisi").password("123456").roles("VIP2","VIP3")
//                .and()
//                .withUser("wangwu").password("123456").roles("VIP1","VIP3");
        auth.userDetailsService(userServiceImpl);

    }

}

最后启动类:

package com.example.security;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.example.security.mapper")
public class SecurityApplication {

    public static void main(String[] args) {
        SpringApplication.run(SecurityApplication.class, args);
    }

}

最终结果:

 

 可以看到,用户名为赵六,密码123456,对应的数据库信息如下:id为4,再通过user_role表查看id为4对应的role_id,结果为2,查看role表,id为2时对应的角色为VIP2,对应的是学生,结果正确

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Boot整合Spring Security主要是为了提供安全控制功能,帮助开发者快速地在Spring Boot应用中添加身份验证、授权和会话管理等安全性措施。以下是基本步骤: 1. 添加依赖:首先,在Maven或Gradle项目中添加Spring Security的相关依赖到pom.xml或build.gradle文件中。 ```xml <!-- Maven --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- Gradle --> implementation 'org.springframework.boot:spring-boot-starter-security' ``` 2. 配置WebSecurityConfigurerAdapter:在`src/main/resources/application.properties`或application.yml中配置一些基础属性,如启用HTTPS、密码加密策略等。然后创建一个实现了`WebSecurityConfigurerAdapter`的类,进行具体的配置,如设置登录页面、认证器、过滤器等。 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/css/**", "/js/**", "/images/**").permitAll() // 允许静态资源访问 .anyRequest().authenticated() // 所有其他请求需要认证 .and() .formLogin() // 设置基于表单的身份验证 .loginPage("/login") // 登录页URL .defaultSuccessUrl("/") // 登录成功后的默认跳转URL .usernameParameter("username") .passwordParameter("password") .and() .logout() // 注销功能 .logoutUrl("/logout") .logoutSuccessUrl("/") .deleteCookies("JSESSIONID"); } // ... 其他配置如自定义用户DetailsService、密码编码器等 } ``` 3. 用户服务(UserDetailsService):如果需要从数据库或其他数据源获取用户信息,需要实现`UserDetailsService`接口并提供用户查询逻辑。 4. 运行应用:启动Spring Boot应用后,Spring Security将自动处理HTTP请求的安全检查,例如身份验证和授权。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mozzm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值