Spring Boot 整合Spring Securityt数据库

首先创建Spring Boot项目依赖

<dependencies>
        <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.1</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>  
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
            <version>5.1.27</version>
        </dependency>

         <build>
        <resources>
            <resource>	<!--同步xml文件-->
                <directory>src/main/resources</directory>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

application.properties

spring.datasource.username=root
spring.datasource.password=***
spring.datasource.url=jdbc:mysql:///securit
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

Role

/**
 * 角色
 */
public class Role {
    private Integer id;
    private String name;
    private String nameZh;

在这里插入图片描述
User

/**
 * UserDetails:  Spring Security基础接口,包含某个用户的账号,密码,权限,状态(是否锁定)等信息。
 * 数据库和Spring Security 的安全上下文需要保留的信息之间的适配器,实际是一种规范
 */
public class User implements UserDetails {
    private Integer id;
    private String username;
    private String password;
    private Boolean enabled; //默认1开启,0锁定
    private Boolean locked; // 账号默认0没锁定
    private List<Role> roles; //角色
    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }

    public void setLocked(Boolean locked) {
        this.locked = locked;
    }
    @Override //获取账号
    public String getUsername() {
        return username;
    }

    @Override   //获取密码
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }

    /**
     *
     * @return获取用户信息
     */
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<SimpleGrantedAuthority> list = new ArrayList<>();
        for(Role role:roles){
            list.add(new SimpleGrantedAuthority(role.getName()));
        }
            return list;
    }

    /**
     * 账号是否未过期->true没过期
     * @return
     */
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }
    /**
     * 账号是否未锁定-->单独locker是锁定
     * @return
     */
    @Override
    public boolean isAccountNonLocked() {
        return !locked;//没锁定
    }
    /**
     * 密码是否未过期
     *
     * @return
     */
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }
    /**
     * 账号是否可用
     * @return
     */
    @Override
    public boolean isEnabled() {
        return true;
    }
}

在这里插入图片描述
UserMapper

@Mapper//mapper类
public interface UserMapper {
    /**
     *
     * @param username 根据输入的值获取用户名
     * @return 获取用户名
     */
    User loadUserByUsername(String username);
    /**
     *  获取角色
     * @param uid 根据输入的id获取角色名
     * @return
     */
    List<Role> getRolesByUid(Integer uid);
}

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.sxt.springsecuritytest.mapper.UserMapper">
    <select id="loadUserByUsername" resultType="com.sxt.springsecuritytest.model.User">
        select * from user where username=#{username}
    </select>
    <select id="getRolesByUid" resultType="com.sxt.springsecuritytest.model.Role">
        select r.* from role r,user_role ur where r.`id`=ur.`rid` and ur.`uid`=#{uid}
    </select>
</mapper>

UserService

@Service
public class UserService implements UserDetailsService {

    @Autowired
    UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        User user = userMapper.loadUserByUsername(s); //输入用户名
        if (user == null){
            throw new UsernameNotFoundException("用户名不在");
        }
        user.setRoles(userMapper.getRolesByUid(user.getId())); //查询角色信息
        return user;
    }
}

SecurityConfig

/**
 * 配置账号验证和请求授权
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired  
    UserService userService;
    /**
     * 授权方法
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests() //开启授权请求
                .antMatchers("/admin/**") //控制层路径下的请求匹配
                .hasRole("admin")//一个角色和admin/路径绑定
                .antMatchers("/user/**") //控制层路径下的请求匹配
                 .hasAnyRole("admin","user")  //二个角色和user/路径绑定
                .anyRequest().authenticated()//其它的请求要登陆后才能访问
                .and()
                .formLogin()
                .passwordParameter("password")//自定义登陆时密码的key
                .usernameParameter("username")//自定义登陆时用户名的key
                .loginProcessingUrl("/doLogin") //页面输入登陆接口请求
                .loginPage("/login") //登陆页面

                 //登录成功的处理器
                .successHandler(new AuthenticationSuccessHandler() {
                    /**
                     * 登陆成功返回一段json数据
                     * @param request 请求
                     * @param response 响应
                     * @param authentication 身份验证
                     * @throws IOException
                     * @throws ServletException
                     */
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                        response.setContentType("application/json;charset=utf-8");//响应格式
                        Map<String, Object> map = new HashMap<>();//保存到集合
                        map.put("status",200);//成功200
                        map.put("msg","登录成功");
                        map.put("obj",authentication.getPrincipal()); //获取用户信息
                        PrintWriter out = response.getWriter(); //获取响应流对象
                        out.write(new ObjectMapper().writeValueAsString(map)); //集合里值输出到页面
                        out.flush();//刷新
                        out.close();//关闭
                    }
                })

                //登陆失败的处理器
                //AuthenticationException 登陆失败的异常类
                .failureHandler(new AuthenticationFailureHandler() {
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
                            response.setContentType("application/json;charset=utf-8");
                        Map<String, Object> map = new HashMap<String,Object>();
                        map.put("status","500");
                        map.put("msg","登陆失败"); //下面是登陆异常
                        if (e instanceof BadCredentialsException) {
                            map.put("msg", "用户名或密码写错");
                        } else if (e instanceof DisabledException) {
                            map.put("msg", "账户被禁用,登录失败");
                        } else if (e instanceof LockedException) {
                            map.put("msg", "账户被锁定,登录失败");
                       }
                        PrintWriter writer = response.getWriter();
                        writer.write(new ObjectMapper().writeValueAsString(map));
                        writer.flush();
                        writer.close();
                    }
                })
                 .permitAll()
                 .and()
                 .csrf().disable();//安全关闭posm测试

    }
    /**
     * 账号密码和角色验证方法
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService);  

    }
    /**
     *  对密码进行加密与密码匹配
     * @return
     */
    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

HelloController

@RestController
@ResponseBody
public class HelloController {
    
    @GetMapping("/user")
    public String Hello(){
        return "user访问成功";
    }
    @GetMapping("/admin")
    public String admin(){
        return "admin访问成功";
    }
}

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Java语录精选

你的鼓励是我坚持下去的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值