SpringSecurity快速上手

一 . springsecurity简介

springsecurity是一个安全框架,它能提供登录验证,权限认证的功能

二. springsecurity的使用

这篇写的挺好的,我的要是看不懂,可以看这个
我们最关心的大概都是是如何用springsecurity,有想看背后原理的小伙伴可以自行去度娘,本博文内容包括如何添加保护路径及如何设置登录验证及权限验证!;

  1. 首先在pom文件导入SpringSecurity依赖
 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
  1. 之后创建一个配置类,继承WebSecurityConfigurerAdapter这个类,其中根据需求可以重写WebSecurityConfigurerAdapter中多个configure()方法代码如下
@Configuration
public class MyWebSecurityconfigure extends WebSecurityConfigurerAdapter {
    
}

添加保护路径

protected configure(HttpSecurity)

configure(HttpSecurity)方法定义了哪些URL路径应该被保护,哪些不应该,我将在下边举出常用的例子,你们看过后应该明白的更快点!

插播几个常用api的用法;

  • permitAll()
    • 若跟在antMatchers() 后使用,代表所有路径均可访问
  • anyRequest()
    • 若跟在permitAll() 后使用,代表所有路径均不可访问,除啦 permitAll()修饰过的路径,注意若使用此api,则所有不需要保护的路径都呆加上permitAll()修饰;

登录验证

springsecurity关于登陆验证的实现我晓得的有两种,第一种内存验证登录,第二种jdbc

内存验证登录

只需要在配置类里加上这段便可以完成一个内存验证登录,注意springsecurity5后强制要求进行密码加密操作

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
     @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
//此路径需要admin权限用户才可访问
.antMatchers("/adminshow.html").hasRole("admin").
		//任何路径都是登录后即可访问;
anyRequest().authenticated().and().
							//设置登陆页,默认被拦截后都跳回登陆页
        formLogin().loginPage("/login.html").usernameParameter("username")            .passwordParameter("password").
//设置表单提交路径
loginProcessingUrl("/login").permitAll().
//成功后如何处理
successHandler(new AuthenticationSuccessHandler() {
            @Override
            public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                resp.setContentType("application/json;charset=utf-8");
                PrintWriter out = resp.getWriter();
                out.write("success");
                out.flush();
            }    //注意,不需要csrf防护时一定要禁用喽,否则一样拦截你;
        }).and().csrf().disable();

			
	 @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().
        //在内存中创建啦用户名为“lisi”
        withUser("lisi").
        //用户密码为“123”,此处必须填加密后的值
        password(new BCryptPasswordEncoder().encode("123")).
        //角色权限为“user”的这么一个用户
        roles("user");
    }
    
	//Spring Security 中提供了BCryptPasswordEncoder 密码编码工具,可以非常方便的实现密码的加密加盐,相同明文加密出来的结果总是不同
	//将Spring Security 中提供的BCryptPasswordEncoder加密类注入到spring容器中;
 	@Bean
    PasswordEncoder passwordEncoder(){
        return  new BCryptPasswordEncoder();
    }

   }

JDBC登录验证

根据下述操作来;

  • user对象实现UserDetails接口;
//UserDetails接口
public interface UserDetails extends Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();

    String getPassword();

    String getUsername();
	
	/**
     * 账号是否失效,返回false账号失效,不可用。
     */
    boolean isAccountNonExpired();
    
    /**
     * 账号是否被锁,返回false,账号被锁,不可用
     */
    boolean isAccountNonLocked();
	
	 /**
     * 账号认证是否过期,返回false,过期,不可用
        */
    boolean isCredentialsNonExpired();

 /**
     * 账号是否可用。返回false不可用
         */
    boolean isEnabled();
}
public class User implements UserDetails {
    Long id;
    String username;
    String password;
    List<Role> roles;

    public User() {
    }

    public User(Long id, String username, String password, List<Role> roles) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.roles = roles;
    }


    public Long getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public List<Role> getRoles() {
        return roles;
    }

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

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

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

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

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

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

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


    public String getPassword() {
        return password;
    }

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

  • Role类实现GrantedAuthority这个接口
public class Role implements GrantedAuthority {
    private Long id;
    private String name;

    public Role() {
    }

    public Long getId() {

        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Role(Long id, String name) {

        this.id = id;
        this.name = name;
    }

    @Override
    public String getAuthority() {
        return this.name;
    }
}

  • service层实现UserDetailsService这个接口并重写其中的loadUserByUsername方法;
@Service
public class UserService implements UserDetailsService {
    @Autowired
    UserMapper userMapper;
    @Autowired
    RoleMapper roleMapper;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        User user = userMapper.loadUserByUsername(s);
        List<Role> rolesbyname = roleMapper.rolesbyname(s);
        /*注意此处关于角色权限名字必须是ROLE_*的形式,否则不认你,
        所以我在此处又重新设置啦下角色权限的名字*/
        for (Role role : rolesbyname) {
            role.setName("ROLE_"+role.getName());
        }
        //此处必须返回新建的对象;
        return user == null ? null : new User(user.getId(), s, new BCryptPasswordEncoder().encode(user.getPassword()), rolesbyname);
    }
}
  • 最后在自定义安全配置类中重写configure(AuthenticationManagerBuilder auth)方法,将你的service层 传入进去;
@Configuration
public class MyWebsecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Autowired
    UserService userService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /*
         springsecurity通过loginProcessingUrl这个方法添加登录验证路径,loginPage添加登陆页面,
         不添加的默认使用springsecurity自带的登录页面,usernameParameter获取用户
         名,passwordParameter获取登录表单的密码
		*/
http.authorizeRequests().antMatchers("/adminshow.html").hasRole("admin").anyRequest().authenticated().and().formLogin().loginPage("/login.html").usernameParameter("username")
                .passwordParameter("password").loginProcessingUrl("/login").permitAll().successHandler(new AuthenticationSuccessHandler() {
            @Override
            public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                resp.setContentType("application/json;charset=utf-8");
                PrintWriter out = resp.getWriter();
                out.write("success");
                out.flush();
            }
        }).and()	//不用csrf时就关闭它;
                .csrf().disable();

    }
	
	//将你的userservice交给springsecurity去处理
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService);
    }
	
	//重要,这个不能丢,加密用的!
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}

上述一系列操作完成,springsecurity就可以代替你完成登录及权限认证的操作!

总结:
总体流程

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值