Spring security的配置(2)

1.依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

2.webSecurityConfigurerAdapter
通过重写抽象接口webSecurityConfigurerAdapter,在加上注解@EnableWebSecurity,即可实现web 的安全配置。
webSecurityConfigurerAdapter Config模块一共有三个builder(构造程序)。
(1)AuthenticationManagerBuilder:认证相关builder,用来配置全局的认证相关的信息。它包含AuthenticationProvider和UserDetailsService,前者是认证服务提供者,后者是用户详情查询服务。
(2)HttpSecurity:进行权限控制规则相关配置。
(3)WebSecurity:进行全局请求忽略规则配置、HTTPFirewall配置、debug配置、全局securityFilterChain配置。

简单的config配置如下:

package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //进行密码的加密
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(10);
    }

    //configure(AuthenticationManagerBuilder auth),
// 这个方法的主要作用就是设置用户的权限,从数据库获取用户信息之类的
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());
    }
    //通过http对象的authorizeRequests()方法定义url访问权限。
//    这个方法的主要作用就是设置某个请求需要什么权限才能访问
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()//定义哪些url需要被保护,哪些不需要被保护。
                .antMatchers("/login/**")
                .hasRole("user")//定义/login/下的所有url,只有拥有user角色的用户才有访问权限
                .antMatchers("/admin/**")
                .hasAuthority("admin")//定义/admin/下的所有url,只有拥有admin权限的用户才有访问权限
                .anyRequest()
                .authenticated()//除上面外的所有请求全部需要鉴权认证
                .and()
                .formLogin()//自定义用户登录页面
                .loginProcessingUrl("/login")//登录表单详细配置
                .loginPage("/Login")
                .usernameParameter("username")
                .passwordParameter("password")
                .successHandler(new AuthenticationSuccessHandler() {//登录成功的配置
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication auth) throws IOException, ServletException {
                        Object principal = auth.getPrincipal();//获取用户
                        resp.setContentType("application/json;charset=utf-8");
                        PrintWriter out = resp.getWriter();
                        resp.setStatus(200);
                        Map<String, Object> map = new HashMap<>();
                        map.put("status", 200);
                        map.put("msg", principal);
                        ObjectMapper om = new ObjectMapper();
                        out.write(om.writeValueAsString(map));
                        out.flush();
                        out.close();
                    }
                })//登录失败操作
                .failureHandler(new AuthenticationFailureHandler() {
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException e) throws IOException, ServletException {
                        resp.setContentType("application/json;charset=utf-8");
                        PrintWriter out = resp.getWriter();
                        resp.setStatus(401);
                        Map<String, Object> map = new HashMap<>();
                        map.put("status", 401);
                        if (e instanceof LockedException) {
                            map.put("msg", "账户被锁定,登录失败!!");
                        } else if (e instanceof BadCredentialsException) {
                            map.put("msg", "账户名或密码输入错误,登录失败!!");
                        } else if (e instanceof DisabledException) {
                            map.put("msg", "账户被禁用,登录失败!!");
                        } else if (e instanceof AccountExpiredException) {
                            map.put("msg", "账户已过期,登录失败!!");
                        } else if (e instanceof CredentialsExpiredException) {
                            map.put("msg", "密码已过期,登录失败!!");
                        } else {
                            map.put("msg", "登录失败");
                        }
                        ObjectMapper om = new ObjectMapper();
                        out.write(om.writeValueAsString(map));
                        out.flush();
                        out.close();
                    }
                })
                .permitAll()
                .and()
        //logout操作,注销登录操作
                .logout()
                .logoutUrl("/logout")
                .clearAuthentication(true)//清除身份认证信息,默认为true,表示清除
                .invalidateHttpSession(true)//是否使session失效,默认为true
                .addLogoutHandler(new LogoutHandler() {
                    @Override
                    public void logout(HttpServletRequest res, HttpServletResponse resp, Authentication auth) {

                    }
                })
                .logoutSuccessHandler(new LogoutSuccessHandler() {
                    @Override
                    public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                        httpServletResponse.sendRedirect("/login_page");
                    }
                })
                .and()
                .cors()
                .and()
                .csrf()
                .disable();



    }
}


配置用户加密

 @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());
    }
//用户信息是存储在数据库中的,因此需要在用户注册时对密码进行加密处理。
//用户将密码从前端传来之后,通过调用BCryptPasswordEncoder实例中的encode方法对面进行加密处理,加密完成后将密文存入数据库

配置用户实体类

package com.example.demo.bean;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import lombok.*;
import lombok.experimental.Accessors;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Data
@Accessors(chain = true)
@TableName("user")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor

//使用SpringSecurity从数据库里拿用户信息需要实现这个接口
public class User implements UserDetails {
    @TableId
    private Integer id;
    private String username;
    private String password;
//    用transient关键字标记的成员变量不参与序列化过程。
    private  String role;//用户角色
    private boolean enabled;//是否禁用
    private boolean locked;//是否锁死
    private transient Collection<? extends GrantedAuthority> authorities;
    public User(String username,String password,Collection<? extends GrantedAuthority> authorities){
        this.username = username;
        this.password = password;
        this.authorities = authorities;
    }
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        String str[] = this.role.split(",");
        for(String s: str){
            authorities.add(new SimpleGrantedAuthority(s));
        }
        return authorities;
    }
    /**
     * 用户账号是否过期
     */
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }
    /**
     * 用户账号是否被锁定
     */
    @Override
    public boolean isAccountNonLocked() {
        return !locked;
    }
    /**
     * 用户密码是否过期
     */
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }
    
    @Override
    public boolean isEnabled() {
        return enabled;
    }
}

hasRole当前用户是否拥有指定角色
hasAnyRole多个角色以逗号进行分割的字符串。如果当前用户拥有指定角色中的任意一个,则返回true
hasAuthority等同与hasRole ,但是指的是权限
hasAnyAuthority等同于hasAnyRole
Principle代表当前用户的principle对象
premitAll表示允许所有的
denyAll表示拒绝所有的
isAnonymous当前用户是否是一个匿名用户
isRememberme表示当前用户是否是通过Remember-Me自动登录的
isAuthenticated表示当前用户是否已经登录认证成功了

authenticated():保护url,需要用户登录,如:anyRequest().anthenticated()代表其他未配置的页面都已经授权。
hasIpAddress(String …):用于限制ip地址或子网。

创建UserService

@Service
@Transactional
public class UserServiceImpl implements MyUserService {
    @Autowired
    UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username",s));
        System.out.println("loaduserByName 方法");
        if(user==null)
           throw  new UsernameNotFoundException("该用户名不存在");
        //查询权限信息
        List<SimpleGrantedAuthority> authorities = createAuthorities(user.getRole());

        System.out.println("user 的 Authorities权限是:"+user.getAuthorities());

        return user.setAuthorities(authorities);
    }
    private List<SimpleGrantedAuthority> createAuthorities(String roleStr){
        String[] roles = roleStr.split(",");
        List<SimpleGrantedAuthority> simpleGrantedAuthorities = new ArrayList<>();
        for (String role : roles) {
            simpleGrantedAuthorities.add(new SimpleGrantedAuthority(role));
        }
        return simpleGrantedAuthorities;
    }
}

loadUserByUsername方法将在用户登录时自动调用(这是个坑点)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

龙怪神

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

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

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

打赏作者

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

抵扣说明:

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

余额充值