springsecurity安全框架

一 安全性框架

  • apache shiro 比较简单易用,不依赖于spring,应用场景:传统SSM项目。
  • springsecurity 比较复杂,功能较强大,属于spring框架技术,应用场景:springboot+springcloud

springsecurity框架内容:

  • springsecurity基础入门
  • jwt+sprinsecurity 组合,多用于微服务分布式开发中
  • jwt+springsecurity+springcloud
  • jwt+springsecurity+springcloud+前端(angular.js vue.js)

二 了解springsecurity的核心组件

  • SecurityContext springsecurity的上下文,保存重要对象的信息,比如,用户信息
  • SecurityContextHolder 通过该工具获取SecurityContext
  • Authencation "认证"的意思,理解成认证的主体,获取认证主体的信息,账号和密码
  • UserDetails 接口 表示“用户的详情信息”,规范了用户的详情信息(或者规范了pojo的定义,对用户对象的约束,用户的pojo类要实现该接口)
  • UserDetailsService 接口, 仅有一个方法:loadUserByUsername(String username),对用户验证接口的约束。

三 Springsecurity入门程序

  • 扩展用户的pojo类(UserDetails接口)
public class SysUser implements UserDetails{
    private String id;

    private String usercode;

    private String username;

    private String password;

    private String salt;

    private String locked;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id == null ? null : id.trim();
    }

    public String getUsercode() {
        return usercode;
    }

    public void setUsercode(String usercode) {
        this.usercode = usercode == null ? null : usercode.trim();
    }

    public String getUsername() {
        return username;
    }


    public void setUsername(String username) {
        this.username = username == null ? null : username.trim();
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password == null ? null : password.trim();
    }

    public String getSalt() {
        return salt;
    }

    public void setSalt(String salt) {
        this.salt = salt == null ? null : salt.trim();
    }

    public String getLocked() {
        return locked;
    }

    public void setLocked(String locked) {
        this.locked = locked == null ? null : locked.trim();
    }

    @Override //返回用户的权限信息
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }

    @Override //判断账号是否过期
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override //判断 账号是否被锁定
    public boolean isAccountNonLocked() {
        return this.locked.equals("0");
    }

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

    @Override
    public boolean isEnabled() {
        return true;
    }
}
  • 实现业务类(UserDetailsService接口)
@Service
public class SysUserService implements UserDetailsService {

    @Autowired
    private SysUserMapper userMapper;

    //根据账号查找用户的方法;账号名是唯一约束
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println("验证(Service): " + username);
        SysUserExample example = new SysUserExample();
        SysUserExample.Criteria criteria = example.createCriteria();
        criteria.andUsercodeEqualTo(username);
        List<SysUser> list = userMapper.selectByExample(example);
        if(list!=null && list.size()==0) { //找不到用户,抛异常
            throw new UsernameNotFoundException("账号不存在");
        }
        return list.get(0);
    }
}
  • springsecurity配置
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private SysUserService userService;

    //指定加密算法  springsecurity必须要用加密,推荐BCrypt算法,64位的长度
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(); //盐放在密文中
    }

    //指定用户的验证业务对象
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
       auth.userDetailsService(userService);
    }

    //框架的安全性配置(重要)
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置是一种链式风格
        http.authorizeRequests()
            .anyRequest()
            .authenticated()  //所有请求都要被验证
            .and()
            .formLogin()
            .usernameParameter("username")
            .passwordParameter("password")  //框架会提供默认的登录表单页
            .successHandler(new AuthenticationSuccessHandler() {//登录成功后的回调接口
                @Override
                public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                    response.setContentType("application/json;charset=utf-8");
                    //返回json数据
                    PrintWriter out = response.getWriter();
                    //获取用户的身份信息(类型:UserDetails)
                    SysUser user = (SysUser) authentication.getPrincipal();
                    RespBean respBean = RespBean.ok("登录成功",user);
                    //把respBean转成json对象,返回到前端
                    String json = new ObjectMapper().writeValueAsString(respBean);
                    System.out.println("成功返回json对象:" + json);
                    
                    out.write(json);
                    out.flush();
                    out.close();
                }
            })
            .failureHandler(new AuthenticationFailureHandler() { //登录失败后的回调接口
                @Override
                public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
                    response.setContentType("application/json;charset=utf-8");
                    //返回json数据
                    PrintWriter out = response.getWriter();
                    //登录失败,主要是处理异常
                    RespBean respBean = RespBean.error("登录失败");
                    if(e instanceof LockedException) {
                        respBean.setMsg("账号被锁定");
                    } else if(e instanceof CredentialsExpiredException) {
                        respBean.setMsg("密码过期");
                    } else if(e instanceof DisabledException) {
                        respBean.setMsg("账号被禁用");
                    } else if(e instanceof BadCredentialsException) {
                        respBean.setMsg("账号或密码错误");
                    }
                    
                    String json = new ObjectMapper().writeValueAsString(respBean);
                    System.out.println("登录失败返回的json: " + json);
                    
                    out.write(json);
                    out.flush();
                    out.close();
                }
            })
            .permitAll()
            .and()
            .logout()
            .logoutSuccessHandler(new LogoutSuccessHandler() {
                @Override
                public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {

                }
            })
            .permitAll()
            .and()
            .csrf().disable(); //禁用跨域攻击


    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值