SpringBoot集成Spring Security(一)登录注销

同个人网站 https://www.serendipper-x.cn/,欢迎访问 !

SpringBoot集成Spring Security(二)注册 、密码加密、修改密码
写在前面
Spring Security是一种基于 Spring AOP 和 Servlet 过滤器的安全框架。它提供全面的安全性解决方案,同时在 Web 请求级和方法调用级处理身份确认和授权。
由于最近写的项目用到了这方面知识,这里做一些总结。下面直接看代码
一、创建项目
这里以多模块项目为例。

多模块项目优点: 帮助项目划分模块,鼓励重用,防止POM变得过于庞大,方便各个模块的构建,而不用每次都构建整个项目,使得针对某个模块的特殊控制更为方便。
在这里插入图片描述
二、引入pom依赖

<dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>

三、web层

项目最核心的代码
SecurityConfig.java

/**
 * @author xiao
 * 使用springsecurity对用户登录、注销以及权限进行控制
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private StudentService studentService;

    @Autowired
    private ObjectMapper objectMapper;

    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(studentService).passwordEncoder(new BCryptPasswordEncoder());
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
//                .authenticationProvider(authenticationProvider())
                .httpBasic()
                //未登录时
                .authenticationEntryPoint((request,response,authException) -> {
                    response.setContentType("application/json;charset=utf-8");
                    response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                    PrintWriter out = response.getWriter();
                    RespBean error = RespBean.error("未登录");
                    String s = new ObjectMapper().writeValueAsString(error);
                    out.write(s);
                    out.flush();
                    out.close();
                })

                .and()
                .authorizeRequests()
                .anyRequest().authenticated() //必须授权才能范围

                .and()
                .formLogin() //使用自带的登录
                .usernameParameter("username")
                .passwordParameter("password")
                .permitAll()
                //登录失败,返回json
                .failureHandler(new AuthenticationFailureHandler() {
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException exception) throws IOException, ServletException {
                        resp.setContentType("application/json;charset=utf-8");
                        resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                        PrintWriter out = resp.getWriter();
                        RespBean respBean = RespBean.error("登录失败!");
                        if (exception instanceof UsernameNotFoundException || exception instanceof BadCredentialsException) {
                            respBean.setMsg("用户名或者密码输入错误,请重新输入!");
                        } else if (exception instanceof DisabledException) {
                            respBean.setMsg("账户被禁用");
                        } else {
                            respBean.setMsg("未知错误");
                        }
                        out.write(objectMapper.writeValueAsString(respBean));
                        out.flush();
                        out.close();
                    }
                })
                //登录成功,返回json
                .successHandler(new AuthenticationSuccessHandler() {
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                        resp.setContentType("application/json;charset=utf-8");
                        PrintWriter out = resp.getWriter();
                        Student student = (Student) authentication.getPrincipal();
                        student.setPassword(null);
                        RespBean ok = RespBean.ok("登录成功!", student);
                        String s = new ObjectMapper().writeValueAsString(ok);
                        out.write(s);
                        out.flush();
                        out.close();
                    }
                })
                .and()
                .exceptionHandling()
                //没有权限,返回json
                .accessDeniedHandler((request,response,ex) -> {
                    response.setContentType("application/json;charset=utf-8");
                    response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                    PrintWriter out = response.getWriter();
                    out.write(new ObjectMapper().writeValueAsString(RespBean.error("权限不足")));
                    out.flush();
                    out.close();
                })
                .and()
                .logout()
                //退出成功,返回json
                .logoutSuccessHandler(new LogoutSuccessHandler() {
                    @Override
                    public void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                        resp.setContentType("application/json;charset=utf-8");
                        PrintWriter out = resp.getWriter();
                        out.write(new ObjectMapper().writeValueAsString(RespBean.ok("注销成功!")));
                        out.flush();
                        out.close();
                    }
                })
                .permitAll();
        //开启跨域访问
        http.cors().disable();
        //开启模拟请求,比如API POST测试工具的测试,不开启时,API POST为报403错误
        http.csrf().disable();
    }

    @Override
    public void configure(WebSecurity web) {
        //对于在header里面增加token等类似情况,放行所有OPTIONS请求。
        web.ignoring()
                .antMatchers(HttpMethod.OPTIONS, "/**");
    }
}

四、mapper层

mapper下的StudentMapper.java

/**
 * @author xiao
 */
public interface StudentMapper {

    Student loadUserBySno(String sno);
}

resource下的StudentMapper.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.jxnu.os.mapper.StudentMapper">
    <resultMap id="BaseResultMap" type="com.jxnu.os.model.Student">
        <id column="id" property="id" jdbcType="INTEGER"/>
        <result column="username" property="username" jdbcType="VARCHAR"/>
        <result column="sno" property="sno" jdbcType="VARCHAR"/>
        <result column="s_sex" property="s_sex" jdbcType="CHAR"/>
        <result column="t_id" property="t_id" jdbcType="INTEGER"/>
        <result column="password" property="password" jdbcType="VARCHAR"/>
    </resultMap>

    <select id="loadUserByUsername" resultMap="BaseResultMap">
        select * from student where username=#{username}
    </select>

</mapper>

五、model层

model下的Student.java
注意一定要implements UserDetails

/**
 * @author xiao
 * 学生实体类
 */
public class Student implements UserDetails {
//
    //学生主键ID
    private Integer id;
    //学生姓名
    private String username;
    //登录密码
    private String password;

    public Integer getId() {
        return id;
    }

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

    private Collection<? extends GrantedAuthority> authorities;

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setAuthorities(Collection<? extends GrantedAuthority> authorities) {
        this.authorities = authorities;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return this.authorities;
    }

    @Override
    public String getPassword() {
        return this.password;
    }

    @Override
    public String getUsername() {
        return this.username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

六、service层
service下的StudentService.java

/**
 * @author xiao
 */
@Service
public class StudentService implements UserDetailsService {

    @Autowired
    StudentMapper studentMapper;

    /**
     * 登录
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        Student student = studentMapper.loadUserBySno(username);
        if (student == null) {
            throw new UsernameNotFoundException("用户不存在");
        }
        return student;
    }
}

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值